Object cycles should not prevent allocation elimination/sinking
[WebKit-https.git] / Source / JavaScriptCore / ftl / FTLLowerDFGToLLVM.cpp
1 /*
2  * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27 #include "FTLLowerDFGToLLVM.h"
28
29 #if ENABLE(FTL_JIT)
30
31 #include "CodeBlockWithJITType.h"
32 #include "DFGAbstractInterpreterInlines.h"
33 #include "DFGInPlaceAbstractState.h"
34 #include "DFGOSRAvailabilityAnalysisPhase.h"
35 #include "DFGOSRExitFuzz.h"
36 #include "DirectArguments.h"
37 #include "FTLAbstractHeapRepository.h"
38 #include "FTLAvailableRecovery.h"
39 #include "FTLForOSREntryJITCode.h"
40 #include "FTLFormattedValue.h"
41 #include "FTLInlineCacheSize.h"
42 #include "FTLLoweredNodeValue.h"
43 #include "FTLOperations.h"
44 #include "FTLOutput.h"
45 #include "FTLThunks.h"
46 #include "FTLWeightedTarget.h"
47 #include "JSCInlines.h"
48 #include "JSLexicalEnvironment.h"
49 #include "OperandsInlines.h"
50 #include "ScopedArguments.h"
51 #include "ScopedArgumentsTable.h"
52 #include "VirtualRegister.h"
53 #include <atomic>
54 #include <dlfcn.h>
55 #include <llvm/InitializeLLVM.h>
56 #include <unordered_set>
57 #include <wtf/ProcessID.h>
58
59 #if ENABLE(FTL_NATIVE_CALL_INLINING)
60 #include "BundlePath.h"
61 #endif
62
63 namespace JSC { namespace FTL {
64
65 using namespace DFG;
66
67 namespace {
68
69 std::atomic<int> compileCounter;
70
71 #if ASSERT_DISABLED
72 NO_RETURN_DUE_TO_CRASH static void ftlUnreachable()
73 {
74     CRASH();
75 }
76 #else
77 NO_RETURN_DUE_TO_CRASH static void ftlUnreachable(
78     CodeBlock* codeBlock, BlockIndex blockIndex, unsigned nodeIndex)
79 {
80     dataLog("Crashing in thought-to-be-unreachable FTL-generated code for ", pointerDump(codeBlock), " at basic block #", blockIndex);
81     if (nodeIndex != UINT_MAX)
82         dataLog(", node @", nodeIndex);
83     dataLog(".\n");
84     CRASH();
85 }
86 #endif
87
88 // Using this instead of typeCheck() helps to reduce the load on LLVM, by creating
89 // significantly less dead code.
90 #define FTL_TYPE_CHECK(lowValue, highValue, typesPassedThrough, failCondition) do { \
91         FormattedValue _ftc_lowValue = (lowValue);                      \
92         Edge _ftc_highValue = (highValue);                              \
93         SpeculatedType _ftc_typesPassedThrough = (typesPassedThrough);  \
94         if (!m_interpreter.needsTypeCheck(_ftc_highValue, _ftc_typesPassedThrough)) \
95             break;                                                      \
96         typeCheck(_ftc_lowValue, _ftc_highValue, _ftc_typesPassedThrough, (failCondition)); \
97     } while (false)
98
99 class LowerDFGToLLVM {
100 public:
101     LowerDFGToLLVM(State& state)
102         : m_graph(state.graph)
103         , m_ftlState(state)
104         , m_heaps(state.context)
105         , m_out(state.context)
106         , m_state(state.graph)
107         , m_interpreter(state.graph, m_state)
108         , m_stackmapIDs(0)
109         , m_tbaaKind(mdKindID(state.context, "tbaa"))
110         , m_tbaaStructKind(mdKindID(state.context, "tbaa.struct"))
111     {
112     }
113     
114     void lower()
115     {
116         CString name;
117         if (verboseCompilationEnabled()) {
118             name = toCString(
119                 "jsBody_", ++compileCounter, "_", codeBlock()->inferredName(),
120                 "_", codeBlock()->hash());
121         } else
122             name = "jsBody";
123         
124         m_graph.m_dominators.computeIfNecessary(m_graph);
125         
126         m_ftlState.module =
127             moduleCreateWithNameInContext(name.data(), m_ftlState.context);
128         
129         m_ftlState.function = addFunction(
130             m_ftlState.module, name.data(), functionType(m_out.int64));
131         setFunctionCallingConv(m_ftlState.function, LLVMCCallConv);
132         if (isX86() && Options::llvmDisallowAVX()) {
133             // AVX makes V8/raytrace 80% slower. It makes Kraken/audio-oscillator 4.5x
134             // slower. It should be disabled.
135             addTargetDependentFunctionAttr(m_ftlState.function, "target-features", "-avx");
136         }
137         
138         if (verboseCompilationEnabled())
139             dataLog("Function ready, beginning lowering.\n");
140         
141         m_out.initialize(m_ftlState.module, m_ftlState.function, m_heaps);
142         
143         m_prologue = FTL_NEW_BLOCK(m_out, ("Prologue"));
144         LBasicBlock stackOverflow = FTL_NEW_BLOCK(m_out, ("Stack overflow"));
145         m_handleExceptions = FTL_NEW_BLOCK(m_out, ("Handle Exceptions"));
146         
147         LBasicBlock checkArguments = FTL_NEW_BLOCK(m_out, ("Check arguments"));
148
149         for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
150             m_highBlock = m_graph.block(blockIndex);
151             if (!m_highBlock)
152                 continue;
153             m_blocks.add(m_highBlock, FTL_NEW_BLOCK(m_out, ("Block ", *m_highBlock)));
154         }
155         
156         m_out.appendTo(m_prologue, stackOverflow);
157         createPhiVariables();
158
159         auto preOrder = m_graph.blocksInPreOrder();
160
161         int maxNumberOfArguments = -1;
162         for (BasicBlock* block : preOrder) {
163             for (unsigned nodeIndex = block->size(); nodeIndex--; ) {
164                 Node* node = block->at(nodeIndex);
165                 switch (node->op()) {
166                 case NativeCall:
167                 case NativeConstruct: {
168                     int numArgs = node->numChildren();
169                     if (numArgs > maxNumberOfArguments)
170                         maxNumberOfArguments = numArgs;
171                     break;
172                 }
173                 default:
174                     break;
175                 }
176             }
177         }
178         
179         if (maxNumberOfArguments >= 0) {
180             m_execState = m_out.alloca(arrayType(m_out.int64, JSStack::CallFrameHeaderSize + maxNumberOfArguments));
181             m_execStorage = m_out.ptrToInt(m_execState, m_out.intPtr);        
182         }
183
184         LValue capturedAlloca = m_out.alloca(arrayType(m_out.int64, m_graph.m_nextMachineLocal));
185         
186         m_captured = m_out.add(
187             m_out.ptrToInt(capturedAlloca, m_out.intPtr),
188             m_out.constIntPtr(m_graph.m_nextMachineLocal * sizeof(Register)));
189         
190         m_ftlState.capturedStackmapID = m_stackmapIDs++;
191         m_out.call(
192             m_out.stackmapIntrinsic(), m_out.constInt64(m_ftlState.capturedStackmapID),
193             m_out.int32Zero, capturedAlloca);
194         
195         // If we have any CallVarargs then we nee to have a spill slot for it.
196         bool hasVarargs = false;
197         for (BasicBlock* block : preOrder) {
198             for (Node* node : *block) {
199                 switch (node->op()) {
200                 case CallVarargs:
201                 case CallForwardVarargs:
202                 case ConstructVarargs:
203                 case ConstructForwardVarargs:
204                     hasVarargs = true;
205                     break;
206                 default:
207                     break;
208                 }
209             }
210         }
211         if (hasVarargs) {
212             LValue varargsSpillSlots = m_out.alloca(
213                 arrayType(m_out.int64, JSCallVarargs::numSpillSlotsNeeded()));
214             m_ftlState.varargsSpillSlotsStackmapID = m_stackmapIDs++;
215             m_out.call(
216                 m_out.stackmapIntrinsic(), m_out.constInt64(m_ftlState.varargsSpillSlotsStackmapID),
217                 m_out.int32Zero, varargsSpillSlots);
218         }
219         
220         // We should not create any alloca's after this point, since they will cease to
221         // be mem2reg candidates.
222         
223         m_callFrame = m_out.ptrToInt(
224             m_out.call(m_out.frameAddressIntrinsic(), m_out.int32Zero), m_out.intPtr);
225         m_tagTypeNumber = m_out.constInt64(TagTypeNumber);
226         m_tagMask = m_out.constInt64(TagMask);
227         
228         m_out.storePtr(m_out.constIntPtr(codeBlock()), addressFor(JSStack::CodeBlock));
229         
230         m_out.branch(
231             didOverflowStack(), rarely(stackOverflow), usually(checkArguments));
232         
233         m_out.appendTo(stackOverflow, m_handleExceptions);
234         m_out.call(m_out.operation(operationThrowStackOverflowError), m_callFrame, m_out.constIntPtr(codeBlock()));
235         m_ftlState.handleStackOverflowExceptionStackmapID = m_stackmapIDs++;
236         m_out.call(
237             m_out.stackmapIntrinsic(), m_out.constInt64(m_ftlState.handleStackOverflowExceptionStackmapID),
238             m_out.constInt32(MacroAssembler::maxJumpReplacementSize()));
239         m_out.unreachable();
240         
241         m_out.appendTo(m_handleExceptions, checkArguments);
242         m_ftlState.handleExceptionStackmapID = m_stackmapIDs++;
243         m_out.call(
244             m_out.stackmapIntrinsic(), m_out.constInt64(m_ftlState.handleExceptionStackmapID),
245             m_out.constInt32(MacroAssembler::maxJumpReplacementSize()));
246         m_out.unreachable();
247         
248         m_out.appendTo(checkArguments, lowBlock(m_graph.block(0)));
249         availabilityMap().clear();
250         availabilityMap().m_locals = Operands<Availability>(codeBlock()->numParameters(), 0);
251         for (unsigned i = codeBlock()->numParameters(); i--;) {
252             availabilityMap().m_locals.argument(i) =
253                 Availability(FlushedAt(FlushedJSValue, virtualRegisterForArgument(i)));
254         }
255         m_codeOriginForExitTarget = CodeOrigin(0);
256         m_codeOriginForExitProfile = CodeOrigin(0);
257         m_node = nullptr;
258         for (unsigned i = codeBlock()->numParameters(); i--;) {
259             Node* node = m_graph.m_arguments[i];
260             VirtualRegister operand = virtualRegisterForArgument(i);
261             
262             LValue jsValue = m_out.load64(addressFor(operand));
263             
264             if (node) {
265                 DFG_ASSERT(m_graph, node, operand == node->stackAccessData()->machineLocal);
266                 
267                 // This is a hack, but it's an effective one. It allows us to do CSE on the
268                 // primordial load of arguments. This assumes that the GetLocal that got put in
269                 // place of the original SetArgument doesn't have any effects before it. This
270                 // should hold true.
271                 m_loadedArgumentValues.add(node, jsValue);
272             }
273             
274             switch (m_graph.m_argumentFormats[i]) {
275             case FlushedInt32:
276                 speculate(BadType, jsValueValue(jsValue), node, isNotInt32(jsValue));
277                 break;
278             case FlushedBoolean:
279                 speculate(BadType, jsValueValue(jsValue), node, isNotBoolean(jsValue));
280                 break;
281             case FlushedCell:
282                 speculate(BadType, jsValueValue(jsValue), node, isNotCell(jsValue));
283                 break;
284             case FlushedJSValue:
285                 break;
286             default:
287                 DFG_CRASH(m_graph, node, "Bad flush format for argument");
288                 break;
289             }
290         }
291         m_out.jump(lowBlock(m_graph.block(0)));
292         
293         for (BasicBlock* block : preOrder)
294             compileBlock(block);
295         
296         if (Options::dumpLLVMIR())
297             dumpModule(m_ftlState.module);
298         
299         if (verboseCompilationEnabled())
300             m_ftlState.dumpState("after lowering");
301         if (validationEnabled())
302             verifyModule(m_ftlState.module);
303     }
304
305 private:
306     
307     void createPhiVariables()
308     {
309         for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
310             BasicBlock* block = m_graph.block(blockIndex);
311             if (!block)
312                 continue;
313             for (unsigned nodeIndex = block->size(); nodeIndex--;) {
314                 Node* node = block->at(nodeIndex);
315                 if (node->op() != Phi)
316                     continue;
317                 LType type;
318                 switch (node->flags() & NodeResultMask) {
319                 case NodeResultDouble:
320                     type = m_out.doubleType;
321                     break;
322                 case NodeResultInt32:
323                     type = m_out.int32;
324                     break;
325                 case NodeResultInt52:
326                     type = m_out.int64;
327                     break;
328                 case NodeResultBoolean:
329                     type = m_out.boolean;
330                     break;
331                 case NodeResultJS:
332                     type = m_out.int64;
333                     break;
334                 default:
335                     DFG_CRASH(m_graph, node, "Bad Phi node result type");
336                     break;
337                 }
338                 m_phis.add(node, buildAlloca(m_out.m_builder, type));
339             }
340         }
341     }
342     
343     void compileBlock(BasicBlock* block)
344     {
345         if (!block)
346             return;
347         
348         if (verboseCompilationEnabled())
349             dataLog("Compiling block ", *block, "\n");
350         
351         m_highBlock = block;
352         
353         LBasicBlock lowBlock = m_blocks.get(m_highBlock);
354         
355         m_nextHighBlock = 0;
356         for (BlockIndex nextBlockIndex = m_highBlock->index + 1; nextBlockIndex < m_graph.numBlocks(); ++nextBlockIndex) {
357             m_nextHighBlock = m_graph.block(nextBlockIndex);
358             if (m_nextHighBlock)
359                 break;
360         }
361         m_nextLowBlock = m_nextHighBlock ? m_blocks.get(m_nextHighBlock) : 0;
362         
363         // All of this effort to find the next block gives us the ability to keep the
364         // generated IR in roughly program order. This ought not affect the performance
365         // of the generated code (since we expect LLVM to reorder things) but it will
366         // make IR dumps easier to read.
367         m_out.appendTo(lowBlock, m_nextLowBlock);
368         
369         if (Options::ftlCrashes())
370             m_out.trap();
371         
372         if (!m_highBlock->cfaHasVisited) {
373             if (verboseCompilationEnabled())
374                 dataLog("Bailing because CFA didn't reach.\n");
375             crash(m_highBlock->index, UINT_MAX);
376             return;
377         }
378         
379         m_availabilityCalculator.beginBlock(m_highBlock);
380         
381         m_state.reset();
382         m_state.beginBasicBlock(m_highBlock);
383         
384         for (m_nodeIndex = 0; m_nodeIndex < m_highBlock->size(); ++m_nodeIndex) {
385             if (!compileNode(m_nodeIndex))
386                 break;
387         }
388     }
389
390     void safelyInvalidateAfterTermination()
391     {
392         if (verboseCompilationEnabled())
393             dataLog("Bailing.\n");
394         crash();
395
396         // Invalidate dominated blocks. Under normal circumstances we would expect
397         // them to be invalidated already. But you can have the CFA become more
398         // precise over time because the structures of objects change on the main
399         // thread. Failing to do this would result in weird crashes due to a value
400         // being used but not defined. Race conditions FTW!
401         for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
402             BasicBlock* target = m_graph.block(blockIndex);
403             if (!target)
404                 continue;
405             if (m_graph.m_dominators.dominates(m_highBlock, target)) {
406                 if (verboseCompilationEnabled())
407                     dataLog("Block ", *target, " will bail also.\n");
408                 target->cfaHasVisited = false;
409             }
410         }
411     }
412
413     bool compileNode(unsigned nodeIndex)
414     {
415         if (!m_state.isValid()) {
416             safelyInvalidateAfterTermination();
417             return false;
418         }
419         
420         m_node = m_highBlock->at(nodeIndex);
421         m_codeOriginForExitProfile = m_node->origin.semantic;
422         m_codeOriginForExitTarget = m_node->origin.forExit;
423         
424         if (verboseCompilationEnabled())
425             dataLog("Lowering ", m_node, "\n");
426         
427         m_availableRecoveries.resize(0);
428         
429         m_interpreter.startExecuting();
430         
431         switch (m_node->op()) {
432         case Upsilon:
433             compileUpsilon();
434             break;
435         case Phi:
436             compilePhi();
437             break;
438         case JSConstant:
439             break;
440         case DoubleConstant:
441             compileDoubleConstant();
442             break;
443         case Int52Constant:
444             compileInt52Constant();
445             break;
446         case DoubleRep:
447             compileDoubleRep();
448             break;
449         case DoubleAsInt32:
450             compileDoubleAsInt32();
451             break;
452         case ValueRep:
453             compileValueRep();
454             break;
455         case Int52Rep:
456             compileInt52Rep();
457             break;
458         case ValueToInt32:
459             compileValueToInt32();
460             break;
461         case BooleanToNumber:
462             compileBooleanToNumber();
463             break;
464         case ExtractOSREntryLocal:
465             compileExtractOSREntryLocal();
466             break;
467         case GetStack:
468             compileGetStack();
469             break;
470         case PutStack:
471             compilePutStack();
472             break;
473         case Check:
474             compileNoOp();
475             break;
476         case ToThis:
477             compileToThis();
478             break;
479         case ValueAdd:
480             compileValueAdd();
481             break;
482         case ArithAdd:
483         case ArithSub:
484             compileArithAddOrSub();
485             break;
486         case ArithClz32:
487             compileArithClz32();
488             break;
489         case ArithMul:
490             compileArithMul();
491             break;
492         case ArithDiv:
493             compileArithDiv();
494             break;
495         case ArithMod:
496             compileArithMod();
497             break;
498         case ArithMin:
499         case ArithMax:
500             compileArithMinOrMax();
501             break;
502         case ArithAbs:
503             compileArithAbs();
504             break;
505         case ArithSin:
506             compileArithSin();
507             break;
508         case ArithCos:
509             compileArithCos();
510             break;
511         case ArithPow:
512             compileArithPow();
513             break;
514         case ArithRound:
515             compileArithRound();
516             break;
517         case ArithSqrt:
518             compileArithSqrt();
519             break;
520         case ArithLog:
521             compileArithLog();
522             break;
523         case ArithFRound:
524             compileArithFRound();
525             break;
526         case ArithNegate:
527             compileArithNegate();
528             break;
529         case BitAnd:
530             compileBitAnd();
531             break;
532         case BitOr:
533             compileBitOr();
534             break;
535         case BitXor:
536             compileBitXor();
537             break;
538         case BitRShift:
539             compileBitRShift();
540             break;
541         case BitLShift:
542             compileBitLShift();
543             break;
544         case BitURShift:
545             compileBitURShift();
546             break;
547         case UInt32ToNumber:
548             compileUInt32ToNumber();
549             break;
550         case CheckStructure:
551             compileCheckStructure();
552             break;
553         case CheckCell:
554             compileCheckCell();
555             break;
556         case CheckNotEmpty:
557             compileCheckNotEmpty();
558             break;
559         case CheckBadCell:
560             compileCheckBadCell();
561             break;
562         case GetExecutable:
563             compileGetExecutable();
564             break;
565         case ArrayifyToStructure:
566             compileArrayifyToStructure();
567             break;
568         case PutStructure:
569             compilePutStructure();
570             break;
571         case GetById:
572             compileGetById();
573             break;
574         case In:
575             compileIn();
576             break;
577         case PutById:
578         case PutByIdDirect:
579             compilePutById();
580             break;
581         case GetButterfly:
582             compileGetButterfly();
583             break;
584         case ConstantStoragePointer:
585             compileConstantStoragePointer();
586             break;
587         case GetIndexedPropertyStorage:
588             compileGetIndexedPropertyStorage();
589             break;
590         case CheckArray:
591             compileCheckArray();
592             break;
593         case GetArrayLength:
594             compileGetArrayLength();
595             break;
596         case CheckInBounds:
597             compileCheckInBounds();
598             break;
599         case GetByVal:
600             compileGetByVal();
601             break;
602         case GetMyArgumentByVal:
603             compileGetMyArgumentByVal();
604             break;
605         case PutByVal:
606         case PutByValAlias:
607         case PutByValDirect:
608             compilePutByVal();
609             break;
610         case ArrayPush:
611             compileArrayPush();
612             break;
613         case ArrayPop:
614             compileArrayPop();
615             break;
616         case CreateActivation:
617             compileCreateActivation();
618             break;
619         case NewFunction:
620             compileNewFunction();
621             break;
622         case CreateDirectArguments:
623             compileCreateDirectArguments();
624             break;
625         case CreateScopedArguments:
626             compileCreateScopedArguments();
627             break;
628         case CreateClonedArguments:
629             compileCreateClonedArguments();
630             break;
631         case NewObject:
632             compileNewObject();
633             break;
634         case NewArray:
635             compileNewArray();
636             break;
637         case NewArrayBuffer:
638             compileNewArrayBuffer();
639             break;
640         case NewArrayWithSize:
641             compileNewArrayWithSize();
642             break;
643         case GetTypedArrayByteOffset:
644             compileGetTypedArrayByteOffset();
645             break;
646         case AllocatePropertyStorage:
647             compileAllocatePropertyStorage();
648             break;
649         case ReallocatePropertyStorage:
650             compileReallocatePropertyStorage();
651             break;
652         case ToString:
653         case CallStringConstructor:
654             compileToStringOrCallStringConstructor();
655             break;
656         case ToPrimitive:
657             compileToPrimitive();
658             break;
659         case MakeRope:
660             compileMakeRope();
661             break;
662         case StringCharAt:
663             compileStringCharAt();
664             break;
665         case StringCharCodeAt:
666             compileStringCharCodeAt();
667             break;
668         case GetByOffset:
669         case GetGetterSetterByOffset:
670             compileGetByOffset();
671             break;
672         case GetGetter:
673             compileGetGetter();
674             break;
675         case GetSetter:
676             compileGetSetter();
677             break;
678         case MultiGetByOffset:
679             compileMultiGetByOffset();
680             break;
681         case PutByOffset:
682             compilePutByOffset();
683             break;
684         case MultiPutByOffset:
685             compileMultiPutByOffset();
686             break;
687         case GetGlobalVar:
688             compileGetGlobalVar();
689             break;
690         case PutGlobalVar:
691             compilePutGlobalVar();
692             break;
693         case NotifyWrite:
694             compileNotifyWrite();
695             break;
696         case GetCallee:
697             compileGetCallee();
698             break;
699         case GetArgumentCount:
700             compileGetArgumentCount();
701             break;
702         case GetScope:
703             compileGetScope();
704             break;
705         case SkipScope:
706             compileSkipScope();
707             break;
708         case GetClosureVar:
709             compileGetClosureVar();
710             break;
711         case PutClosureVar:
712             compilePutClosureVar();
713             break;
714         case GetFromArguments:
715             compileGetFromArguments();
716             break;
717         case PutToArguments:
718             compilePutToArguments();
719             break;
720         case CompareEq:
721             compileCompareEq();
722             break;
723         case CompareEqConstant:
724             compileCompareEqConstant();
725             break;
726         case CompareStrictEq:
727             compileCompareStrictEq();
728             break;
729         case CompareLess:
730             compileCompareLess();
731             break;
732         case CompareLessEq:
733             compileCompareLessEq();
734             break;
735         case CompareGreater:
736             compileCompareGreater();
737             break;
738         case CompareGreaterEq:
739             compileCompareGreaterEq();
740             break;
741         case LogicalNot:
742             compileLogicalNot();
743             break;
744         case Call:
745         case Construct:
746             compileCallOrConstruct();
747             break;
748         case CallVarargs:
749         case CallForwardVarargs:
750         case ConstructVarargs:
751         case ConstructForwardVarargs:
752             compileCallOrConstructVarargs();
753             break;
754         case LoadVarargs:
755             compileLoadVarargs();
756             break;
757         case ForwardVarargs:
758             compileForwardVarargs();
759             break;
760 #if ENABLE(FTL_NATIVE_CALL_INLINING)
761         case NativeCall:
762         case NativeConstruct:
763             compileNativeCallOrConstruct();
764             break;
765 #endif
766         case Jump:
767             compileJump();
768             break;
769         case Branch:
770             compileBranch();
771             break;
772         case Switch:
773             compileSwitch();
774             break;
775         case Return:
776             compileReturn();
777             break;
778         case ForceOSRExit:
779             compileForceOSRExit();
780             break;
781         case Throw:
782         case ThrowReferenceError:
783             compileThrow();
784             break;
785         case InvalidationPoint:
786             compileInvalidationPoint();
787             break;
788         case IsUndefined:
789             compileIsUndefined();
790             break;
791         case IsBoolean:
792             compileIsBoolean();
793             break;
794         case IsNumber:
795             compileIsNumber();
796             break;
797         case IsString:
798             compileIsString();
799             break;
800         case IsObject:
801             compileIsObject();
802             break;
803         case IsObjectOrNull:
804             compileIsObjectOrNull();
805             break;
806         case IsFunction:
807             compileIsFunction();
808             break;
809         case TypeOf:
810             compileTypeOf();
811             break;
812         case CheckHasInstance:
813             compileCheckHasInstance();
814             break;
815         case InstanceOf:
816             compileInstanceOf();
817             break;
818         case CountExecution:
819             compileCountExecution();
820             break;
821         case StoreBarrier:
822             compileStoreBarrier();
823             break;
824         case HasIndexedProperty:
825             compileHasIndexedProperty();
826             break;
827         case HasGenericProperty:
828             compileHasGenericProperty();
829             break;
830         case HasStructureProperty:
831             compileHasStructureProperty();
832             break;
833         case GetDirectPname:
834             compileGetDirectPname();
835             break;
836         case GetEnumerableLength:
837             compileGetEnumerableLength();
838             break;
839         case GetPropertyEnumerator:
840             compileGetPropertyEnumerator();
841             break;
842         case GetEnumeratorStructurePname:
843             compileGetEnumeratorStructurePname();
844             break;
845         case GetEnumeratorGenericPname:
846             compileGetEnumeratorGenericPname();
847             break;
848         case ToIndexString:
849             compileToIndexString();
850             break;
851         case CheckStructureImmediate:
852             compileCheckStructureImmediate();
853             break;
854         case MaterializeNewObject:
855             compileMaterializeNewObject();
856             break;
857         case MaterializeCreateActivation:
858             compileMaterializeCreateActivation();
859             break;
860
861         case PhantomLocal:
862         case LoopHint:
863         case MovHint:
864         case ZombieHint:
865         case PhantomNewObject:
866         case PhantomNewFunction:
867         case PhantomCreateActivation:
868         case PhantomDirectArguments:
869         case PhantomClonedArguments:
870         case PutHint:
871         case BottomValue:
872         case KillStack:
873             break;
874         default:
875             DFG_CRASH(m_graph, m_node, "Unrecognized node in FTL backend");
876             break;
877         }
878         
879         if (m_node->isTerminal())
880             return false;
881         
882         if (!m_state.isValid()) {
883             safelyInvalidateAfterTermination();
884             return false;
885         }
886
887         m_availabilityCalculator.executeNode(m_node);
888         m_interpreter.executeEffects(nodeIndex);
889         
890         return true;
891     }
892
893     void compileUpsilon()
894     {
895         LValue destination = m_phis.get(m_node->phi());
896         
897         switch (m_node->child1().useKind()) {
898         case DoubleRepUse:
899             m_out.set(lowDouble(m_node->child1()), destination);
900             break;
901         case Int32Use:
902             m_out.set(lowInt32(m_node->child1()), destination);
903             break;
904         case Int52RepUse:
905             m_out.set(lowInt52(m_node->child1()), destination);
906             break;
907         case BooleanUse:
908             m_out.set(lowBoolean(m_node->child1()), destination);
909             break;
910         case CellUse:
911             m_out.set(lowCell(m_node->child1()), destination);
912             break;
913         case UntypedUse:
914             m_out.set(lowJSValue(m_node->child1()), destination);
915             break;
916         default:
917             DFG_CRASH(m_graph, m_node, "Bad use kind");
918             break;
919         }
920     }
921     
922     void compilePhi()
923     {
924         LValue source = m_phis.get(m_node);
925         
926         switch (m_node->flags() & NodeResultMask) {
927         case NodeResultDouble:
928             setDouble(m_out.get(source));
929             break;
930         case NodeResultInt32:
931             setInt32(m_out.get(source));
932             break;
933         case NodeResultInt52:
934             setInt52(m_out.get(source));
935             break;
936         case NodeResultBoolean:
937             setBoolean(m_out.get(source));
938             break;
939         case NodeResultJS:
940             setJSValue(m_out.get(source));
941             break;
942         default:
943             DFG_CRASH(m_graph, m_node, "Bad use kind");
944             break;
945         }
946     }
947     
948     void compileDoubleConstant()
949     {
950         setDouble(m_out.constDouble(m_node->asNumber()));
951     }
952     
953     void compileInt52Constant()
954     {
955         int64_t value = m_node->asMachineInt();
956         
957         setInt52(m_out.constInt64(value << JSValue::int52ShiftAmount));
958         setStrictInt52(m_out.constInt64(value));
959     }
960
961     void compileDoubleRep()
962     {
963         switch (m_node->child1().useKind()) {
964         case RealNumberUse: {
965             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
966             
967             LValue doubleValue = unboxDouble(value);
968             
969             LBasicBlock intCase = FTL_NEW_BLOCK(m_out, ("DoubleRep RealNumberUse int case"));
970             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("DoubleRep continuation"));
971             
972             ValueFromBlock fastResult = m_out.anchor(doubleValue);
973             m_out.branch(
974                 m_out.doubleEqual(doubleValue, doubleValue),
975                 usually(continuation), rarely(intCase));
976             
977             LBasicBlock lastNext = m_out.appendTo(intCase, continuation);
978             
979             FTL_TYPE_CHECK(
980                 jsValueValue(value), m_node->child1(), SpecBytecodeRealNumber,
981                 isNotInt32(value, provenType(m_node->child1()) & ~SpecFullDouble));
982             ValueFromBlock slowResult = m_out.anchor(m_out.intToDouble(unboxInt32(value)));
983             m_out.jump(continuation);
984             
985             m_out.appendTo(continuation, lastNext);
986             
987             setDouble(m_out.phi(m_out.doubleType, fastResult, slowResult));
988             return;
989         }
990             
991         case NotCellUse:
992         case NumberUse: {
993             bool shouldConvertNonNumber = m_node->child1().useKind() == NotCellUse;
994             
995             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
996
997             LBasicBlock intCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble unboxing int case"));
998             LBasicBlock doubleTesting = FTL_NEW_BLOCK(m_out, ("jsValueToDouble testing double case"));
999             LBasicBlock doubleCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble unboxing double case"));
1000             LBasicBlock nonDoubleCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble testing undefined case"));
1001             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("jsValueToDouble unboxing continuation"));
1002             
1003             m_out.branch(
1004                 isNotInt32(value, provenType(m_node->child1())),
1005                 unsure(doubleTesting), unsure(intCase));
1006             
1007             LBasicBlock lastNext = m_out.appendTo(intCase, doubleTesting);
1008             
1009             ValueFromBlock intToDouble = m_out.anchor(
1010                 m_out.intToDouble(unboxInt32(value)));
1011             m_out.jump(continuation);
1012             
1013             m_out.appendTo(doubleTesting, doubleCase);
1014             LValue valueIsNumber = isNumber(value, provenType(m_node->child1()));
1015             m_out.branch(valueIsNumber, usually(doubleCase), rarely(nonDoubleCase));
1016
1017             m_out.appendTo(doubleCase, nonDoubleCase);
1018             ValueFromBlock unboxedDouble = m_out.anchor(unboxDouble(value));
1019             m_out.jump(continuation);
1020
1021             if (shouldConvertNonNumber) {
1022                 LBasicBlock undefinedCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble converting undefined case"));
1023                 LBasicBlock testNullCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble testing null case"));
1024                 LBasicBlock nullCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble converting null case"));
1025                 LBasicBlock testBooleanTrueCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble testing boolean true case"));
1026                 LBasicBlock convertBooleanTrueCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble convert boolean true case"));
1027                 LBasicBlock convertBooleanFalseCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble convert boolean false case"));
1028
1029                 m_out.appendTo(nonDoubleCase, undefinedCase);
1030                 LValue valueIsUndefined = m_out.equal(value, m_out.constInt64(ValueUndefined));
1031                 m_out.branch(valueIsUndefined, unsure(undefinedCase), unsure(testNullCase));
1032
1033                 m_out.appendTo(undefinedCase, testNullCase);
1034                 ValueFromBlock convertedUndefined = m_out.anchor(m_out.constDouble(PNaN));
1035                 m_out.jump(continuation);
1036
1037                 m_out.appendTo(testNullCase, nullCase);
1038                 LValue valueIsNull = m_out.equal(value, m_out.constInt64(ValueNull));
1039                 m_out.branch(valueIsNull, unsure(nullCase), unsure(testBooleanTrueCase));
1040
1041                 m_out.appendTo(nullCase, testBooleanTrueCase);
1042                 ValueFromBlock convertedNull = m_out.anchor(m_out.constDouble(0));
1043                 m_out.jump(continuation);
1044
1045                 m_out.appendTo(testBooleanTrueCase, convertBooleanTrueCase);
1046                 LValue valueIsBooleanTrue = m_out.equal(value, m_out.constInt64(ValueTrue));
1047                 m_out.branch(valueIsBooleanTrue, unsure(convertBooleanTrueCase), unsure(convertBooleanFalseCase));
1048
1049                 m_out.appendTo(convertBooleanTrueCase, convertBooleanFalseCase);
1050                 ValueFromBlock convertedTrue = m_out.anchor(m_out.constDouble(1));
1051                 m_out.jump(continuation);
1052
1053                 m_out.appendTo(convertBooleanFalseCase, continuation);
1054
1055                 LValue valueIsNotBooleanFalse = m_out.notEqual(value, m_out.constInt64(ValueFalse));
1056                 FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), ~SpecCell, valueIsNotBooleanFalse);
1057                 ValueFromBlock convertedFalse = m_out.anchor(m_out.constDouble(0));
1058                 m_out.jump(continuation);
1059
1060                 m_out.appendTo(continuation, lastNext);
1061                 setDouble(m_out.phi(m_out.doubleType, intToDouble, unboxedDouble, convertedUndefined, convertedNull, convertedTrue, convertedFalse));
1062                 return;
1063             }
1064             m_out.appendTo(nonDoubleCase, continuation);
1065             FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), SpecBytecodeNumber, m_out.booleanTrue);
1066             m_out.unreachable();
1067
1068             m_out.appendTo(continuation, lastNext);
1069
1070             setDouble(m_out.phi(m_out.doubleType, intToDouble, unboxedDouble));
1071             return;
1072         }
1073             
1074         case Int52RepUse: {
1075             setDouble(strictInt52ToDouble(lowStrictInt52(m_node->child1())));
1076             return;
1077         }
1078             
1079         default:
1080             DFG_CRASH(m_graph, m_node, "Bad use kind");
1081         }
1082     }
1083
1084     void compileDoubleAsInt32()
1085     {
1086         LValue integerValue = convertDoubleToInt32(lowDouble(m_node->child1()), shouldCheckNegativeZero(m_node->arithMode()));
1087         setInt32(integerValue);
1088     }
1089
1090     void compileValueRep()
1091     {
1092         switch (m_node->child1().useKind()) {
1093         case DoubleRepUse: {
1094             LValue value = lowDouble(m_node->child1());
1095             
1096             if (m_interpreter.needsTypeCheck(m_node->child1(), ~SpecDoubleImpureNaN)) {
1097                 value = m_out.select(
1098                     m_out.doubleEqual(value, value), value, m_out.constDouble(PNaN));
1099             }
1100             
1101             setJSValue(boxDouble(value));
1102             return;
1103         }
1104             
1105         case Int52RepUse: {
1106             setJSValue(strictInt52ToJSValue(lowStrictInt52(m_node->child1())));
1107             return;
1108         }
1109             
1110         default:
1111             DFG_CRASH(m_graph, m_node, "Bad use kind");
1112         }
1113     }
1114     
1115     void compileInt52Rep()
1116     {
1117         switch (m_node->child1().useKind()) {
1118         case Int32Use:
1119             setStrictInt52(m_out.signExt(lowInt32(m_node->child1()), m_out.int64));
1120             return;
1121             
1122         case MachineIntUse:
1123             setStrictInt52(
1124                 jsValueToStrictInt52(
1125                     m_node->child1(), lowJSValue(m_node->child1(), ManualOperandSpeculation)));
1126             return;
1127             
1128         case DoubleRepMachineIntUse:
1129             setStrictInt52(
1130                 doubleToStrictInt52(
1131                     m_node->child1(), lowDouble(m_node->child1())));
1132             return;
1133             
1134         default:
1135             RELEASE_ASSERT_NOT_REACHED();
1136         }
1137     }
1138     
1139     void compileValueToInt32()
1140     {
1141         switch (m_node->child1().useKind()) {
1142         case Int52RepUse:
1143             setInt32(m_out.castToInt32(lowStrictInt52(m_node->child1())));
1144             break;
1145             
1146         case DoubleRepUse:
1147             setInt32(doubleToInt32(lowDouble(m_node->child1())));
1148             break;
1149             
1150         case NumberUse:
1151         case NotCellUse: {
1152             LoweredNodeValue value = m_int32Values.get(m_node->child1().node());
1153             if (isValid(value)) {
1154                 setInt32(value.value());
1155                 break;
1156             }
1157             
1158             value = m_jsValueValues.get(m_node->child1().node());
1159             if (isValid(value)) {
1160                 setInt32(numberOrNotCellToInt32(m_node->child1(), value.value()));
1161                 break;
1162             }
1163             
1164             // We'll basically just get here for constants. But it's good to have this
1165             // catch-all since we often add new representations into the mix.
1166             setInt32(
1167                 numberOrNotCellToInt32(
1168                     m_node->child1(),
1169                     lowJSValue(m_node->child1(), ManualOperandSpeculation)));
1170             break;
1171         }
1172             
1173         default:
1174             DFG_CRASH(m_graph, m_node, "Bad use kind");
1175             break;
1176         }
1177     }
1178     
1179     void compileBooleanToNumber()
1180     {
1181         switch (m_node->child1().useKind()) {
1182         case BooleanUse: {
1183             setInt32(m_out.zeroExt(lowBoolean(m_node->child1()), m_out.int32));
1184             return;
1185         }
1186             
1187         case UntypedUse: {
1188             LValue value = lowJSValue(m_node->child1());
1189             
1190             if (!m_interpreter.needsTypeCheck(m_node->child1(), SpecBoolInt32 | SpecBoolean)) {
1191                 setInt32(m_out.bitAnd(m_out.castToInt32(value), m_out.int32One));
1192                 return;
1193             }
1194             
1195             LBasicBlock booleanCase = FTL_NEW_BLOCK(m_out, ("BooleanToNumber boolean case"));
1196             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("BooleanToNumber continuation"));
1197             
1198             ValueFromBlock notBooleanResult = m_out.anchor(value);
1199             m_out.branch(
1200                 isBoolean(value, provenType(m_node->child1())),
1201                 unsure(booleanCase), unsure(continuation));
1202             
1203             LBasicBlock lastNext = m_out.appendTo(booleanCase, continuation);
1204             ValueFromBlock booleanResult = m_out.anchor(m_out.bitOr(
1205                 m_out.zeroExt(unboxBoolean(value), m_out.int64), m_tagTypeNumber));
1206             m_out.jump(continuation);
1207             
1208             m_out.appendTo(continuation, lastNext);
1209             setJSValue(m_out.phi(m_out.int64, booleanResult, notBooleanResult));
1210             return;
1211         }
1212             
1213         default:
1214             RELEASE_ASSERT_NOT_REACHED();
1215             return;
1216         }
1217     }
1218
1219     void compileExtractOSREntryLocal()
1220     {
1221         EncodedJSValue* buffer = static_cast<EncodedJSValue*>(
1222             m_ftlState.jitCode->ftlForOSREntry()->entryBuffer()->dataBuffer());
1223         setJSValue(m_out.load64(m_out.absolute(buffer + m_node->unlinkedLocal().toLocal())));
1224     }
1225     
1226     void compileGetStack()
1227     {
1228         // GetLocals arise only for captured variables and arguments. For arguments, we might have
1229         // already loaded it.
1230         if (LValue value = m_loadedArgumentValues.get(m_node)) {
1231             setJSValue(value);
1232             return;
1233         }
1234         
1235         StackAccessData* data = m_node->stackAccessData();
1236         AbstractValue& value = m_state.variables().operand(data->local);
1237         
1238         DFG_ASSERT(m_graph, m_node, isConcrete(data->format));
1239         DFG_ASSERT(m_graph, m_node, data->format != FlushedDouble); // This just happens to not arise for GetStacks, right now. It would be trivial to support.
1240         
1241         if (isInt32Speculation(value.m_type))
1242             setInt32(m_out.load32(payloadFor(data->machineLocal)));
1243         else
1244             setJSValue(m_out.load64(addressFor(data->machineLocal)));
1245     }
1246     
1247     void compilePutStack()
1248     {
1249         StackAccessData* data = m_node->stackAccessData();
1250         switch (data->format) {
1251         case FlushedJSValue: {
1252             LValue value = lowJSValue(m_node->child1());
1253             m_out.store64(value, addressFor(data->machineLocal));
1254             break;
1255         }
1256             
1257         case FlushedDouble: {
1258             LValue value = lowDouble(m_node->child1());
1259             m_out.storeDouble(value, addressFor(data->machineLocal));
1260             break;
1261         }
1262             
1263         case FlushedInt32: {
1264             LValue value = lowInt32(m_node->child1());
1265             m_out.store32(value, payloadFor(data->machineLocal));
1266             break;
1267         }
1268             
1269         case FlushedInt52: {
1270             LValue value = lowInt52(m_node->child1());
1271             m_out.store64(value, addressFor(data->machineLocal));
1272             break;
1273         }
1274             
1275         case FlushedCell: {
1276             LValue value = lowCell(m_node->child1());
1277             m_out.store64(value, addressFor(data->machineLocal));
1278             break;
1279         }
1280             
1281         case FlushedBoolean: {
1282             speculateBoolean(m_node->child1());
1283             m_out.store64(
1284                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
1285                 addressFor(data->machineLocal));
1286             break;
1287         }
1288             
1289         default:
1290             DFG_CRASH(m_graph, m_node, "Bad flush format");
1291             break;
1292         }
1293     }
1294     
1295     void compileNoOp()
1296     {
1297         DFG_NODE_DO_TO_CHILDREN(m_graph, m_node, speculate);
1298     }
1299     
1300     void compileToThis()
1301     {
1302         LValue value = lowJSValue(m_node->child1());
1303         
1304         LBasicBlock isCellCase = FTL_NEW_BLOCK(m_out, ("ToThis is cell case"));
1305         LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("ToThis slow case"));
1306         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ToThis continuation"));
1307         
1308         m_out.branch(
1309             isCell(value, provenType(m_node->child1())), usually(isCellCase), rarely(slowCase));
1310         
1311         LBasicBlock lastNext = m_out.appendTo(isCellCase, slowCase);
1312         ValueFromBlock fastResult = m_out.anchor(value);
1313         m_out.branch(isType(value, FinalObjectType), usually(continuation), rarely(slowCase));
1314         
1315         m_out.appendTo(slowCase, continuation);
1316         J_JITOperation_EJ function;
1317         if (m_graph.isStrictModeFor(m_node->origin.semantic))
1318             function = operationToThisStrict;
1319         else
1320             function = operationToThis;
1321         ValueFromBlock slowResult = m_out.anchor(
1322             vmCall(m_out.operation(function), m_callFrame, value));
1323         m_out.jump(continuation);
1324         
1325         m_out.appendTo(continuation, lastNext);
1326         setJSValue(m_out.phi(m_out.int64, fastResult, slowResult));
1327     }
1328     
1329     void compileValueAdd()
1330     {
1331         J_JITOperation_EJJ operation;
1332         if (!(provenType(m_node->child1()) & SpecFullNumber)
1333             && !(provenType(m_node->child2()) & SpecFullNumber))
1334             operation = operationValueAddNotNumber;
1335         else
1336             operation = operationValueAdd;
1337         setJSValue(vmCall(
1338             m_out.operation(operation), m_callFrame,
1339             lowJSValue(m_node->child1()), lowJSValue(m_node->child2())));
1340     }
1341     
1342     void compileArithAddOrSub()
1343     {
1344         bool isSub =  m_node->op() == ArithSub;
1345         switch (m_node->binaryUseKind()) {
1346         case Int32Use: {
1347             LValue left = lowInt32(m_node->child1());
1348             LValue right = lowInt32(m_node->child2());
1349
1350             if (!shouldCheckOverflow(m_node->arithMode())) {
1351                 setInt32(isSub ? m_out.sub(left, right) : m_out.add(left, right));
1352                 break;
1353             }
1354
1355             LValue result;
1356             if (!isSub) {
1357                 result = m_out.addWithOverflow32(left, right);
1358                 
1359                 if (doesKill(m_node->child2())) {
1360                     addAvailableRecovery(
1361                         m_node->child2(), SubRecovery,
1362                         m_out.extractValue(result, 0), left, ValueFormatInt32);
1363                 } else if (doesKill(m_node->child1())) {
1364                     addAvailableRecovery(
1365                         m_node->child1(), SubRecovery,
1366                         m_out.extractValue(result, 0), right, ValueFormatInt32);
1367                 }
1368             } else {
1369                 result = m_out.subWithOverflow32(left, right);
1370                 
1371                 if (doesKill(m_node->child2())) {
1372                     // result = left - right
1373                     // result - left = -right
1374                     // right = left - result
1375                     addAvailableRecovery(
1376                         m_node->child2(), SubRecovery,
1377                         left, m_out.extractValue(result, 0), ValueFormatInt32);
1378                 } else if (doesKill(m_node->child1())) {
1379                     // result = left - right
1380                     // result + right = left
1381                     addAvailableRecovery(
1382                         m_node->child1(), AddRecovery,
1383                         m_out.extractValue(result, 0), right, ValueFormatInt32);
1384                 }
1385             }
1386
1387             speculate(Overflow, noValue(), 0, m_out.extractValue(result, 1));
1388             setInt32(m_out.extractValue(result, 0));
1389             break;
1390         }
1391             
1392         case Int52RepUse: {
1393             if (!abstractValue(m_node->child1()).couldBeType(SpecInt52)
1394                 && !abstractValue(m_node->child2()).couldBeType(SpecInt52)) {
1395                 Int52Kind kind;
1396                 LValue left = lowWhicheverInt52(m_node->child1(), kind);
1397                 LValue right = lowInt52(m_node->child2(), kind);
1398                 setInt52(isSub ? m_out.sub(left, right) : m_out.add(left, right), kind);
1399                 break;
1400             }
1401             
1402             LValue left = lowInt52(m_node->child1());
1403             LValue right = lowInt52(m_node->child2());
1404
1405             LValue result;
1406             if (!isSub) {
1407                 result = m_out.addWithOverflow64(left, right);
1408                 
1409                 if (doesKill(m_node->child2())) {
1410                     addAvailableRecovery(
1411                         m_node->child2(), SubRecovery,
1412                         m_out.extractValue(result, 0), left, ValueFormatInt52);
1413                 } else if (doesKill(m_node->child1())) {
1414                     addAvailableRecovery(
1415                         m_node->child1(), SubRecovery,
1416                         m_out.extractValue(result, 0), right, ValueFormatInt52);
1417                 }
1418             } else {
1419                 result = m_out.subWithOverflow64(left, right);
1420                 
1421                 if (doesKill(m_node->child2())) {
1422                     // result = left - right
1423                     // result - left = -right
1424                     // right = left - result
1425                     addAvailableRecovery(
1426                         m_node->child2(), SubRecovery,
1427                         left, m_out.extractValue(result, 0), ValueFormatInt52);
1428                 } else if (doesKill(m_node->child1())) {
1429                     // result = left - right
1430                     // result + right = left
1431                     addAvailableRecovery(
1432                         m_node->child1(), AddRecovery,
1433                         m_out.extractValue(result, 0), right, ValueFormatInt52);
1434                 }
1435             }
1436
1437             speculate(Int52Overflow, noValue(), 0, m_out.extractValue(result, 1));
1438             setInt52(m_out.extractValue(result, 0));
1439             break;
1440         }
1441             
1442         case DoubleRepUse: {
1443             LValue C1 = lowDouble(m_node->child1());
1444             LValue C2 = lowDouble(m_node->child2());
1445
1446             setDouble(isSub ? m_out.doubleSub(C1, C2) : m_out.doubleAdd(C1, C2));
1447             break;
1448         }
1449             
1450         default:
1451             DFG_CRASH(m_graph, m_node, "Bad use kind");
1452             break;
1453         }
1454     }
1455
1456     void compileArithClz32()
1457     {
1458         LValue operand = lowInt32(m_node->child1());
1459         LValue isZeroUndef = m_out.booleanFalse;
1460         setInt32(m_out.ctlz32(operand, isZeroUndef));
1461     }
1462     
1463     void compileArithMul()
1464     {
1465         switch (m_node->binaryUseKind()) {
1466         case Int32Use: {
1467             LValue left = lowInt32(m_node->child1());
1468             LValue right = lowInt32(m_node->child2());
1469             
1470             LValue result;
1471
1472             if (!shouldCheckOverflow(m_node->arithMode()))
1473                 result = m_out.mul(left, right);
1474             else {
1475                 LValue overflowResult = m_out.mulWithOverflow32(left, right);
1476                 speculate(Overflow, noValue(), 0, m_out.extractValue(overflowResult, 1));
1477                 result = m_out.extractValue(overflowResult, 0);
1478             }
1479             
1480             if (shouldCheckNegativeZero(m_node->arithMode())) {
1481                 LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("ArithMul slow case"));
1482                 LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithMul continuation"));
1483                 
1484                 m_out.branch(
1485                     m_out.notZero32(result), usually(continuation), rarely(slowCase));
1486                 
1487                 LBasicBlock lastNext = m_out.appendTo(slowCase, continuation);
1488                 LValue cond = m_out.bitOr(m_out.lessThan(left, m_out.int32Zero), m_out.lessThan(right, m_out.int32Zero));
1489                 speculate(NegativeZero, noValue(), 0, cond);
1490                 m_out.jump(continuation);
1491                 m_out.appendTo(continuation, lastNext);
1492             }
1493             
1494             setInt32(result);
1495             break;
1496         }
1497             
1498         case Int52RepUse: {
1499             Int52Kind kind;
1500             LValue left = lowWhicheverInt52(m_node->child1(), kind);
1501             LValue right = lowInt52(m_node->child2(), opposite(kind));
1502
1503             LValue overflowResult = m_out.mulWithOverflow64(left, right);
1504             speculate(Int52Overflow, noValue(), 0, m_out.extractValue(overflowResult, 1));
1505             LValue result = m_out.extractValue(overflowResult, 0);
1506
1507             if (shouldCheckNegativeZero(m_node->arithMode())) {
1508                 LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("ArithMul slow case"));
1509                 LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithMul continuation"));
1510                 
1511                 m_out.branch(
1512                     m_out.notZero64(result), usually(continuation), rarely(slowCase));
1513                 
1514                 LBasicBlock lastNext = m_out.appendTo(slowCase, continuation);
1515                 LValue cond = m_out.bitOr(m_out.lessThan(left, m_out.int64Zero), m_out.lessThan(right, m_out.int64Zero));
1516                 speculate(NegativeZero, noValue(), 0, cond);
1517                 m_out.jump(continuation);
1518                 m_out.appendTo(continuation, lastNext);
1519             }
1520             
1521             setInt52(result);
1522             break;
1523         }
1524             
1525         case DoubleRepUse: {
1526             setDouble(
1527                 m_out.doubleMul(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
1528             break;
1529         }
1530             
1531         default:
1532             DFG_CRASH(m_graph, m_node, "Bad use kind");
1533             break;
1534         }
1535     }
1536
1537     void compileArithDiv()
1538     {
1539         switch (m_node->binaryUseKind()) {
1540         case Int32Use: {
1541             LValue numerator = lowInt32(m_node->child1());
1542             LValue denominator = lowInt32(m_node->child2());
1543             
1544             LBasicBlock unsafeDenominator = FTL_NEW_BLOCK(m_out, ("ArithDiv unsafe denominator"));
1545             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithDiv continuation"));
1546             LBasicBlock done = FTL_NEW_BLOCK(m_out, ("ArithDiv done"));
1547             
1548             Vector<ValueFromBlock, 3> results;
1549             
1550             LValue adjustedDenominator = m_out.add(denominator, m_out.int32One);
1551             
1552             m_out.branch(
1553                 m_out.above(adjustedDenominator, m_out.int32One),
1554                 usually(continuation), rarely(unsafeDenominator));
1555             
1556             LBasicBlock lastNext = m_out.appendTo(unsafeDenominator, continuation);
1557             
1558             LValue neg2ToThe31 = m_out.constInt32(-2147483647-1);
1559             
1560             if (shouldCheckOverflow(m_node->arithMode())) {
1561                 LValue cond = m_out.bitOr(m_out.isZero32(denominator), m_out.equal(numerator, neg2ToThe31));
1562                 speculate(Overflow, noValue(), 0, cond);
1563                 m_out.jump(continuation);
1564             } else {
1565                 // This is the case where we convert the result to an int after we're done. So,
1566                 // if the denominator is zero, then the result should be zero.
1567                 // If the denominator is not zero (i.e. it's -1 because we're guarded by the
1568                 // check above) and the numerator is -2^31 then the result should be -2^31.
1569                 
1570                 LBasicBlock divByZero = FTL_NEW_BLOCK(m_out, ("ArithDiv divide by zero"));
1571                 LBasicBlock notDivByZero = FTL_NEW_BLOCK(m_out, ("ArithDiv not divide by zero"));
1572                 LBasicBlock neg2ToThe31ByNeg1 = FTL_NEW_BLOCK(m_out, ("ArithDiv -2^31/-1"));
1573                 
1574                 m_out.branch(
1575                     m_out.isZero32(denominator), rarely(divByZero), usually(notDivByZero));
1576                 
1577                 m_out.appendTo(divByZero, notDivByZero);
1578                 results.append(m_out.anchor(m_out.int32Zero));
1579                 m_out.jump(done);
1580                 
1581                 m_out.appendTo(notDivByZero, neg2ToThe31ByNeg1);
1582                 m_out.branch(
1583                     m_out.equal(numerator, neg2ToThe31),
1584                     rarely(neg2ToThe31ByNeg1), usually(continuation));
1585                 
1586                 m_out.appendTo(neg2ToThe31ByNeg1, continuation);
1587                 results.append(m_out.anchor(neg2ToThe31));
1588                 m_out.jump(done);
1589             }
1590             
1591             m_out.appendTo(continuation, done);
1592             
1593             if (shouldCheckNegativeZero(m_node->arithMode())) {
1594                 LBasicBlock zeroNumerator = FTL_NEW_BLOCK(m_out, ("ArithDiv zero numerator"));
1595                 LBasicBlock numeratorContinuation = FTL_NEW_BLOCK(m_out, ("ArithDiv numerator continuation"));
1596                 
1597                 m_out.branch(
1598                     m_out.isZero32(numerator),
1599                     rarely(zeroNumerator), usually(numeratorContinuation));
1600                 
1601                 LBasicBlock innerLastNext = m_out.appendTo(zeroNumerator, numeratorContinuation);
1602                 
1603                 speculate(
1604                     NegativeZero, noValue(), 0, m_out.lessThan(denominator, m_out.int32Zero));
1605                 
1606                 m_out.jump(numeratorContinuation);
1607                 
1608                 m_out.appendTo(numeratorContinuation, innerLastNext);
1609             }
1610             
1611             LValue result = m_out.div(numerator, denominator);
1612             
1613             if (shouldCheckOverflow(m_node->arithMode())) {
1614                 speculate(
1615                     Overflow, noValue(), 0,
1616                     m_out.notEqual(m_out.mul(result, denominator), numerator));
1617             }
1618             
1619             results.append(m_out.anchor(result));
1620             m_out.jump(done);
1621             
1622             m_out.appendTo(done, lastNext);
1623             
1624             setInt32(m_out.phi(m_out.int32, results));
1625             break;
1626         }
1627             
1628         case DoubleRepUse: {
1629             setDouble(m_out.doubleDiv(
1630                 lowDouble(m_node->child1()), lowDouble(m_node->child2())));
1631             break;
1632         }
1633             
1634         default:
1635             DFG_CRASH(m_graph, m_node, "Bad use kind");
1636             break;
1637         }
1638     }
1639     
1640     void compileArithMod()
1641     {
1642         switch (m_node->binaryUseKind()) {
1643         case Int32Use: {
1644             LValue numerator = lowInt32(m_node->child1());
1645             LValue denominator = lowInt32(m_node->child2());
1646             
1647             LBasicBlock unsafeDenominator = FTL_NEW_BLOCK(m_out, ("ArithMod unsafe denominator"));
1648             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithMod continuation"));
1649             LBasicBlock done = FTL_NEW_BLOCK(m_out, ("ArithMod done"));
1650             
1651             Vector<ValueFromBlock, 3> results;
1652             
1653             LValue adjustedDenominator = m_out.add(denominator, m_out.int32One);
1654             
1655             m_out.branch(
1656                 m_out.above(adjustedDenominator, m_out.int32One),
1657                 usually(continuation), rarely(unsafeDenominator));
1658             
1659             LBasicBlock lastNext = m_out.appendTo(unsafeDenominator, continuation);
1660             
1661             LValue neg2ToThe31 = m_out.constInt32(-2147483647-1);
1662             
1663             // FIXME: -2^31 / -1 will actually yield negative zero, so we could have a
1664             // separate case for that. But it probably doesn't matter so much.
1665             if (shouldCheckOverflow(m_node->arithMode())) {
1666                 LValue cond = m_out.bitOr(m_out.isZero32(denominator), m_out.equal(numerator, neg2ToThe31));
1667                 speculate(Overflow, noValue(), 0, cond);
1668                 m_out.jump(continuation);
1669             } else {
1670                 // This is the case where we convert the result to an int after we're done. So,
1671                 // if the denominator is zero, then the result should be result should be zero.
1672                 // If the denominator is not zero (i.e. it's -1 because we're guarded by the
1673                 // check above) and the numerator is -2^31 then the result should be -2^31.
1674                 
1675                 LBasicBlock modByZero = FTL_NEW_BLOCK(m_out, ("ArithMod modulo by zero"));
1676                 LBasicBlock notModByZero = FTL_NEW_BLOCK(m_out, ("ArithMod not modulo by zero"));
1677                 LBasicBlock neg2ToThe31ByNeg1 = FTL_NEW_BLOCK(m_out, ("ArithMod -2^31/-1"));
1678                 
1679                 m_out.branch(
1680                     m_out.isZero32(denominator), rarely(modByZero), usually(notModByZero));
1681                 
1682                 m_out.appendTo(modByZero, notModByZero);
1683                 results.append(m_out.anchor(m_out.int32Zero));
1684                 m_out.jump(done);
1685                 
1686                 m_out.appendTo(notModByZero, neg2ToThe31ByNeg1);
1687                 m_out.branch(
1688                     m_out.equal(numerator, neg2ToThe31),
1689                     rarely(neg2ToThe31ByNeg1), usually(continuation));
1690                 
1691                 m_out.appendTo(neg2ToThe31ByNeg1, continuation);
1692                 results.append(m_out.anchor(m_out.int32Zero));
1693                 m_out.jump(done);
1694             }
1695             
1696             m_out.appendTo(continuation, done);
1697             
1698             LValue remainder = m_out.rem(numerator, denominator);
1699             
1700             if (shouldCheckNegativeZero(m_node->arithMode())) {
1701                 LBasicBlock negativeNumerator = FTL_NEW_BLOCK(m_out, ("ArithMod negative numerator"));
1702                 LBasicBlock numeratorContinuation = FTL_NEW_BLOCK(m_out, ("ArithMod numerator continuation"));
1703                 
1704                 m_out.branch(
1705                     m_out.lessThan(numerator, m_out.int32Zero),
1706                     unsure(negativeNumerator), unsure(numeratorContinuation));
1707                 
1708                 LBasicBlock innerLastNext = m_out.appendTo(negativeNumerator, numeratorContinuation);
1709                 
1710                 speculate(NegativeZero, noValue(), 0, m_out.isZero32(remainder));
1711                 
1712                 m_out.jump(numeratorContinuation);
1713                 
1714                 m_out.appendTo(numeratorContinuation, innerLastNext);
1715             }
1716             
1717             results.append(m_out.anchor(remainder));
1718             m_out.jump(done);
1719             
1720             m_out.appendTo(done, lastNext);
1721             
1722             setInt32(m_out.phi(m_out.int32, results));
1723             break;
1724         }
1725             
1726         case DoubleRepUse: {
1727             setDouble(
1728                 m_out.doubleRem(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
1729             break;
1730         }
1731             
1732         default:
1733             DFG_CRASH(m_graph, m_node, "Bad use kind");
1734             break;
1735         }
1736     }
1737
1738     void compileArithMinOrMax()
1739     {
1740         switch (m_node->binaryUseKind()) {
1741         case Int32Use: {
1742             LValue left = lowInt32(m_node->child1());
1743             LValue right = lowInt32(m_node->child2());
1744             
1745             setInt32(
1746                 m_out.select(
1747                     m_node->op() == ArithMin
1748                         ? m_out.lessThan(left, right)
1749                         : m_out.lessThan(right, left),
1750                     left, right));
1751             break;
1752         }
1753             
1754         case DoubleRepUse: {
1755             LValue left = lowDouble(m_node->child1());
1756             LValue right = lowDouble(m_node->child2());
1757             
1758             LBasicBlock notLessThan = FTL_NEW_BLOCK(m_out, ("ArithMin/ArithMax not less than"));
1759             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithMin/ArithMax continuation"));
1760             
1761             Vector<ValueFromBlock, 2> results;
1762             
1763             results.append(m_out.anchor(left));
1764             m_out.branch(
1765                 m_node->op() == ArithMin
1766                     ? m_out.doubleLessThan(left, right)
1767                     : m_out.doubleGreaterThan(left, right),
1768                 unsure(continuation), unsure(notLessThan));
1769             
1770             LBasicBlock lastNext = m_out.appendTo(notLessThan, continuation);
1771             results.append(m_out.anchor(m_out.select(
1772                 m_node->op() == ArithMin
1773                     ? m_out.doubleGreaterThanOrEqual(left, right)
1774                     : m_out.doubleLessThanOrEqual(left, right),
1775                 right, m_out.constDouble(PNaN))));
1776             m_out.jump(continuation);
1777             
1778             m_out.appendTo(continuation, lastNext);
1779             setDouble(m_out.phi(m_out.doubleType, results));
1780             break;
1781         }
1782             
1783         default:
1784             DFG_CRASH(m_graph, m_node, "Bad use kind");
1785             break;
1786         }
1787     }
1788     
1789     void compileArithAbs()
1790     {
1791         switch (m_node->child1().useKind()) {
1792         case Int32Use: {
1793             LValue value = lowInt32(m_node->child1());
1794             
1795             LValue mask = m_out.aShr(value, m_out.constInt32(31));
1796             LValue result = m_out.bitXor(mask, m_out.add(mask, value));
1797             
1798             speculate(Overflow, noValue(), 0, m_out.equal(result, m_out.constInt32(1 << 31)));
1799             
1800             setInt32(result);
1801             break;
1802         }
1803             
1804         case DoubleRepUse: {
1805             setDouble(m_out.doubleAbs(lowDouble(m_node->child1())));
1806             break;
1807         }
1808             
1809         default:
1810             DFG_CRASH(m_graph, m_node, "Bad use kind");
1811             break;
1812         }
1813     }
1814
1815     void compileArithSin() { setDouble(m_out.doubleSin(lowDouble(m_node->child1()))); }
1816
1817     void compileArithCos() { setDouble(m_out.doubleCos(lowDouble(m_node->child1()))); }
1818
1819     void compileArithPow()
1820     {
1821         // FIXME: investigate llvm.powi to better understand its performance characteristics.
1822         // It might be better to have the inline loop in DFG too.
1823         if (m_node->child2().useKind() == Int32Use)
1824             setDouble(m_out.doublePowi(lowDouble(m_node->child1()), lowInt32(m_node->child2())));
1825         else {
1826             LValue base = lowDouble(m_node->child1());
1827             LValue exponent = lowDouble(m_node->child2());
1828
1829             LBasicBlock integerExponentIsSmallBlock = FTL_NEW_BLOCK(m_out, ("ArithPow test integer exponent is small."));
1830             LBasicBlock integerExponentPowBlock = FTL_NEW_BLOCK(m_out, ("ArithPow pow(double, (int)double)."));
1831             LBasicBlock doubleExponentPowBlockEntry = FTL_NEW_BLOCK(m_out, ("ArithPow pow(double, double)."));
1832             LBasicBlock nanExceptionExponentIsInfinity = FTL_NEW_BLOCK(m_out, ("ArithPow NaN Exception, check exponent is infinity."));
1833             LBasicBlock nanExceptionBaseIsOne = FTL_NEW_BLOCK(m_out, ("ArithPow NaN Exception, check base is one."));
1834             LBasicBlock powBlock = FTL_NEW_BLOCK(m_out, ("ArithPow regular pow"));
1835             LBasicBlock nanExceptionResultIsNaN = FTL_NEW_BLOCK(m_out, ("ArithPow NaN Exception, result is NaN."));
1836             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithPow continuation"));
1837
1838             LValue integerExponent = m_out.fpToInt32(exponent);
1839             LValue integerExponentConvertedToDouble = m_out.intToDouble(integerExponent);
1840             LValue exponentIsInteger = m_out.doubleEqual(exponent, integerExponentConvertedToDouble);
1841             m_out.branch(exponentIsInteger, unsure(integerExponentIsSmallBlock), unsure(doubleExponentPowBlockEntry));
1842
1843             LBasicBlock lastNext = m_out.appendTo(integerExponentIsSmallBlock, integerExponentPowBlock);
1844             LValue integerExponentBelow1000 = m_out.below(integerExponent, m_out.constInt32(1000));
1845             m_out.branch(integerExponentBelow1000, usually(integerExponentPowBlock), rarely(doubleExponentPowBlockEntry));
1846
1847             m_out.appendTo(integerExponentPowBlock, doubleExponentPowBlockEntry);
1848             ValueFromBlock powDoubleIntResult = m_out.anchor(m_out.doublePowi(base, integerExponent));
1849             m_out.jump(continuation);
1850
1851             // If y is NaN, the result is NaN.
1852             m_out.appendTo(doubleExponentPowBlockEntry, nanExceptionExponentIsInfinity);
1853             LValue exponentIsNaN;
1854             if (provenType(m_node->child2()) & SpecDoubleNaN)
1855                 exponentIsNaN = m_out.doubleNotEqualOrUnordered(exponent, exponent);
1856             else
1857                 exponentIsNaN = m_out.booleanFalse;
1858             m_out.branch(exponentIsNaN, rarely(nanExceptionResultIsNaN), usually(nanExceptionExponentIsInfinity));
1859
1860             // If abs(x) is 1 and y is +infinity, the result is NaN.
1861             // If abs(x) is 1 and y is -infinity, the result is NaN.
1862             m_out.appendTo(nanExceptionExponentIsInfinity, nanExceptionBaseIsOne);
1863             LValue absoluteExponent = m_out.doubleAbs(exponent);
1864             LValue absoluteExponentIsInfinity = m_out.doubleEqual(absoluteExponent, m_out.constDouble(std::numeric_limits<double>::infinity()));
1865             m_out.branch(absoluteExponentIsInfinity, rarely(nanExceptionBaseIsOne), usually(powBlock));
1866
1867             m_out.appendTo(nanExceptionBaseIsOne, powBlock);
1868             LValue absoluteBase = m_out.doubleAbs(base);
1869             LValue absoluteBaseIsOne = m_out.doubleEqual(absoluteBase, m_out.constDouble(1));
1870             m_out.branch(absoluteBaseIsOne, unsure(nanExceptionResultIsNaN), unsure(powBlock));
1871
1872             m_out.appendTo(powBlock, nanExceptionResultIsNaN);
1873             ValueFromBlock powResult = m_out.anchor(m_out.doublePow(base, exponent));
1874             m_out.jump(continuation);
1875
1876             m_out.appendTo(nanExceptionResultIsNaN, continuation);
1877             ValueFromBlock pureNan = m_out.anchor(m_out.constDouble(PNaN));
1878             m_out.jump(continuation);
1879
1880             m_out.appendTo(continuation, lastNext);
1881             setDouble(m_out.phi(m_out.doubleType, powDoubleIntResult, powResult, pureNan));
1882         }
1883     }
1884
1885     void compileArithRound()
1886     {
1887         LBasicBlock realPartIsMoreThanHalf = FTL_NEW_BLOCK(m_out, ("ArithRound should round down"));
1888         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithRound continuation"));
1889
1890         LValue value = lowDouble(m_node->child1());
1891         LValue integerValue = m_out.ceil64(value);
1892         ValueFromBlock integerValueResult = m_out.anchor(integerValue);
1893
1894         LValue realPart = m_out.doubleSub(integerValue, value);
1895
1896         m_out.branch(m_out.doubleGreaterThanOrUnordered(realPart, m_out.constDouble(0.5)), unsure(realPartIsMoreThanHalf), unsure(continuation));
1897
1898         LBasicBlock lastNext = m_out.appendTo(realPartIsMoreThanHalf, continuation);
1899         LValue integerValueRoundedDown = m_out.doubleSub(integerValue, m_out.constDouble(1));
1900         ValueFromBlock integerValueRoundedDownResult = m_out.anchor(integerValueRoundedDown);
1901         m_out.jump(continuation);
1902         m_out.appendTo(continuation, lastNext);
1903
1904         LValue result = m_out.phi(m_out.doubleType, integerValueResult, integerValueRoundedDownResult);
1905
1906         if (producesInteger(m_node->arithRoundingMode())) {
1907             LValue integerValue = convertDoubleToInt32(result, shouldCheckNegativeZero(m_node->arithRoundingMode()));
1908             setInt32(integerValue);
1909         } else
1910             setDouble(result);
1911     }
1912
1913     void compileArithSqrt() { setDouble(m_out.doubleSqrt(lowDouble(m_node->child1()))); }
1914
1915     void compileArithLog() { setDouble(m_out.doubleLog(lowDouble(m_node->child1()))); }
1916     
1917     void compileArithFRound()
1918     {
1919         LValue floatValue = m_out.fpCast(lowDouble(m_node->child1()), m_out.floatType);
1920         setDouble(m_out.fpCast(floatValue, m_out.doubleType));
1921     }
1922     
1923     void compileArithNegate()
1924     {
1925         switch (m_node->child1().useKind()) {
1926         case Int32Use: {
1927             LValue value = lowInt32(m_node->child1());
1928             
1929             LValue result;
1930             if (!shouldCheckOverflow(m_node->arithMode()))
1931                 result = m_out.neg(value);
1932             else if (!shouldCheckNegativeZero(m_node->arithMode())) {
1933                 // We don't have a negate-with-overflow intrinsic. Hopefully this
1934                 // does the trick, though.
1935                 LValue overflowResult = m_out.subWithOverflow32(m_out.int32Zero, value);
1936                 speculate(Overflow, noValue(), 0, m_out.extractValue(overflowResult, 1));
1937                 result = m_out.extractValue(overflowResult, 0);
1938             } else {
1939                 speculate(Overflow, noValue(), 0, m_out.testIsZero32(value, m_out.constInt32(0x7fffffff)));
1940                 result = m_out.neg(value);
1941             }
1942
1943             setInt32(result);
1944             break;
1945         }
1946             
1947         case Int52RepUse: {
1948             if (!abstractValue(m_node->child1()).couldBeType(SpecInt52)) {
1949                 Int52Kind kind;
1950                 LValue value = lowWhicheverInt52(m_node->child1(), kind);
1951                 LValue result = m_out.neg(value);
1952                 if (shouldCheckNegativeZero(m_node->arithMode()))
1953                     speculate(NegativeZero, noValue(), 0, m_out.isZero64(result));
1954                 setInt52(result, kind);
1955                 break;
1956             }
1957             
1958             LValue value = lowInt52(m_node->child1());
1959             LValue overflowResult = m_out.subWithOverflow64(m_out.int64Zero, value);
1960             speculate(Int52Overflow, noValue(), 0, m_out.extractValue(overflowResult, 1));
1961             LValue result = m_out.extractValue(overflowResult, 0);
1962             speculate(NegativeZero, noValue(), 0, m_out.isZero64(result));
1963             setInt52(result);
1964             break;
1965         }
1966             
1967         case DoubleRepUse: {
1968             setDouble(m_out.doubleNeg(lowDouble(m_node->child1())));
1969             break;
1970         }
1971             
1972         default:
1973             DFG_CRASH(m_graph, m_node, "Bad use kind");
1974             break;
1975         }
1976     }
1977     
1978     void compileBitAnd()
1979     {
1980         setInt32(m_out.bitAnd(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
1981     }
1982     
1983     void compileBitOr()
1984     {
1985         setInt32(m_out.bitOr(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
1986     }
1987     
1988     void compileBitXor()
1989     {
1990         setInt32(m_out.bitXor(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
1991     }
1992     
1993     void compileBitRShift()
1994     {
1995         setInt32(m_out.aShr(
1996             lowInt32(m_node->child1()),
1997             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
1998     }
1999     
2000     void compileBitLShift()
2001     {
2002         setInt32(m_out.shl(
2003             lowInt32(m_node->child1()),
2004             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2005     }
2006     
2007     void compileBitURShift()
2008     {
2009         setInt32(m_out.lShr(
2010             lowInt32(m_node->child1()),
2011             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2012     }
2013     
2014     void compileUInt32ToNumber()
2015     {
2016         LValue value = lowInt32(m_node->child1());
2017
2018         if (doesOverflow(m_node->arithMode())) {
2019             setDouble(m_out.unsignedToDouble(value));
2020             return;
2021         }
2022         
2023         speculate(Overflow, noValue(), 0, m_out.lessThan(value, m_out.int32Zero));
2024         setInt32(value);
2025     }
2026     
2027     void compileCheckStructure()
2028     {
2029         LValue cell = lowCell(m_node->child1());
2030         
2031         ExitKind exitKind;
2032         if (m_node->child1()->hasConstant())
2033             exitKind = BadConstantCache;
2034         else
2035             exitKind = BadCache;
2036         
2037         LValue structureID = m_out.load32(cell, m_heaps.JSCell_structureID);
2038         
2039         checkStructure(
2040             structureID, jsValueValue(cell), exitKind, m_node->structureSet(),
2041             [this] (Structure* structure) {
2042                 return weakStructureID(structure);
2043             });
2044     }
2045     
2046     void compileCheckCell()
2047     {
2048         LValue cell = lowCell(m_node->child1());
2049         
2050         speculate(
2051             BadCell, jsValueValue(cell), m_node->child1().node(),
2052             m_out.notEqual(cell, weakPointer(m_node->cellOperand()->cell())));
2053     }
2054     
2055     void compileCheckBadCell()
2056     {
2057         terminate(BadCell);
2058     }
2059
2060     void compileCheckNotEmpty()
2061     {
2062         speculate(TDZFailure, noValue(), nullptr, m_out.isZero64(lowJSValue(m_node->child1())));
2063     }
2064
2065     void compileGetExecutable()
2066     {
2067         LValue cell = lowCell(m_node->child1());
2068         speculateFunction(m_node->child1(), cell);
2069         setJSValue(m_out.loadPtr(cell, m_heaps.JSFunction_executable));
2070     }
2071     
2072     void compileArrayifyToStructure()
2073     {
2074         LValue cell = lowCell(m_node->child1());
2075         LValue property = !!m_node->child2() ? lowInt32(m_node->child2()) : 0;
2076         
2077         LBasicBlock unexpectedStructure = FTL_NEW_BLOCK(m_out, ("ArrayifyToStructure unexpected structure"));
2078         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArrayifyToStructure continuation"));
2079         
2080         LValue structureID = m_out.load32(cell, m_heaps.JSCell_structureID);
2081         
2082         m_out.branch(
2083             m_out.notEqual(structureID, weakStructureID(m_node->structure())),
2084             rarely(unexpectedStructure), usually(continuation));
2085         
2086         LBasicBlock lastNext = m_out.appendTo(unexpectedStructure, continuation);
2087         
2088         if (property) {
2089             switch (m_node->arrayMode().type()) {
2090             case Array::Int32:
2091             case Array::Double:
2092             case Array::Contiguous:
2093                 speculate(
2094                     Uncountable, noValue(), 0,
2095                     m_out.aboveOrEqual(property, m_out.constInt32(MIN_SPARSE_ARRAY_INDEX)));
2096                 break;
2097             default:
2098                 break;
2099             }
2100         }
2101         
2102         switch (m_node->arrayMode().type()) {
2103         case Array::Int32:
2104             vmCall(m_out.operation(operationEnsureInt32), m_callFrame, cell);
2105             break;
2106         case Array::Double:
2107             vmCall(m_out.operation(operationEnsureDouble), m_callFrame, cell);
2108             break;
2109         case Array::Contiguous:
2110             vmCall(m_out.operation(operationEnsureContiguous), m_callFrame, cell);
2111             break;
2112         case Array::ArrayStorage:
2113         case Array::SlowPutArrayStorage:
2114             vmCall(m_out.operation(operationEnsureArrayStorage), m_callFrame, cell);
2115             break;
2116         default:
2117             DFG_CRASH(m_graph, m_node, "Bad array type");
2118             break;
2119         }
2120         
2121         structureID = m_out.load32(cell, m_heaps.JSCell_structureID);
2122         speculate(
2123             BadIndexingType, jsValueValue(cell), 0,
2124             m_out.notEqual(structureID, weakStructureID(m_node->structure())));
2125         m_out.jump(continuation);
2126         
2127         m_out.appendTo(continuation, lastNext);
2128     }
2129     
2130     void compilePutStructure()
2131     {
2132         m_ftlState.jitCode->common.notifyCompilingStructureTransition(m_graph.m_plan, codeBlock(), m_node);
2133
2134         Structure* oldStructure = m_node->transition()->previous;
2135         Structure* newStructure = m_node->transition()->next;
2136         ASSERT_UNUSED(oldStructure, oldStructure->indexingType() == newStructure->indexingType());
2137         ASSERT(oldStructure->typeInfo().inlineTypeFlags() == newStructure->typeInfo().inlineTypeFlags());
2138         ASSERT(oldStructure->typeInfo().type() == newStructure->typeInfo().type());
2139
2140         LValue cell = lowCell(m_node->child1()); 
2141         m_out.store32(
2142             weakStructureID(newStructure),
2143             cell, m_heaps.JSCell_structureID);
2144     }
2145     
2146     void compileGetById()
2147     {
2148         // Pretty much the only reason why we don't also support GetByIdFlush is because:
2149         // https://bugs.webkit.org/show_bug.cgi?id=125711
2150         
2151         switch (m_node->child1().useKind()) {
2152         case CellUse: {
2153             setJSValue(getById(lowCell(m_node->child1())));
2154             return;
2155         }
2156             
2157         case UntypedUse: {
2158             // This is pretty weird, since we duplicate the slow path both here and in the
2159             // code generated by the IC. We should investigate making this less bad.
2160             // https://bugs.webkit.org/show_bug.cgi?id=127830
2161             LValue value = lowJSValue(m_node->child1());
2162             
2163             LBasicBlock cellCase = FTL_NEW_BLOCK(m_out, ("GetById untyped cell case"));
2164             LBasicBlock notCellCase = FTL_NEW_BLOCK(m_out, ("GetById untyped not cell case"));
2165             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetById untyped continuation"));
2166             
2167             m_out.branch(
2168                 isCell(value, provenType(m_node->child1())), unsure(cellCase), unsure(notCellCase));
2169             
2170             LBasicBlock lastNext = m_out.appendTo(cellCase, notCellCase);
2171             ValueFromBlock cellResult = m_out.anchor(getById(value));
2172             m_out.jump(continuation);
2173             
2174             m_out.appendTo(notCellCase, continuation);
2175             ValueFromBlock notCellResult = m_out.anchor(vmCall(
2176                 m_out.operation(operationGetByIdGeneric),
2177                 m_callFrame, value,
2178                 m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()])));
2179             m_out.jump(continuation);
2180             
2181             m_out.appendTo(continuation, lastNext);
2182             setJSValue(m_out.phi(m_out.int64, cellResult, notCellResult));
2183             return;
2184         }
2185             
2186         default:
2187             DFG_CRASH(m_graph, m_node, "Bad use kind");
2188             return;
2189         }
2190     }
2191     
2192     void compilePutById()
2193     {
2194         // See above; CellUse is easier so we do only that for now.
2195         ASSERT(m_node->child1().useKind() == CellUse);
2196         
2197         LValue base = lowCell(m_node->child1());
2198         LValue value = lowJSValue(m_node->child2());
2199         auto uid = m_graph.identifiers()[m_node->identifierNumber()];
2200
2201         // Arguments: id, bytes, target, numArgs, args...
2202         unsigned stackmapID = m_stackmapIDs++;
2203
2204         if (verboseCompilationEnabled())
2205             dataLog("    Emitting PutById patchpoint with stackmap #", stackmapID, "\n");
2206         
2207         LValue call = m_out.call(
2208             m_out.patchpointVoidIntrinsic(),
2209             m_out.constInt64(stackmapID), m_out.constInt32(sizeOfPutById()),
2210             constNull(m_out.ref8), m_out.constInt32(2), base, value);
2211         setInstructionCallingConvention(call, LLVMAnyRegCallConv);
2212         
2213         m_ftlState.putByIds.append(PutByIdDescriptor(
2214             stackmapID, m_node->origin.semantic, uid,
2215             m_graph.executableFor(m_node->origin.semantic)->ecmaMode(),
2216             m_node->op() == PutByIdDirect ? Direct : NotDirect));
2217     }
2218     
2219     void compileGetButterfly()
2220     {
2221         setStorage(m_out.loadPtr(lowCell(m_node->child1()), m_heaps.JSObject_butterfly));
2222     }
2223     
2224     void compileConstantStoragePointer()
2225     {
2226         setStorage(m_out.constIntPtr(m_node->storagePointer()));
2227     }
2228     
2229     void compileGetIndexedPropertyStorage()
2230     {
2231         LValue cell = lowCell(m_node->child1());
2232         
2233         if (m_node->arrayMode().type() == Array::String) {
2234             LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("GetIndexedPropertyStorage String slow case"));
2235             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetIndexedPropertyStorage String continuation"));
2236             
2237             ValueFromBlock fastResult = m_out.anchor(
2238                 m_out.loadPtr(cell, m_heaps.JSString_value));
2239             
2240             m_out.branch(
2241                 m_out.notNull(fastResult.value()), usually(continuation), rarely(slowPath));
2242             
2243             LBasicBlock lastNext = m_out.appendTo(slowPath, continuation);
2244             
2245             ValueFromBlock slowResult = m_out.anchor(
2246                 vmCall(m_out.operation(operationResolveRope), m_callFrame, cell));
2247             
2248             m_out.jump(continuation);
2249             
2250             m_out.appendTo(continuation, lastNext);
2251             
2252             setStorage(m_out.loadPtr(m_out.phi(m_out.intPtr, fastResult, slowResult), m_heaps.StringImpl_data));
2253             return;
2254         }
2255         
2256         setStorage(m_out.loadPtr(cell, m_heaps.JSArrayBufferView_vector));
2257     }
2258     
2259     void compileCheckArray()
2260     {
2261         Edge edge = m_node->child1();
2262         LValue cell = lowCell(edge);
2263         
2264         if (m_node->arrayMode().alreadyChecked(m_graph, m_node, abstractValue(edge)))
2265             return;
2266         
2267         speculate(
2268             BadIndexingType, jsValueValue(cell), 0,
2269             m_out.bitNot(isArrayType(cell, m_node->arrayMode())));
2270     }
2271
2272     void compileGetTypedArrayByteOffset()
2273     {
2274         LValue basePtr = lowCell(m_node->child1());    
2275
2276         LBasicBlock simpleCase = FTL_NEW_BLOCK(m_out, ("wasteless typed array"));
2277         LBasicBlock wastefulCase = FTL_NEW_BLOCK(m_out, ("wasteful typed array"));
2278         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("continuation branch"));
2279         
2280         LValue mode = m_out.load32(basePtr, m_heaps.JSArrayBufferView_mode);
2281         m_out.branch(
2282             m_out.notEqual(mode, m_out.constInt32(WastefulTypedArray)),
2283             unsure(simpleCase), unsure(wastefulCase));
2284
2285         // begin simple case        
2286         LBasicBlock lastNext = m_out.appendTo(simpleCase, wastefulCase);
2287
2288         ValueFromBlock simpleOut = m_out.anchor(m_out.constIntPtr(0));
2289
2290         m_out.jump(continuation);
2291
2292         // begin wasteful case
2293         m_out.appendTo(wastefulCase, continuation);
2294
2295         LValue vectorPtr = m_out.loadPtr(basePtr, m_heaps.JSArrayBufferView_vector);
2296         LValue butterflyPtr = m_out.loadPtr(basePtr, m_heaps.JSObject_butterfly);
2297         LValue arrayBufferPtr = m_out.loadPtr(butterflyPtr, m_heaps.Butterfly_arrayBuffer);
2298         LValue dataPtr = m_out.loadPtr(arrayBufferPtr, m_heaps.ArrayBuffer_data);
2299
2300         ValueFromBlock wastefulOut = m_out.anchor(m_out.sub(vectorPtr, dataPtr));
2301
2302         m_out.jump(continuation);
2303         m_out.appendTo(continuation, lastNext);
2304
2305         // output
2306         setInt32(m_out.castToInt32(m_out.phi(m_out.intPtr, simpleOut, wastefulOut)));
2307     }
2308     
2309     void compileGetArrayLength()
2310     {
2311         switch (m_node->arrayMode().type()) {
2312         case Array::Int32:
2313         case Array::Double:
2314         case Array::Contiguous: {
2315             setInt32(m_out.load32NonNegative(lowStorage(m_node->child2()), m_heaps.Butterfly_publicLength));
2316             return;
2317         }
2318             
2319         case Array::String: {
2320             LValue string = lowCell(m_node->child1());
2321             setInt32(m_out.load32NonNegative(string, m_heaps.JSString_length));
2322             return;
2323         }
2324             
2325         case Array::DirectArguments: {
2326             LValue arguments = lowCell(m_node->child1());
2327             speculate(
2328                 ExoticObjectMode, noValue(), nullptr,
2329                 m_out.notNull(m_out.loadPtr(arguments, m_heaps.DirectArguments_overrides)));
2330             setInt32(m_out.load32NonNegative(arguments, m_heaps.DirectArguments_length));
2331             return;
2332         }
2333             
2334         case Array::ScopedArguments: {
2335             LValue arguments = lowCell(m_node->child1());
2336             speculate(
2337                 ExoticObjectMode, noValue(), nullptr,
2338                 m_out.notZero8(m_out.load8(arguments, m_heaps.ScopedArguments_overrodeThings)));
2339             setInt32(m_out.load32NonNegative(arguments, m_heaps.ScopedArguments_totalLength));
2340             return;
2341         }
2342             
2343         default:
2344             if (isTypedView(m_node->arrayMode().typedArrayType())) {
2345                 setInt32(
2346                     m_out.load32NonNegative(lowCell(m_node->child1()), m_heaps.JSArrayBufferView_length));
2347                 return;
2348             }
2349             
2350             DFG_CRASH(m_graph, m_node, "Bad array type");
2351             return;
2352         }
2353     }
2354     
2355     void compileCheckInBounds()
2356     {
2357         speculate(
2358             OutOfBounds, noValue(), 0,
2359             m_out.aboveOrEqual(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2360     }
2361     
2362     void compileGetByVal()
2363     {
2364         switch (m_node->arrayMode().type()) {
2365         case Array::Int32:
2366         case Array::Contiguous: {
2367             LValue index = lowInt32(m_node->child2());
2368             LValue storage = lowStorage(m_node->child3());
2369             
2370             IndexedAbstractHeap& heap = m_node->arrayMode().type() == Array::Int32 ?
2371                 m_heaps.indexedInt32Properties : m_heaps.indexedContiguousProperties;
2372             
2373             if (m_node->arrayMode().isInBounds()) {
2374                 LValue result = m_out.load64(baseIndex(heap, storage, index, m_node->child2()));
2375                 LValue isHole = m_out.isZero64(result);
2376                 if (m_node->arrayMode().isSaneChain()) {
2377                     DFG_ASSERT(
2378                         m_graph, m_node, m_node->arrayMode().type() == Array::Contiguous);
2379                     result = m_out.select(
2380                         isHole, m_out.constInt64(JSValue::encode(jsUndefined())), result);
2381                 } else
2382                     speculate(LoadFromHole, noValue(), 0, isHole);
2383                 setJSValue(result);
2384                 return;
2385             }
2386             
2387             LValue base = lowCell(m_node->child1());
2388             
2389             LBasicBlock fastCase = FTL_NEW_BLOCK(m_out, ("GetByVal int/contiguous fast case"));
2390             LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("GetByVal int/contiguous slow case"));
2391             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetByVal int/contiguous continuation"));
2392             
2393             m_out.branch(
2394                 m_out.aboveOrEqual(
2395                     index, m_out.load32NonNegative(storage, m_heaps.Butterfly_publicLength)),
2396                 rarely(slowCase), usually(fastCase));
2397             
2398             LBasicBlock lastNext = m_out.appendTo(fastCase, slowCase);
2399             
2400             ValueFromBlock fastResult = m_out.anchor(
2401                 m_out.load64(baseIndex(heap, storage, index, m_node->child2())));
2402             m_out.branch(
2403                 m_out.isZero64(fastResult.value()), rarely(slowCase), usually(continuation));
2404             
2405             m_out.appendTo(slowCase, continuation);
2406             ValueFromBlock slowResult = m_out.anchor(
2407                 vmCall(m_out.operation(operationGetByValArrayInt), m_callFrame, base, index));
2408             m_out.jump(continuation);
2409             
2410             m_out.appendTo(continuation, lastNext);
2411             setJSValue(m_out.phi(m_out.int64, fastResult, slowResult));
2412             return;
2413         }
2414             
2415         case Array::Double: {
2416             LValue index = lowInt32(m_node->child2());
2417             LValue storage = lowStorage(m_node->child3());
2418             
2419             IndexedAbstractHeap& heap = m_heaps.indexedDoubleProperties;
2420             
2421             if (m_node->arrayMode().isInBounds()) {
2422                 LValue result = m_out.loadDouble(
2423                     baseIndex(heap, storage, index, m_node->child2()));
2424                 
2425                 if (!m_node->arrayMode().isSaneChain()) {
2426                     speculate(
2427                         LoadFromHole, noValue(), 0,
2428                         m_out.doubleNotEqualOrUnordered(result, result));
2429                 }
2430                 setDouble(result);
2431                 break;
2432             }
2433             
2434             LValue base = lowCell(m_node->child1());
2435             
2436             LBasicBlock inBounds = FTL_NEW_BLOCK(m_out, ("GetByVal double in bounds"));
2437             LBasicBlock boxPath = FTL_NEW_BLOCK(m_out, ("GetByVal double boxing"));
2438             LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("GetByVal double slow case"));
2439             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetByVal double continuation"));
2440             
2441             m_out.branch(
2442                 m_out.aboveOrEqual(
2443                     index, m_out.load32NonNegative(storage, m_heaps.Butterfly_publicLength)),
2444                 rarely(slowCase), usually(inBounds));
2445             
2446             LBasicBlock lastNext = m_out.appendTo(inBounds, boxPath);
2447             LValue doubleValue = m_out.loadDouble(
2448                 baseIndex(heap, storage, index, m_node->child2()));
2449             m_out.branch(
2450                 m_out.doubleNotEqualOrUnordered(doubleValue, doubleValue),
2451                 rarely(slowCase), usually(boxPath));
2452             
2453             m_out.appendTo(boxPath, slowCase);
2454             ValueFromBlock fastResult = m_out.anchor(boxDouble(doubleValue));
2455             m_out.jump(continuation);
2456             
2457             m_out.appendTo(slowCase, continuation);
2458             ValueFromBlock slowResult = m_out.anchor(
2459                 vmCall(m_out.operation(operationGetByValArrayInt), m_callFrame, base, index));
2460             m_out.jump(continuation);
2461             
2462             m_out.appendTo(continuation, lastNext);
2463             setJSValue(m_out.phi(m_out.int64, fastResult, slowResult));
2464             return;
2465         }
2466             
2467         case Array::DirectArguments: {
2468             LValue base = lowCell(m_node->child1());
2469             LValue index = lowInt32(m_node->child2());
2470             
2471             speculate(
2472                 ExoticObjectMode, noValue(), nullptr,
2473                 m_out.notNull(m_out.loadPtr(base, m_heaps.DirectArguments_overrides)));
2474             speculate(
2475                 ExoticObjectMode, noValue(), nullptr,
2476                 m_out.aboveOrEqual(
2477                     index,
2478                     m_out.load32NonNegative(base, m_heaps.DirectArguments_length)));
2479
2480             TypedPointer address = m_out.baseIndex(
2481                 m_heaps.DirectArguments_storage, base, m_out.zeroExtPtr(index));
2482             setJSValue(m_out.load64(address));
2483             return;
2484         }
2485             
2486         case Array::ScopedArguments: {
2487             LValue base = lowCell(m_node->child1());
2488             LValue index = lowInt32(m_node->child2());
2489             
2490             speculate(
2491                 ExoticObjectMode, noValue(), nullptr,
2492                 m_out.aboveOrEqual(
2493                     index,
2494                     m_out.load32NonNegative(base, m_heaps.ScopedArguments_totalLength)));
2495             
2496             LValue table = m_out.loadPtr(base, m_heaps.ScopedArguments_table);
2497             LValue namedLength = m_out.load32(table, m_heaps.ScopedArgumentsTable_length);
2498             
2499             LBasicBlock namedCase = FTL_NEW_BLOCK(m_out, ("GetByVal ScopedArguments named case"));
2500             LBasicBlock overflowCase = FTL_NEW_BLOCK(m_out, ("GetByVal ScopedArguments overflow case"));
2501             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetByVal ScopedArguments continuation"));
2502             
2503             m_out.branch(
2504                 m_out.aboveOrEqual(index, namedLength), unsure(overflowCase), unsure(namedCase));
2505             
2506             LBasicBlock lastNext = m_out.appendTo(namedCase, overflowCase);
2507             
2508             LValue scope = m_out.loadPtr(base, m_heaps.ScopedArguments_scope);
2509             LValue arguments = m_out.loadPtr(table, m_heaps.ScopedArgumentsTable_arguments);
2510             
2511             TypedPointer address = m_out.baseIndex(
2512                 m_heaps.scopedArgumentsTableArguments, arguments, m_out.zeroExtPtr(index));
2513             LValue scopeOffset = m_out.load32(address);
2514             
2515             speculate(
2516                 ExoticObjectMode, noValue(), nullptr,
2517                 m_out.equal(scopeOffset, m_out.constInt32(ScopeOffset::invalidOffset)));
2518             
2519             address = m_out.baseIndex(
2520                 m_heaps.JSEnvironmentRecord_variables, scope, m_out.zeroExtPtr(scopeOffset));
2521             ValueFromBlock namedResult = m_out.anchor(m_out.load64(address));
2522             m_out.jump(continuation);
2523             
2524             m_out.appendTo(overflowCase, continuation);
2525             
2526             address = m_out.baseIndex(
2527                 m_heaps.ScopedArguments_overflowStorage, base,
2528                 m_out.zeroExtPtr(m_out.sub(index, namedLength)));
2529             LValue overflowValue = m_out.load64(address);
2530             speculate(ExoticObjectMode, noValue(), nullptr, m_out.isZero64(overflowValue));
2531             ValueFromBlock overflowResult = m_out.anchor(overflowValue);
2532             m_out.jump(continuation);
2533             
2534             m_out.appendTo(continuation, lastNext);
2535             setJSValue(m_out.phi(m_out.int64, namedResult, overflowResult));
2536             return;
2537         }
2538             
2539         case Array::Generic: {
2540             setJSValue(vmCall(
2541                 m_out.operation(operationGetByVal), m_callFrame,
2542                 lowJSValue(m_node->child1()), lowJSValue(m_node->child2())));
2543             return;
2544         }
2545             
2546         case Array::String: {
2547             compileStringCharAt();
2548             return;
2549         }
2550             
2551         default: {
2552             LValue index = lowInt32(m_node->child2());
2553             LValue storage = lowStorage(m_node->child3());
2554             
2555             TypedArrayType type = m_node->arrayMode().typedArrayType();
2556             
2557             if (isTypedView(type)) {
2558                 TypedPointer pointer = TypedPointer(
2559                     m_heaps.typedArrayProperties,
2560                     m_out.add(
2561                         storage,
2562                         m_out.shl(
2563                             m_out.zeroExtPtr(index),
2564                             m_out.constIntPtr(logElementSize(type)))));
2565                 
2566                 if (isInt(type)) {
2567                     LValue result;
2568                     switch (elementSize(type)) {
2569                     case 1:
2570                         result = m_out.load8(pointer);
2571                         break;
2572                     case 2:
2573                         result = m_out.load16(pointer);
2574                         break;
2575                     case 4:
2576                         result = m_out.load32(pointer);
2577                         break;
2578                     default:
2579                         DFG_CRASH(m_graph, m_node, "Bad element size");
2580                     }
2581                     
2582                     if (elementSize(type) < 4) {
2583                         if (isSigned(type))
2584                             result = m_out.signExt(result, m_out.int32);
2585                         else
2586                             result = m_out.zeroExt(result, m_out.int32);
2587                         setInt32(result);
2588                         return;
2589                     }
2590                     
2591                     if (isSigned(type)) {
2592                         setInt32(result);
2593                         return;
2594                     }
2595                     
2596                     if (m_node->shouldSpeculateInt32()) {
2597                         speculate(
2598                             Overflow, noValue(), 0, m_out.lessThan(result, m_out.int32Zero));
2599                         setInt32(result);
2600                         return;
2601                     }
2602                     
2603                     if (m_node->shouldSpeculateMachineInt()) {
2604                         setStrictInt52(m_out.zeroExt(result, m_out.int64));
2605                         return;
2606                     }
2607                     
2608                     setDouble(m_out.unsignedToFP(result, m_out.doubleType));
2609                     return;
2610                 }
2611             
2612                 ASSERT(isFloat(type));
2613                 
2614                 LValue result;
2615                 switch (type) {
2616                 case TypeFloat32:
2617                     result = m_out.fpCast(m_out.loadFloat(pointer), m_out.doubleType);
2618                     break;
2619                 case TypeFloat64:
2620                     result = m_out.loadDouble(pointer);
2621                     break;
2622                 default:
2623                     DFG_CRASH(m_graph, m_node, "Bad typed array type");
2624                 }
2625                 
2626                 setDouble(result);
2627                 return;
2628             }
2629             
2630             DFG_CRASH(m_graph, m_node, "Bad array type");
2631             return;
2632         } }
2633     }
2634     
2635     void compileGetMyArgumentByVal()
2636     {
2637         InlineCallFrame* inlineCallFrame = m_node->child1()->origin.semantic.inlineCallFrame;
2638         
2639         LValue index = lowInt32(m_node->child2());
2640         
2641         LValue limit;
2642         if (inlineCallFrame && !inlineCallFrame->isVarargs())
2643             limit = m_out.constInt32(inlineCallFrame->arguments.size() - 1);
2644         else {
2645             VirtualRegister argumentCountRegister;
2646             if (!inlineCallFrame)
2647                 argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
2648             else
2649                 argumentCountRegister = inlineCallFrame->argumentCountRegister;
2650             limit = m_out.sub(m_out.load32(payloadFor(argumentCountRegister)), m_out.int32One);
2651         }
2652         
2653         speculate(ExoticObjectMode, noValue(), 0, m_out.aboveOrEqual(index, limit));
2654         
2655         TypedPointer base;
2656         if (inlineCallFrame) {
2657             if (inlineCallFrame->arguments.size() <= 1) {
2658                 // We should have already exited due to the bounds check, above. Just tell the
2659                 // compiler that anything dominated by this instruction is not reachable, so
2660                 // that we don't waste time generating such code. This will also plant some
2661                 // kind of crashing instruction so that if by some fluke the bounds check didn't
2662                 // work, we'll crash in an easy-to-see way.
2663                 didAlreadyTerminate();
2664                 return;
2665             }
2666             base = addressFor(inlineCallFrame->arguments[1].virtualRegister());
2667         } else
2668             base = addressFor(virtualRegisterForArgument(1));
2669         
2670         LValue pointer = m_out.baseIndex(
2671             base.value(), m_out.zeroExt(index, m_out.intPtr), ScaleEight);
2672         setJSValue(m_out.load64(TypedPointer(m_heaps.variables.atAnyIndex(), pointer)));
2673     }
2674     
2675     void compilePutByVal()
2676     {
2677         Edge child1 = m_graph.varArgChild(m_node, 0);
2678         Edge child2 = m_graph.varArgChild(m_node, 1);
2679         Edge child3 = m_graph.varArgChild(m_node, 2);
2680         Edge child4 = m_graph.varArgChild(m_node, 3);
2681         Edge child5 = m_graph.varArgChild(m_node, 4);
2682         
2683         switch (m_node->arrayMode().type()) {
2684         case Array::Generic: {
2685             V_JITOperation_EJJJ operation;
2686             if (m_node->op() == PutByValDirect) {
2687                 if (m_graph.isStrictModeFor(m_node->origin.semantic))
2688                     operation = operationPutByValDirectStrict;
2689                 else
2690                     operation = operationPutByValDirectNonStrict;
2691             } else {
2692                 if (m_graph.isStrictModeFor(m_node->origin.semantic))
2693                     operation = operationPutByValStrict;
2694                 else
2695                     operation = operationPutByValNonStrict;
2696             }
2697                 
2698             vmCall(
2699                 m_out.operation(operation), m_callFrame,
2700                 lowJSValue(child1), lowJSValue(child2), lowJSValue(child3));
2701             return;
2702         }
2703             
2704         default:
2705             break;
2706         }
2707
2708         LValue base = lowCell(child1);
2709         LValue index = lowInt32(child2);
2710         LValue storage = lowStorage(child4);
2711         
2712         switch (m_node->arrayMode().type()) {
2713         case Array::Int32:
2714         case Array::Double:
2715         case Array::Contiguous: {
2716             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("PutByVal continuation"));
2717             LBasicBlock outerLastNext = m_out.appendTo(m_out.m_block, continuation);
2718             
2719             switch (m_node->arrayMode().type()) {
2720             case Array::Int32:
2721             case Array::Contiguous: {
2722                 LValue value = lowJSValue(child3, ManualOperandSpeculation);
2723                 
2724                 if (m_node->arrayMode().type() == Array::Int32)
2725                     FTL_TYPE_CHECK(jsValueValue(value), child3, SpecInt32, isNotInt32(value));
2726                 
2727                 TypedPointer elementPointer = m_out.baseIndex(
2728                     m_node->arrayMode().type() == Array::Int32 ?
2729                     m_heaps.indexedInt32Properties : m_heaps.indexedContiguousProperties,
2730                     storage, m_out.zeroExtPtr(index), provenValue(child2));
2731                 
2732                 if (m_node->op() == PutByValAlias) {
2733                     m_out.store64(value, elementPointer);
2734                     break;
2735                 }
2736                 
2737                 contiguousPutByValOutOfBounds(
2738                     codeBlock()->isStrictMode()
2739                     ? operationPutByValBeyondArrayBoundsStrict
2740                     : operationPutByValBeyondArrayBoundsNonStrict,
2741                     base, storage, index, value, continuation);
2742                 
2743                 m_out.store64(value, elementPointer);
2744                 break;
2745             }
2746                 
2747             case Array::Double: {
2748                 LValue value = lowDouble(child3);
2749                 
2750                 FTL_TYPE_CHECK(
2751                     doubleValue(value), child3, SpecDoubleReal,
2752                     m_out.doubleNotEqualOrUnordered(value, value));
2753                 
2754                 TypedPointer elementPointer = m_out.baseIndex(
2755                     m_heaps.indexedDoubleProperties, storage, m_out.zeroExtPtr(index),
2756                     provenValue(child2));
2757                 
2758                 if (m_node->op() == PutByValAlias) {
2759                     m_out.storeDouble(value, elementPointer);
2760                     break;
2761                 }
2762                 
2763                 contiguousPutByValOutOfBounds(
2764                     codeBlock()->isStrictMode()
2765                     ? operationPutDoubleByValBeyondArrayBoundsStrict
2766                     : operationPutDoubleByValBeyondArrayBoundsNonStrict,
2767                     base, storage, index, value, continuation);
2768                 
2769                 m_out.storeDouble(value, elementPointer);
2770                 break;
2771             }
2772                 
2773             default:
2774                 DFG_CRASH(m_graph, m_node, "Bad array type");
2775             }
2776
2777             m_out.jump(continuation);
2778             m_out.appendTo(continuation, outerLastNext);
2779             return;
2780         }
2781             
2782         default:
2783             TypedArrayType type = m_node->arrayMode().typedArrayType();
2784             
2785             if (isTypedView(type)) {
2786                 TypedPointer pointer = TypedPointer(
2787                     m_heaps.typedArrayProperties,
2788                     m_out.add(
2789                         storage,
2790                         m_out.shl(
2791                             m_out.zeroExt(index, m_out.intPtr),
2792                             m_out.constIntPtr(logElementSize(type)))));
2793                 
2794                 LType refType;
2795                 LValue valueToStore;
2796                 
2797                 if (isInt(type)) {
2798                     LValue intValue;
2799                     switch (child3.useKind()) {
2800                     case Int52RepUse:
2801                     case Int32Use: {
2802                         if (child3.useKind() == Int32Use)
2803                             intValue = lowInt32(child3);
2804                         else
2805                             intValue = m_out.castToInt32(lowStrictInt52(child3));
2806
2807                         if (isClamped(type)) {
2808                             ASSERT(elementSize(type) == 1);
2809                             
2810                             LBasicBlock atLeastZero = FTL_NEW_BLOCK(m_out, ("PutByVal int clamp atLeastZero"));
2811                             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("PutByVal int clamp continuation"));
2812                             
2813                             Vector<ValueFromBlock, 2> intValues;
2814                             intValues.append(m_out.anchor(m_out.int32Zero));
2815                             m_out.branch(
2816                                 m_out.lessThan(intValue, m_out.int32Zero),
2817                                 unsure(continuation), unsure(atLeastZero));
2818                             
2819                             LBasicBlock lastNext = m_out.appendTo(atLeastZero, continuation);
2820                             
2821                             intValues.append(m_out.anchor(m_out.select(
2822                                 m_out.greaterThan(intValue, m_out.constInt32(255)),
2823                                 m_out.constInt32(255),
2824                                 intValue)));
2825                             m_out.jump(continuation);
2826                             
2827                             m_out.appendTo(continuation, lastNext);
2828                             intValue = m_out.phi(m_out.int32, intValues);
2829                         }
2830                         break;
2831                     }
2832                         
2833                     case DoubleRepUse: {
2834                         LValue doubleValue = lowDouble(child3);
2835                         
2836                         if (isClamped(type)) {
2837                             ASSERT(elementSize(type) == 1);
2838                             
2839                             LBasicBlock atLeastZero = FTL_NEW_BLOCK(m_out, ("PutByVal double clamp atLeastZero"));
2840                             LBasicBlock withinRange = FTL_NEW_BLOCK(m_out, ("PutByVal double clamp withinRange"));
2841                             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("PutByVal double clamp continuation"));
2842                             
2843                             Vector<ValueFromBlock, 3> intValues;
2844                             intValues.append(m_out.anchor(m_out.int32Zero));
2845                             m_out.branch(
2846                                 m_out.doubleLessThanOrUnordered(doubleValue, m_out.doubleZero),
2847                                 unsure(continuation), unsure(atLeastZero));
2848                             
2849                             LBasicBlock lastNext = m_out.appendTo(atLeastZero, withinRange);
2850                             intValues.append(m_out.anchor(m_out.constInt32(255)));
2851                             m_out.branch(
2852                                 m_out.doubleGreaterThan(doubleValue, m_out.constDouble(255)),
2853                                 unsure(continuation), unsure(withinRange));
2854                             
2855                             m_out.appendTo(withinRange, continuation);
2856                             intValues.append(m_out.anchor(m_out.fpToInt32(doubleValue)));
2857                             m_out.jump(continuation);
2858                             
2859                             m_out.appendTo(continuation, lastNext);
2860                             intValue = m_out.phi(m_out.int32, intValues);
2861                         } else
2862                             intValue = doubleToInt32(doubleValue);
2863                         break;
2864                     }
2865                         
2866                     default:
2867                         DFG_CRASH(m_graph, m_node, "Bad use kind");
2868                     }
2869                     
2870                     switch (elementSize(type)) {
2871                     case 1:
2872                         valueToStore = m_out.intCast(intValue, m_out.int8);
2873                         refType = m_out.ref8;
2874                         break;
2875                     case 2:
2876                         valueToStore = m_out.intCast(intValue, m_out.int16);
2877                         refType = m_out.ref16;
2878                         break;
2879                     case 4:
2880                         valueToStore = intValue;
2881                         refType = m_out.ref32;
2882                         break;
2883                     default:
2884                         DFG_CRASH(m_graph, m_node, "Bad element size");
2885                     }
2886                 } else /* !isInt(type) */ {
2887                     LValue value = lowDouble(child3);
2888                     switch (type) {
2889                     case TypeFloat32:
2890                         valueToStore = m_out.fpCast(value, m_out.floatType);
2891                         refType = m_out.refFloat;
2892                         break;
2893                     case TypeFloat64:
2894                         valueToStore = value;
2895                         refType = m_out.refDouble;
2896                         break;
2897                     default:
2898                         DFG_CRASH(m_graph, m_node, "Bad typed array type");
2899                     }
2900                 }
2901                 
2902                 if (m_node->arrayMode().isInBounds() || m_node->op() == PutByValAlias)
2903                     m_out.store(valueToStore, pointer, refType);
2904                 else {
2905                     LBasicBlock isInBounds = FTL_NEW_BLOCK(m_out, ("PutByVal typed array in bounds case"));
2906                     LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("PutByVal typed array continuation"));
2907                     
2908                     m_out.branch(
2909                         m_out.aboveOrEqual(index, lowInt32(child5)),
2910                         unsure(continuation), unsure(isInBounds));
2911                     
2912                     LBasicBlock lastNext = m_out.appendTo(isInBounds, continuation);
2913                     m_out.store(valueToStore, pointer, refType);
2914                     m_out.jump(continuation);
2915                     
2916                     m_out.appendTo(continuation, lastNext);
2917                 }
2918                 
2919                 return;
2920             }
2921             
2922             DFG_CRASH(m_graph, m_node, "Bad array type");
2923             break;
2924         }
2925     }
2926     
2927     void compileArrayPush()
2928     {
2929         LValue base = lowCell(m_node->child1());
2930         LValue storage = lowStorage(m_node->child3());
2931         
2932         switch (m_node->arrayMode().type()) {
2933         case Array::Int32:
2934         case Array::Contiguous:
2935         case Array::Double: {
2936             LValue value;
2937             LType refType;
2938             
2939             if (m_node->arrayMode().type() != Array::Double) {
2940                 value = lowJSValue(m_node->child2(), ManualOperandSpeculation);
2941                 if (m_node->arrayMode().type() == Array::Int32) {
2942                     FTL_TYPE_CHECK(
2943                         jsValueValue(value), m_node->child2(), SpecInt32, isNotInt32(value));
2944                 }
2945                 refType = m_out.ref64;
2946             } else {
2947                 value = lowDouble(m_node->child2());
2948                 FTL_TYPE_CHECK(
2949                     doubleValue(value), m_node->child2(), SpecDoubleReal,
2950                     m_out.doubleNotEqualOrUnordered(value, value));
2951                 refType = m_out.refDouble;
2952             }
2953             
2954             IndexedAbstractHeap& heap = m_heaps.forArrayType(m_node->arrayMode().type());
2955
2956             LValue prevLength = m_out.load32(storage, m_heaps.Butterfly_publicLength);
2957             
2958             LBasicBlock fastPath = FTL_NEW_BLOCK(m_out, ("ArrayPush fast path"));
2959             LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("ArrayPush slow path"));
2960             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArrayPush continuation"));
2961             
2962             m_out.branch(
2963                 m_out.aboveOrEqual(
2964                     prevLength, m_out.load32(storage, m_heaps.Butterfly_vectorLength)),
2965                 rarely(slowPath), usually(fastPath));
2966             
2967             LBasicBlock lastNext = m_out.appendTo(fastPath, slowPath);
2968             m_out.store(
2969                 value, m_out.baseIndex(heap, storage, m_out.zeroExtPtr(prevLength)), refType);
2970             LValue newLength = m_out.add(prevLength, m_out.int32One);
2971             m_out.store32(newLength, storage, m_heaps.Butterfly_publicLength);
2972             
2973             ValueFromBlock fastResult = m_out.anchor(boxInt32(newLength));
2974             m_out.jump(continuation);
2975             
2976             m_out.appendTo(slowPath, continuation);
2977             LValue operation;
2978             if (m_node->arrayMode().type() != Array::Double)
2979                 operation = m_out.operation(operationArrayPush);
2980             else
2981                 operation = m_out.operation(operationArrayPushDouble);
2982             ValueFromBlock slowResult = m_out.anchor(
2983                 vmCall(operation, m_callFrame, value, base));
2984             m_out.jump(continuation);
2985             
2986             m_out.appendTo(continuation, lastNext);
2987             setJSValue(m_out.phi(m_out.int64, fastResult, slowResult));
2988             return;
2989         }
2990             
2991         default:
2992             DFG_CRASH(m_graph, m_node, "Bad array type");
2993             return;
2994         }
2995     }
2996     
2997     void compileArrayPop()
2998     {
2999         LValue base = lowCell(m_node->child1());
3000         LValue storage = lowStorage(m_node->child2());
3001         
3002         switch (m_node->arrayMode().type()) {
3003         case Array::Int32:
3004         case Array::Double:
3005         case Array::Contiguous: {
3006             IndexedAbstractHeap& heap = m_heaps.forArrayType(m_node->arrayMode().type());
3007             
3008             LBasicBlock fastCase = FTL_NEW_BLOCK(m_out, ("ArrayPop fast case"));
3009             LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("ArrayPop slow case"));
3010             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArrayPop continuation"));
3011             
3012             LValue prevLength = m_out.load32(storage, m_heaps.Butterfly_publicLength);
3013             
3014             Vector<ValueFromBlock, 3> results;
3015             results.append(m_out.anchor(m_out.constInt64(JSValue::encode(jsUndefined()))));
3016             m_out.branch(
3017                 m_out.isZero32(prevLength), rarely(continuation), usually(fastCase));
3018             
3019             LBasicBlock lastNext = m_out.appendTo(fastCase, slowCase);
3020             LValue newLength = m_out.sub(prevLength, m_out.int32One);
3021             m_out.store32(newLength, storage, m_heaps.Butterfly_publicLength);
3022             TypedPointer pointer = m_out.baseIndex(heap, storage, m_out.zeroExtPtr(newLength));
3023             if (m_node->arrayMode().type() != Array::Double) {
3024                 LValue result = m_out.load64(pointer);
3025                 m_out.store64(m_out.int64Zero, pointer);
3026                 results.append(m_out.anchor(result));
3027                 m_out.branch(
3028                     m_out.notZero64(result), usually(continuation), rarely(slowCase));
3029             } else {
3030                 LValue result = m_out.loadDouble(pointer);
3031                 m_out.store64(m_out.constInt64(bitwise_cast<int64_t>(PNaN)), pointer);
3032                 results.append(m_out.anchor(boxDouble(result)));
3033                 m_out.branch(
3034                     m_out.doubleEqual(result, result),
3035                     usually(continuation), rarely(slowCase));
3036             }
3037             
3038             m_out.appendTo(slowCase, continuation);
3039             results.append(m_out.anchor(vmCall(
3040                 m_out.operation(operationArrayPopAndRecoverLength), m_callFrame, base)));
3041             m_out.jump(continuation);
3042             
3043             m_out.appendTo(continuation, lastNext);
3044             setJSValue(m_out.phi(m_out.int64, results));
3045             return;
3046         }
3047
3048         default:
3049             DFG_CRASH(m_graph, m_node, "Bad array type");
3050             return;
3051         }
3052     }
3053