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