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