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