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