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