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