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