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