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