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