53c505c6b03722e0023891e44c32733b09d0f29d
[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 CheckIdent:
606             compileCheckIdent();
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 compileCheckIdent()
2481     {
2482         UniquedStringImpl* uid = m_node->uidOperand();
2483         if (uid->isSymbol()) {
2484             LValue stringImpl = lowSymbolUID(m_node->child1());
2485             speculate(BadIdent, noValue(), nullptr, m_out.notEqual(stringImpl, m_out.constIntPtr(uid)));
2486         } else {
2487             LValue string = lowStringIdent(m_node->child1());
2488             LValue stringImpl = m_out.loadPtr(string, m_heaps.JSString_value);
2489             speculate(BadIdent, noValue(), nullptr, m_out.notEqual(stringImpl, m_out.constIntPtr(uid)));
2490         }
2491     }
2492
2493     void compileGetExecutable()
2494     {
2495         LValue cell = lowCell(m_node->child1());
2496         speculateFunction(m_node->child1(), cell);
2497         setJSValue(m_out.loadPtr(cell, m_heaps.JSFunction_executable));
2498     }
2499     
2500     void compileArrayifyToStructure()
2501     {
2502         LValue cell = lowCell(m_node->child1());
2503         LValue property = !!m_node->child2() ? lowInt32(m_node->child2()) : 0;
2504         
2505         LBasicBlock unexpectedStructure = m_out.newBlock();
2506         LBasicBlock continuation = m_out.newBlock();
2507         
2508         LValue structureID = m_out.load32(cell, m_heaps.JSCell_structureID);
2509         
2510         m_out.branch(
2511             m_out.notEqual(structureID, weakStructureID(m_node->structure())),
2512             rarely(unexpectedStructure), usually(continuation));
2513         
2514         LBasicBlock lastNext = m_out.appendTo(unexpectedStructure, continuation);
2515         
2516         if (property) {
2517             switch (m_node->arrayMode().type()) {
2518             case Array::Int32:
2519             case Array::Double:
2520             case Array::Contiguous:
2521                 speculate(
2522                     Uncountable, noValue(), 0,
2523                     m_out.aboveOrEqual(property, m_out.constInt32(MIN_SPARSE_ARRAY_INDEX)));
2524                 break;
2525             default:
2526                 break;
2527             }
2528         }
2529         
2530         switch (m_node->arrayMode().type()) {
2531         case Array::Int32:
2532             vmCall(Void, m_out.operation(operationEnsureInt32), m_callFrame, cell);
2533             break;
2534         case Array::Double:
2535             vmCall(Void, m_out.operation(operationEnsureDouble), m_callFrame, cell);
2536             break;
2537         case Array::Contiguous:
2538             vmCall(Void, m_out.operation(operationEnsureContiguous), m_callFrame, cell);
2539             break;
2540         case Array::ArrayStorage:
2541         case Array::SlowPutArrayStorage:
2542             vmCall(Void, m_out.operation(operationEnsureArrayStorage), m_callFrame, cell);
2543             break;
2544         default:
2545             DFG_CRASH(m_graph, m_node, "Bad array type");
2546             break;
2547         }
2548         
2549         structureID = m_out.load32(cell, m_heaps.JSCell_structureID);
2550         speculate(
2551             BadIndexingType, jsValueValue(cell), 0,
2552             m_out.notEqual(structureID, weakStructureID(m_node->structure())));
2553         m_out.jump(continuation);
2554         
2555         m_out.appendTo(continuation, lastNext);
2556     }
2557     
2558     void compilePutStructure()
2559     {
2560         m_ftlState.jitCode->common.notifyCompilingStructureTransition(m_graph.m_plan, codeBlock(), m_node);
2561
2562         Structure* oldStructure = m_node->transition()->previous;
2563         Structure* newStructure = m_node->transition()->next;
2564         ASSERT_UNUSED(oldStructure, oldStructure->indexingType() == newStructure->indexingType());
2565         ASSERT(oldStructure->typeInfo().inlineTypeFlags() == newStructure->typeInfo().inlineTypeFlags());
2566         ASSERT(oldStructure->typeInfo().type() == newStructure->typeInfo().type());
2567
2568         LValue cell = lowCell(m_node->child1()); 
2569         m_out.store32(
2570             weakStructureID(newStructure),
2571             cell, m_heaps.JSCell_structureID);
2572     }
2573     
2574     void compileGetById(AccessType type)
2575     {
2576         ASSERT(type == AccessType::Get || type == AccessType::GetPure);
2577         switch (m_node->child1().useKind()) {
2578         case CellUse: {
2579             setJSValue(getById(lowCell(m_node->child1()), type));
2580             return;
2581         }
2582             
2583         case UntypedUse: {
2584             // This is pretty weird, since we duplicate the slow path both here and in the
2585             // code generated by the IC. We should investigate making this less bad.
2586             // https://bugs.webkit.org/show_bug.cgi?id=127830
2587             LValue value = lowJSValue(m_node->child1());
2588             
2589             LBasicBlock cellCase = m_out.newBlock();
2590             LBasicBlock notCellCase = m_out.newBlock();
2591             LBasicBlock continuation = m_out.newBlock();
2592             
2593             m_out.branch(
2594                 isCell(value, provenType(m_node->child1())), unsure(cellCase), unsure(notCellCase));
2595             
2596             LBasicBlock lastNext = m_out.appendTo(cellCase, notCellCase);
2597             ValueFromBlock cellResult = m_out.anchor(getById(value, type));
2598             m_out.jump(continuation);
2599
2600             J_JITOperation_EJI getByIdFunction;
2601             if (type == AccessType::Get)
2602                 getByIdFunction = operationGetByIdGeneric;
2603             else
2604                 getByIdFunction = operationTryGetByIdGeneric;
2605
2606             m_out.appendTo(notCellCase, continuation);
2607             ValueFromBlock notCellResult = m_out.anchor(vmCall(
2608                 Int64, m_out.operation(getByIdFunction),
2609                 m_callFrame, value,
2610                 m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()])));
2611             m_out.jump(continuation);
2612             
2613             m_out.appendTo(continuation, lastNext);
2614             setJSValue(m_out.phi(Int64, cellResult, notCellResult));
2615             return;
2616         }
2617             
2618         default:
2619             DFG_CRASH(m_graph, m_node, "Bad use kind");
2620             return;
2621         }
2622     }
2623
2624     void compileGetByIdWithThis()
2625     {
2626         LValue base = lowJSValue(m_node->child1());
2627         LValue thisValue = lowJSValue(m_node->child2());
2628         LValue result = vmCall(Int64, m_out.operation(operationGetByIdWithThis), m_callFrame, base, thisValue, m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()]));
2629         setJSValue(result);
2630     }
2631
2632     void compileGetByValWithThis()
2633     {
2634         LValue base = lowJSValue(m_node->child1());
2635         LValue thisValue = lowJSValue(m_node->child2());
2636         LValue subscript = lowJSValue(m_node->child3());
2637
2638         LValue result = vmCall(Int64, m_out.operation(operationGetByValWithThis), m_callFrame, base, thisValue, subscript);
2639         setJSValue(result);
2640     }
2641
2642     void compilePutByIdWithThis()
2643     {
2644         LValue base = lowJSValue(m_node->child1());
2645         LValue thisValue = lowJSValue(m_node->child2());
2646         LValue value = lowJSValue(m_node->child3());
2647
2648         vmCall(Void, m_out.operation(m_graph.isStrictModeFor(m_node->origin.semantic) ? operationPutByIdWithThisStrict : operationPutByIdWithThis),
2649             m_callFrame, base, thisValue, value, m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()]));
2650     }
2651
2652     void compilePutByValWithThis()
2653     {
2654         LValue base = lowJSValue(m_graph.varArgChild(m_node, 0));
2655         LValue thisValue = lowJSValue(m_graph.varArgChild(m_node, 1));
2656         LValue property = lowJSValue(m_graph.varArgChild(m_node, 2));
2657         LValue value = lowJSValue(m_graph.varArgChild(m_node, 3));
2658
2659         vmCall(Void, m_out.operation(m_graph.isStrictModeFor(m_node->origin.semantic) ? operationPutByValWithThisStrict : operationPutByValWithThis),
2660             m_callFrame, base, thisValue, property, value);
2661     }
2662     
2663     void compilePutById()
2664     {
2665         Node* node = m_node;
2666         
2667         // See above; CellUse is easier so we do only that for now.
2668         ASSERT(node->child1().useKind() == CellUse);
2669
2670         LValue base = lowCell(node->child1());
2671         LValue value = lowJSValue(node->child2());
2672         auto uid = m_graph.identifiers()[node->identifierNumber()];
2673
2674         B3::PatchpointValue* patchpoint = m_out.patchpoint(Void);
2675         patchpoint->appendSomeRegister(base);
2676         patchpoint->appendSomeRegister(value);
2677         patchpoint->append(m_tagMask, ValueRep::reg(GPRInfo::tagMaskRegister));
2678         patchpoint->append(m_tagTypeNumber, ValueRep::reg(GPRInfo::tagTypeNumberRegister));
2679         patchpoint->clobber(RegisterSet::macroScratchRegisters());
2680
2681         // FIXME: If this is a PutByIdFlush, we might want to late-clobber volatile registers.
2682         // https://bugs.webkit.org/show_bug.cgi?id=152848
2683
2684         RefPtr<PatchpointExceptionHandle> exceptionHandle =
2685             preparePatchpointForExceptions(patchpoint);
2686
2687         State* state = &m_ftlState;
2688         ECMAMode ecmaMode = m_graph.executableFor(node->origin.semantic)->ecmaMode();
2689         
2690         patchpoint->setGenerator(
2691             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
2692                 AllowMacroScratchRegisterUsage allowScratch(jit);
2693
2694                 CallSiteIndex callSiteIndex =
2695                     state->jitCode->common.addUniqueCallSiteIndex(node->origin.semantic);
2696
2697                 Box<CCallHelpers::JumpList> exceptions =
2698                     exceptionHandle->scheduleExitCreation(params)->jumps(jit);
2699
2700                 // JS setter call ICs generated by the PutById IC will need this.
2701                 exceptionHandle->scheduleExitCreationForUnwind(params, callSiteIndex);
2702
2703                 auto generator = Box<JITPutByIdGenerator>::create(
2704                     jit.codeBlock(), node->origin.semantic, callSiteIndex,
2705                     params.unavailableRegisters(), JSValueRegs(params[0].gpr()),
2706                     JSValueRegs(params[1].gpr()), GPRInfo::patchpointScratchRegister, ecmaMode,
2707                     node->op() == PutByIdDirect ? Direct : NotDirect);
2708
2709                 generator->generateFastPath(jit);
2710                 CCallHelpers::Label done = jit.label();
2711
2712                 params.addLatePath(
2713                     [=] (CCallHelpers& jit) {
2714                         AllowMacroScratchRegisterUsage allowScratch(jit);
2715
2716                         generator->slowPathJump().link(&jit);
2717                         CCallHelpers::Label slowPathBegin = jit.label();
2718                         CCallHelpers::Call slowPathCall = callOperation(
2719                             *state, params.unavailableRegisters(), jit, node->origin.semantic,
2720                             exceptions.get(), generator->slowPathFunction(), InvalidGPRReg,
2721                             CCallHelpers::TrustedImmPtr(generator->stubInfo()), params[1].gpr(),
2722                             params[0].gpr(), CCallHelpers::TrustedImmPtr(uid)).call();
2723                         jit.jump().linkTo(done, &jit);
2724
2725                         generator->reportSlowPathCall(slowPathBegin, slowPathCall);
2726
2727                         jit.addLinkTask(
2728                             [=] (LinkBuffer& linkBuffer) {
2729                                 generator->finalize(linkBuffer);
2730                             });
2731                     });
2732             });
2733     }
2734     
2735     void compileGetButterfly()
2736     {
2737         setStorage(m_out.loadPtr(lowCell(m_node->child1()), m_heaps.JSObject_butterfly));
2738     }
2739
2740     void compileConstantStoragePointer()
2741     {
2742         setStorage(m_out.constIntPtr(m_node->storagePointer()));
2743     }
2744     
2745     void compileGetIndexedPropertyStorage()
2746     {
2747         LValue cell = lowCell(m_node->child1());
2748         
2749         if (m_node->arrayMode().type() == Array::String) {
2750             LBasicBlock slowPath = m_out.newBlock();
2751             LBasicBlock continuation = m_out.newBlock();
2752
2753             LValue fastResultValue = m_out.loadPtr(cell, m_heaps.JSString_value);
2754             ValueFromBlock fastResult = m_out.anchor(fastResultValue);
2755             
2756             m_out.branch(
2757                 m_out.notNull(fastResultValue), usually(continuation), rarely(slowPath));
2758             
2759             LBasicBlock lastNext = m_out.appendTo(slowPath, continuation);
2760             
2761             ValueFromBlock slowResult = m_out.anchor(
2762                 vmCall(pointerType(), m_out.operation(operationResolveRope), m_callFrame, cell));
2763             
2764             m_out.jump(continuation);
2765             
2766             m_out.appendTo(continuation, lastNext);
2767             
2768             setStorage(m_out.loadPtr(m_out.phi(pointerType(), fastResult, slowResult), m_heaps.StringImpl_data));
2769             return;
2770         }
2771         
2772         setStorage(m_out.loadPtr(cell, m_heaps.JSArrayBufferView_vector));
2773     }
2774     
2775     void compileCheckArray()
2776     {
2777         Edge edge = m_node->child1();
2778         LValue cell = lowCell(edge);
2779         
2780         if (m_node->arrayMode().alreadyChecked(m_graph, m_node, abstractValue(edge)))
2781             return;
2782         
2783         speculate(
2784             BadIndexingType, jsValueValue(cell), 0,
2785             m_out.logicalNot(isArrayType(cell, m_node->arrayMode())));
2786     }
2787
2788     void compileGetTypedArrayByteOffset()
2789     {
2790         LValue basePtr = lowCell(m_node->child1());    
2791
2792         LBasicBlock simpleCase = m_out.newBlock();
2793         LBasicBlock wastefulCase = m_out.newBlock();
2794         LBasicBlock continuation = m_out.newBlock();
2795         
2796         LValue mode = m_out.load32(basePtr, m_heaps.JSArrayBufferView_mode);
2797         m_out.branch(
2798             m_out.notEqual(mode, m_out.constInt32(WastefulTypedArray)),
2799             unsure(simpleCase), unsure(wastefulCase));
2800
2801         LBasicBlock lastNext = m_out.appendTo(simpleCase, wastefulCase);
2802
2803         ValueFromBlock simpleOut = m_out.anchor(m_out.constIntPtr(0));
2804
2805         m_out.jump(continuation);
2806
2807         m_out.appendTo(wastefulCase, continuation);
2808
2809         LValue vectorPtr = m_out.loadPtr(basePtr, m_heaps.JSArrayBufferView_vector);
2810         LValue butterflyPtr = m_out.loadPtr(basePtr, m_heaps.JSObject_butterfly);
2811         LValue arrayBufferPtr = m_out.loadPtr(butterflyPtr, m_heaps.Butterfly_arrayBuffer);
2812         LValue dataPtr = m_out.loadPtr(arrayBufferPtr, m_heaps.ArrayBuffer_data);
2813
2814         ValueFromBlock wastefulOut = m_out.anchor(m_out.sub(vectorPtr, dataPtr));
2815
2816         m_out.jump(continuation);
2817         m_out.appendTo(continuation, lastNext);
2818
2819         setInt32(m_out.castToInt32(m_out.phi(pointerType(), simpleOut, wastefulOut)));
2820     }
2821     
2822     void compileGetArrayLength()
2823     {
2824         switch (m_node->arrayMode().type()) {
2825         case Array::Int32:
2826         case Array::Double:
2827         case Array::Contiguous: {
2828             setInt32(m_out.load32NonNegative(lowStorage(m_node->child2()), m_heaps.Butterfly_publicLength));
2829             return;
2830         }
2831             
2832         case Array::String: {
2833             LValue string = lowCell(m_node->child1());
2834             setInt32(m_out.load32NonNegative(string, m_heaps.JSString_length));
2835             return;
2836         }
2837             
2838         case Array::DirectArguments: {
2839             LValue arguments = lowCell(m_node->child1());
2840             speculate(
2841                 ExoticObjectMode, noValue(), nullptr,
2842                 m_out.notNull(m_out.loadPtr(arguments, m_heaps.DirectArguments_overrides)));
2843             setInt32(m_out.load32NonNegative(arguments, m_heaps.DirectArguments_length));
2844             return;
2845         }
2846             
2847         case Array::ScopedArguments: {
2848             LValue arguments = lowCell(m_node->child1());
2849             speculate(
2850                 ExoticObjectMode, noValue(), nullptr,
2851                 m_out.notZero32(m_out.load8ZeroExt32(arguments, m_heaps.ScopedArguments_overrodeThings)));
2852             setInt32(m_out.load32NonNegative(arguments, m_heaps.ScopedArguments_totalLength));
2853             return;
2854         }
2855             
2856         default:
2857             if (m_node->arrayMode().isSomeTypedArrayView()) {
2858                 setInt32(
2859                     m_out.load32NonNegative(lowCell(m_node->child1()), m_heaps.JSArrayBufferView_length));
2860                 return;
2861             }
2862             
2863             DFG_CRASH(m_graph, m_node, "Bad array type");
2864             return;
2865         }
2866     }
2867     
2868     void compileCheckInBounds()
2869     {
2870         speculate(
2871             OutOfBounds, noValue(), 0,
2872             m_out.aboveOrEqual(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2873     }
2874     
2875     void compileGetByVal()
2876     {
2877         switch (m_node->arrayMode().type()) {
2878         case Array::Int32:
2879         case Array::Contiguous: {
2880             LValue index = lowInt32(m_node->child2());
2881             LValue storage = lowStorage(m_node->child3());
2882             
2883             IndexedAbstractHeap& heap = m_node->arrayMode().type() == Array::Int32 ?
2884                 m_heaps.indexedInt32Properties : m_heaps.indexedContiguousProperties;
2885             
2886             if (m_node->arrayMode().isInBounds()) {
2887                 LValue result = m_out.load64(baseIndex(heap, storage, index, m_node->child2()));
2888                 LValue isHole = m_out.isZero64(result);
2889                 if (m_node->arrayMode().isSaneChain()) {
2890                     DFG_ASSERT(
2891                         m_graph, m_node, m_node->arrayMode().type() == Array::Contiguous);
2892                     result = m_out.select(
2893                         isHole, m_out.constInt64(JSValue::encode(jsUndefined())), result);
2894                 } else
2895                     speculate(LoadFromHole, noValue(), 0, isHole);
2896                 setJSValue(result);
2897                 return;
2898             }
2899             
2900             LValue base = lowCell(m_node->child1());
2901             
2902             LBasicBlock fastCase = m_out.newBlock();
2903             LBasicBlock slowCase = m_out.newBlock();
2904             LBasicBlock continuation = m_out.newBlock();
2905             
2906             m_out.branch(
2907                 m_out.aboveOrEqual(
2908                     index, m_out.load32NonNegative(storage, m_heaps.Butterfly_publicLength)),
2909                 rarely(slowCase), usually(fastCase));
2910             
2911             LBasicBlock lastNext = m_out.appendTo(fastCase, slowCase);
2912
2913             LValue fastResultValue = m_out.load64(baseIndex(heap, storage, index, m_node->child2()));
2914             ValueFromBlock fastResult = m_out.anchor(fastResultValue);
2915             m_out.branch(
2916                 m_out.isZero64(fastResultValue), rarely(slowCase), usually(continuation));
2917             
2918             m_out.appendTo(slowCase, continuation);
2919             ValueFromBlock slowResult = m_out.anchor(
2920                 vmCall(Int64, m_out.operation(operationGetByValArrayInt), m_callFrame, base, index));
2921             m_out.jump(continuation);
2922             
2923             m_out.appendTo(continuation, lastNext);
2924             setJSValue(m_out.phi(Int64, fastResult, slowResult));
2925             return;
2926         }
2927             
2928         case Array::Double: {
2929             LValue index = lowInt32(m_node->child2());
2930             LValue storage = lowStorage(m_node->child3());
2931             
2932             IndexedAbstractHeap& heap = m_heaps.indexedDoubleProperties;
2933             
2934             if (m_node->arrayMode().isInBounds()) {
2935                 LValue result = m_out.loadDouble(
2936                     baseIndex(heap, storage, index, m_node->child2()));
2937                 
2938                 if (!m_node->arrayMode().isSaneChain()) {
2939                     speculate(
2940                         LoadFromHole, noValue(), 0,
2941                         m_out.doubleNotEqualOrUnordered(result, result));
2942                 }
2943                 setDouble(result);
2944                 break;
2945             }
2946             
2947             LValue base = lowCell(m_node->child1());
2948             
2949             LBasicBlock inBounds = m_out.newBlock();
2950             LBasicBlock boxPath = m_out.newBlock();
2951             LBasicBlock slowCase = m_out.newBlock();
2952             LBasicBlock continuation = m_out.newBlock();
2953             
2954             m_out.branch(
2955                 m_out.aboveOrEqual(
2956                     index, m_out.load32NonNegative(storage, m_heaps.Butterfly_publicLength)),
2957                 rarely(slowCase), usually(inBounds));
2958             
2959             LBasicBlock lastNext = m_out.appendTo(inBounds, boxPath);
2960             LValue doubleValue = m_out.loadDouble(
2961                 baseIndex(heap, storage, index, m_node->child2()));
2962             m_out.branch(
2963                 m_out.doubleNotEqualOrUnordered(doubleValue, doubleValue),
2964                 rarely(slowCase), usually(boxPath));
2965             
2966             m_out.appendTo(boxPath, slowCase);
2967             ValueFromBlock fastResult = m_out.anchor(boxDouble(doubleValue));
2968             m_out.jump(continuation);
2969             
2970             m_out.appendTo(slowCase, continuation);
2971             ValueFromBlock slowResult = m_out.anchor(
2972                 vmCall(Int64, m_out.operation(operationGetByValArrayInt), m_callFrame, base, index));
2973             m_out.jump(continuation);
2974             
2975             m_out.appendTo(continuation, lastNext);
2976             setJSValue(m_out.phi(Int64, fastResult, slowResult));
2977             return;
2978         }
2979
2980         case Array::Undecided: {
2981             LValue index = lowInt32(m_node->child2());
2982
2983             speculate(OutOfBounds, noValue(), m_node, m_out.lessThan(index, m_out.int32Zero));
2984             setJSValue(m_out.constInt64(ValueUndefined));
2985             return;
2986         }
2987             
2988         case Array::DirectArguments: {
2989             LValue base = lowCell(m_node->child1());
2990             LValue index = lowInt32(m_node->child2());
2991             
2992             speculate(
2993                 ExoticObjectMode, noValue(), nullptr,
2994                 m_out.notNull(m_out.loadPtr(base, m_heaps.DirectArguments_overrides)));
2995             speculate(
2996                 ExoticObjectMode, noValue(), nullptr,
2997                 m_out.aboveOrEqual(
2998                     index,
2999                     m_out.load32NonNegative(base, m_heaps.DirectArguments_length)));
3000
3001             TypedPointer address = m_out.baseIndex(
3002                 m_heaps.DirectArguments_storage, base, m_out.zeroExtPtr(index));
3003             setJSValue(m_out.load64(address));
3004             return;
3005         }
3006             
3007         case Array::ScopedArguments: {
3008             LValue base = lowCell(m_node->child1());
3009             LValue index = lowInt32(m_node->child2());
3010             
3011             speculate(
3012                 ExoticObjectMode, noValue(), nullptr,
3013                 m_out.aboveOrEqual(
3014                     index,
3015                     m_out.load32NonNegative(base, m_heaps.ScopedArguments_totalLength)));
3016             
3017             LValue table = m_out.loadPtr(base, m_heaps.ScopedArguments_table);
3018             LValue namedLength = m_out.load32(table, m_heaps.ScopedArgumentsTable_length);
3019             
3020             LBasicBlock namedCase = m_out.newBlock();
3021             LBasicBlock overflowCase = m_out.newBlock();
3022             LBasicBlock continuation = m_out.newBlock();
3023             
3024             m_out.branch(
3025                 m_out.aboveOrEqual(index, namedLength), unsure(overflowCase), unsure(namedCase));
3026             
3027             LBasicBlock lastNext = m_out.appendTo(namedCase, overflowCase);
3028             
3029             LValue scope = m_out.loadPtr(base, m_heaps.ScopedArguments_scope);
3030             LValue arguments = m_out.loadPtr(table, m_heaps.ScopedArgumentsTable_arguments);
3031             
3032             TypedPointer address = m_out.baseIndex(
3033                 m_heaps.scopedArgumentsTableArguments, arguments, m_out.zeroExtPtr(index));
3034             LValue scopeOffset = m_out.load32(address);
3035             
3036             speculate(
3037                 ExoticObjectMode, noValue(), nullptr,
3038                 m_out.equal(scopeOffset, m_out.constInt32(ScopeOffset::invalidOffset)));
3039             
3040             address = m_out.baseIndex(
3041                 m_heaps.JSEnvironmentRecord_variables, scope, m_out.zeroExtPtr(scopeOffset));
3042             ValueFromBlock namedResult = m_out.anchor(m_out.load64(address));
3043             m_out.jump(continuation);
3044             
3045             m_out.appendTo(overflowCase, continuation);
3046             
3047             address = m_out.baseIndex(
3048                 m_heaps.ScopedArguments_overflowStorage, base,
3049                 m_out.zeroExtPtr(m_out.sub(index, namedLength)));
3050             LValue overflowValue = m_out.load64(address);
3051             speculate(ExoticObjectMode, noValue(), nullptr, m_out.isZero64(overflowValue));
3052             ValueFromBlock overflowResult = m_out.anchor(overflowValue);
3053             m_out.jump(continuation);
3054             
3055             m_out.appendTo(continuation, lastNext);
3056             setJSValue(m_out.phi(Int64, namedResult, overflowResult));
3057             return;
3058         }
3059             
3060         case Array::Generic: {
3061             setJSValue(vmCall(
3062                 Int64, m_out.operation(operationGetByVal), m_callFrame,
3063                 lowJSValue(m_node->child1()), lowJSValue(m_node->child2())));
3064             return;
3065         }
3066             
3067         case Array::String: {
3068             compileStringCharAt();
3069             return;
3070         }
3071             
3072         default: {
3073             LValue index = lowInt32(m_node->child2());
3074             LValue storage = lowStorage(m_node->child3());
3075             
3076             TypedArrayType type = m_node->arrayMode().typedArrayType();
3077             
3078             if (isTypedView(type)) {
3079                 TypedPointer pointer = TypedPointer(
3080                     m_heaps.typedArrayProperties,
3081                     m_out.add(
3082                         storage,
3083                         m_out.shl(
3084                             m_out.zeroExtPtr(index),
3085                             m_out.constIntPtr(logElementSize(type)))));
3086                 
3087                 if (isInt(type)) {
3088                     LValue result;
3089                     switch (elementSize(type)) {
3090                     case 1:
3091                         result = isSigned(type) ? m_out.load8SignExt32(pointer) :  m_out.load8ZeroExt32(pointer);
3092                         break;
3093                     case 2:
3094                         result = isSigned(type) ? m_out.load16SignExt32(pointer) :  m_out.load16ZeroExt32(pointer);
3095                         break;
3096                     case 4:
3097                         result = m_out.load32(pointer);
3098                         break;
3099                     default:
3100                         DFG_CRASH(m_graph, m_node, "Bad element size");
3101                     }
3102                     
3103                     if (elementSize(type) < 4 || isSigned(type)) {
3104                         setInt32(result);
3105                         return;
3106                     }
3107
3108                     if (m_node->shouldSpeculateInt32()) {
3109                         speculate(
3110                             Overflow, noValue(), 0, m_out.lessThan(result, m_out.int32Zero));
3111                         setInt32(result);
3112                         return;
3113                     }
3114                     
3115                     if (m_node->shouldSpeculateAnyInt()) {
3116                         setStrictInt52(m_out.zeroExt(result, Int64));
3117                         return;
3118                     }
3119                     
3120                     setDouble(m_out.unsignedToDouble(result));
3121                     return;
3122                 }
3123             
3124                 ASSERT(isFloat(type));
3125                 
3126                 LValue result;
3127                 switch (type) {
3128                 case TypeFloat32:
3129                     result = m_out.floatToDouble(m_out.loadFloat(pointer));
3130                     break;
3131                 case TypeFloat64:
3132                     result = m_out.loadDouble(pointer);
3133                     break;
3134                 default:
3135                     DFG_CRASH(m_graph, m_node, "Bad typed array type");
3136                 }
3137                 
3138                 setDouble(result);
3139                 return;
3140             }
3141             
3142             DFG_CRASH(m_graph, m_node, "Bad array type");
3143             return;
3144         } }
3145     }
3146     
3147     void compileGetMyArgumentByVal()
3148     {
3149         InlineCallFrame* inlineCallFrame = m_node->child1()->origin.semantic.inlineCallFrame;
3150         
3151         LValue index = lowInt32(m_node->child2());
3152         
3153         LValue limit;
3154         if (inlineCallFrame && !inlineCallFrame->isVarargs())
3155             limit = m_out.constInt32(inlineCallFrame->arguments.size() - 1);
3156         else {
3157             VirtualRegister argumentCountRegister;
3158             if (!inlineCallFrame)
3159                 argumentCountRegister = VirtualRegister(CallFrameSlot::argumentCount);
3160             else
3161                 argumentCountRegister = inlineCallFrame->argumentCountRegister;
3162             limit = m_out.sub(m_out.load32(payloadFor(argumentCountRegister)), m_out.int32One);
3163         }
3164         
3165         LValue isOutOfBounds = m_out.aboveOrEqual(index, limit);
3166         LBasicBlock continuation = nullptr;
3167         LBasicBlock lastNext = nullptr;
3168         ValueFromBlock slowResult;
3169         if (m_node->op() == GetMyArgumentByValOutOfBounds) {
3170             LBasicBlock normalCase = m_out.newBlock();
3171             continuation = m_out.newBlock();
3172             
3173             slowResult = m_out.anchor(m_out.constInt64(JSValue::encode(jsUndefined())));
3174             m_out.branch(isOutOfBounds, unsure(continuation), unsure(normalCase));
3175             
3176             lastNext = m_out.appendTo(normalCase, continuation);
3177         } else
3178             speculate(ExoticObjectMode, noValue(), 0, isOutOfBounds);
3179         
3180         TypedPointer base;
3181         if (inlineCallFrame) {
3182             if (inlineCallFrame->arguments.size() > 1)
3183                 base = addressFor(inlineCallFrame->arguments[1].virtualRegister());
3184         } else
3185             base = addressFor(virtualRegisterForArgument(1));
3186         
3187         LValue result;
3188         if (base) {
3189             LValue pointer = m_out.baseIndex(
3190                 base.value(), m_out.zeroExt(index, pointerType()), ScaleEight);
3191             result = m_out.load64(TypedPointer(m_heaps.variables.atAnyIndex(), pointer));
3192         } else
3193             result = m_out.constInt64(JSValue::encode(jsUndefined()));
3194         
3195         if (m_node->op() == GetMyArgumentByValOutOfBounds) {
3196             ValueFromBlock normalResult = m_out.anchor(result);
3197             m_out.jump(continuation);
3198             
3199             m_out.appendTo(continuation, lastNext);
3200             result = m_out.phi(Int64, slowResult, normalResult);
3201         }
3202         
3203         setJSValue(result);
3204     }
3205     
3206     void compilePutByVal()
3207     {
3208         Edge child1 = m_graph.varArgChild(m_node, 0);
3209         Edge child2 = m_graph.varArgChild(m_node, 1);
3210         Edge child3 = m_graph.varArgChild(m_node, 2);
3211         Edge child4 = m_graph.varArgChild(m_node, 3);
3212         Edge child5 = m_graph.varArgChild(m_node, 4);
3213         
3214         switch (m_node->arrayMode().type()) {
3215         case Array::Generic: {
3216             V_JITOperation_EJJJ operation;
3217             if (m_node->op() == PutByValDirect) {
3218                 if (m_graph.isStrictModeFor(m_node->origin.semantic))
3219                     operation = operationPutByValDirectStrict;
3220                 else
3221                     operation = operationPutByValDirectNonStrict;
3222             } else {
3223                 if (m_graph.isStrictModeFor(m_node->origin.semantic))
3224                     operation = operationPutByValStrict;
3225                 else
3226                     operation = operationPutByValNonStrict;
3227             }
3228                 
3229             vmCall(
3230                 Void, m_out.operation(operation), m_callFrame,
3231                 lowJSValue(child1), lowJSValue(child2), lowJSValue(child3));
3232             return;
3233         }
3234             
3235         default:
3236             break;
3237         }
3238
3239         LValue base = lowCell(child1);
3240         LValue index = lowInt32(child2);
3241         LValue storage = lowStorage(child4);
3242         
3243         switch (m_node->arrayMode().type()) {
3244         case Array::Int32:
3245         case Array::Double:
3246         case Array::Contiguous: {
3247             LBasicBlock continuation = m_out.newBlock();
3248             LBasicBlock outerLastNext = m_out.appendTo(m_out.m_block, continuation);
3249             
3250             switch (m_node->arrayMode().type()) {
3251             case Array::Int32:
3252             case Array::Contiguous: {
3253                 LValue value = lowJSValue(child3, ManualOperandSpeculation);
3254                 
3255                 if (m_node->arrayMode().type() == Array::Int32)
3256                     FTL_TYPE_CHECK(jsValueValue(value), child3, SpecInt32Only, isNotInt32(value));
3257                 
3258                 TypedPointer elementPointer = m_out.baseIndex(
3259                     m_node->arrayMode().type() == Array::Int32 ?
3260                     m_heaps.indexedInt32Properties : m_heaps.indexedContiguousProperties,
3261                     storage, m_out.zeroExtPtr(index), provenValue(child2));
3262                 
3263                 if (m_node->op() == PutByValAlias) {
3264                     m_out.store64(value, elementPointer);
3265                     break;
3266                 }
3267                 
3268                 contiguousPutByValOutOfBounds(
3269                     codeBlock()->isStrictMode()
3270                     ? operationPutByValBeyondArrayBoundsStrict
3271                     : operationPutByValBeyondArrayBoundsNonStrict,
3272                     base, storage, index, value, continuation);
3273                 
3274                 m_out.store64(value, elementPointer);
3275                 break;
3276             }
3277                 
3278             case Array::Double: {
3279                 LValue value = lowDouble(child3);
3280                 
3281                 FTL_TYPE_CHECK(
3282                     doubleValue(value), child3, SpecDoubleReal,
3283                     m_out.doubleNotEqualOrUnordered(value, value));
3284                 
3285                 TypedPointer elementPointer = m_out.baseIndex(
3286                     m_heaps.indexedDoubleProperties, storage, m_out.zeroExtPtr(index),
3287                     provenValue(child2));
3288                 
3289                 if (m_node->op() == PutByValAlias) {
3290                     m_out.storeDouble(value, elementPointer);
3291                     break;
3292                 }
3293                 
3294                 contiguousPutByValOutOfBounds(
3295                     codeBlock()->isStrictMode()
3296                     ? operationPutDoubleByValBeyondArrayBoundsStrict
3297                     : operationPutDoubleByValBeyondArrayBoundsNonStrict,
3298                     base, storage, index, value, continuation);
3299                 
3300                 m_out.storeDouble(value, elementPointer);
3301                 break;
3302             }
3303                 
3304             default:
3305                 DFG_CRASH(m_graph, m_node, "Bad array type");
3306             }
3307
3308             m_out.jump(continuation);
3309             m_out.appendTo(continuation, outerLastNext);
3310             return;
3311         }
3312             
3313         default:
3314             TypedArrayType type = m_node->arrayMode().typedArrayType();
3315             
3316             if (isTypedView(type)) {
3317                 TypedPointer pointer = TypedPointer(
3318                     m_heaps.typedArrayProperties,
3319                     m_out.add(
3320                         storage,
3321                         m_out.shl(
3322                             m_out.zeroExt(index, pointerType()),
3323                             m_out.constIntPtr(logElementSize(type)))));
3324                 
3325                 Output::StoreType storeType;
3326                 LValue valueToStore;
3327                 
3328                 if (isInt(type)) {
3329                     LValue intValue;
3330                     switch (child3.useKind()) {
3331                     case Int52RepUse:
3332                     case Int32Use: {
3333                         if (child3.useKind() == Int32Use)
3334                             intValue = lowInt32(child3);
3335                         else
3336                             intValue = m_out.castToInt32(lowStrictInt52(child3));
3337
3338                         if (isClamped(type)) {
3339                             ASSERT(elementSize(type) == 1);
3340                             
3341                             LBasicBlock atLeastZero = m_out.newBlock();
3342                             LBasicBlock continuation = m_out.newBlock();
3343                             
3344                             Vector<ValueFromBlock, 2> intValues;
3345                             intValues.append(m_out.anchor(m_out.int32Zero));
3346                             m_out.branch(
3347                                 m_out.lessThan(intValue, m_out.int32Zero),
3348                                 unsure(continuation), unsure(atLeastZero));
3349                             
3350                             LBasicBlock lastNext = m_out.appendTo(atLeastZero, continuation);
3351                             
3352                             intValues.append(m_out.anchor(m_out.select(
3353                                 m_out.greaterThan(intValue, m_out.constInt32(255)),
3354                                 m_out.constInt32(255),
3355                                 intValue)));
3356                             m_out.jump(continuation);
3357                             
3358                             m_out.appendTo(continuation, lastNext);
3359                             intValue = m_out.phi(Int32, intValues);
3360                         }
3361                         break;
3362                     }
3363                         
3364                     case DoubleRepUse: {
3365                         LValue doubleValue = lowDouble(child3);
3366                         
3367                         if (isClamped(type)) {
3368                             ASSERT(elementSize(type) == 1);
3369                             
3370                             LBasicBlock atLeastZero = m_out.newBlock();
3371                             LBasicBlock withinRange = m_out.newBlock();
3372                             LBasicBlock continuation = m_out.newBlock();
3373                             
3374                             Vector<ValueFromBlock, 3> intValues;
3375                             intValues.append(m_out.anchor(m_out.int32Zero));
3376                             m_out.branch(
3377                                 m_out.doubleLessThanOrUnordered(doubleValue, m_out.doubleZero),
3378                                 unsure(continuation), unsure(atLeastZero));
3379                             
3380                             LBasicBlock lastNext = m_out.appendTo(atLeastZero, withinRange);
3381                             intValues.append(m_out.anchor(m_out.constInt32(255)));
3382                             m_out.branch(
3383                                 m_out.doubleGreaterThan(doubleValue, m_out.constDouble(255)),
3384                                 unsure(continuation), unsure(withinRange));
3385                             
3386                             m_out.appendTo(withinRange, continuation);
3387                             intValues.append(m_out.anchor(m_out.doubleToInt(doubleValue)));
3388                             m_out.jump(continuation);
3389                             
3390                             m_out.appendTo(continuation, lastNext);
3391                             intValue = m_out.phi(Int32, intValues);
3392                         } else
3393                             intValue = doubleToInt32(doubleValue);
3394                         break;
3395                     }
3396                         
3397                     default:
3398                         DFG_CRASH(m_graph, m_node, "Bad use kind");
3399                     }
3400
3401                     valueToStore = intValue;
3402                     switch (elementSize(type)) {
3403                     case 1:
3404                         storeType = Output::Store32As8;
3405                         break;
3406                     case 2:
3407                         storeType = Output::Store32As16;
3408                         break;
3409                     case 4:
3410                         storeType = Output::Store32;
3411                         break;
3412                     default:
3413                         DFG_CRASH(m_graph, m_node, "Bad element size");
3414                     }
3415                 } else /* !isInt(type) */ {
3416                     LValue value = lowDouble(child3);
3417                     switch (type) {
3418                     case TypeFloat32:
3419                         valueToStore = m_out.doubleToFloat(value);
3420                         storeType = Output::StoreFloat;
3421                         break;
3422                     case TypeFloat64:
3423                         valueToStore = value;
3424                         storeType = Output::StoreDouble;
3425                         break;
3426                     default:
3427                         DFG_CRASH(m_graph, m_node, "Bad typed array type");
3428                     }
3429                 }
3430
3431                 if (m_node->arrayMode().isInBounds() || m_node->op() == PutByValAlias)
3432                     m_out.store(valueToStore, pointer, storeType);
3433                 else {
3434                     LBasicBlock isInBounds = m_out.newBlock();
3435                     LBasicBlock isOutOfBounds = m_out.newBlock();
3436                     LBasicBlock continuation = m_out.newBlock();
3437                     
3438                     m_out.branch(
3439                         m_out.aboveOrEqual(index, lowInt32(child5)),
3440                         unsure(isOutOfBounds), unsure(isInBounds));
3441                     
3442                     LBasicBlock lastNext = m_out.appendTo(isInBounds, isOutOfBounds);
3443                     m_out.store(valueToStore, pointer, storeType);
3444                     m_out.jump(continuation);
3445
3446                     m_out.appendTo(isOutOfBounds, continuation);
3447                     speculateTypedArrayIsNotNeutered(base);
3448                     m_out.jump(continuation);
3449                     
3450                     m_out.appendTo(continuation, lastNext);
3451                 }
3452                 
3453                 return;
3454             }
3455
3456             DFG_CRASH(m_graph, m_node, "Bad array type");
3457             break;
3458         }
3459     }
3460
3461     void compilePutAccessorById()
3462     {
3463         LValue base = lowCell(m_node->child1());
3464         LValue accessor = lowCell(m_node->child2());
3465         auto uid = m_graph.identifiers()[m_node->identifierNumber()];
3466         vmCall(
3467             Void,
3468             m_out.operation(m_node->op() == PutGetterById ? operationPutGetterById : operationPutSetterById),
3469             m_callFrame, base, m_out.constIntPtr(uid), m_out.constInt32(m_node->accessorAttributes()), accessor);
3470     }
3471
3472     void compilePutGetterSetterById()
3473     {
3474         LValue base = lowCell(m_node->child1());
3475         LValue getter = lowJSValue(m_node->child2());
3476         LValue setter = lowJSValue(m_node->child3());
3477         auto uid = m_graph.identifiers()[m_node->identifierNumber()];
3478         vmCall(
3479             Void, m_out.operation(operationPutGetterSetter),
3480             m_callFrame, base, m_out.constIntPtr(uid), m_out.constInt32(m_node->accessorAttributes()), getter, setter);
3481
3482     }
3483
3484     void compilePutAccessorByVal()
3485     {
3486         LValue base = lowCell(m_node->child1());
3487         LValue subscript = lowJSValue(m_node->child2());
3488         LValue accessor = lowCell(m_node->child3());
3489         vmCall(
3490             Void,
3491             m_out.operation(m_node->op() == PutGetterByVal ? operationPutGetterByVal : operationPutSetterByVal),
3492             m_callFrame, base, subscript, m_out.constInt32(m_node->accessorAttributes()), accessor);
3493     }
3494     
3495     void compileArrayPush()
3496     {
3497         LValue base = lowCell(m_node->child1());
3498         LValue storage = lowStorage(m_node->child3());
3499         
3500         switch (m_node->arrayMode().type()) {
3501         case Array::Int32:
3502         case Array::Contiguous:
3503         case Array::Double: {
3504             LValue value;
3505             Output::StoreType storeType;
3506             
3507             if (m_node->arrayMode().type() != Array::Double) {
3508                 value = lowJSValue(m_node->child2(), ManualOperandSpeculation);
3509                 if (m_node->arrayMode().type() == Array::Int32) {
3510                     FTL_TYPE_CHECK(
3511                         jsValueValue(value), m_node->child2(), SpecInt32Only, isNotInt32(value));
3512                 }
3513                 storeType = Output::Store64;
3514             } else {
3515                 value = lowDouble(m_node->child2());
3516                 FTL_TYPE_CHECK(
3517                     doubleValue(value), m_node->child2(), SpecDoubleReal,
3518                     m_out.doubleNotEqualOrUnordered(value, value));
3519                 storeType = Output::StoreDouble;
3520             }
3521             
3522             IndexedAbstractHeap& heap = m_heaps.forArrayType(m_node->arrayMode().type());
3523
3524             LValue prevLength = m_out.load32(storage, m_heaps.Butterfly_publicLength);
3525             
3526             LBasicBlock fastPath = m_out.newBlock();
3527             LBasicBlock slowPath = m_out.newBlock();
3528             LBasicBlock continuation = m_out.newBlock();
3529             
3530             m_out.branch(
3531                 m_out.aboveOrEqual(
3532                     prevLength, m_out.load32(storage, m_heaps.Butterfly_vectorLength)),
3533                 unsure(slowPath), unsure(fastPath));
3534             
3535             LBasicBlock lastNext = m_out.appendTo(fastPath, slowPath);
3536             m_out.store(
3537                 value, m_out.baseIndex(heap, storage, m_out.zeroExtPtr(prevLength)), storeType);
3538             LValue newLength = m_out.add(prevLength, m_out.int32One);
3539             m_out.store32(newLength, storage, m_heaps.Butterfly_publicLength);
3540             
3541             ValueFromBlock fastResult = m_out.anchor(boxInt32(newLength));
3542             m_out.jump(continuation);
3543             
3544             m_out.appendTo(slowPath, continuation);
3545             LValue operation;
3546             if (m_node->arrayMode().type() != Array::Double)
3547                 operation = m_out.operation(operationArrayPush);
3548             else
3549                 operation = m_out.operation(operationArrayPushDouble);
3550             ValueFromBlock slowResult = m_out.anchor(
3551                 vmCall(Int64, operation, m_callFrame, value, base));
3552             m_out.jump(continuation);
3553             
3554             m_out.appendTo(continuation, lastNext);
3555             setJSValue(m_out.phi(Int64, fastResult, slowResult));
3556             return;
3557         }
3558             
3559         default:
3560             DFG_CRASH(m_graph, m_node, "Bad array type");
3561             return;
3562         }
3563     }
3564     
3565     void compileArrayPop()
3566     {
3567         LValue base = lowCell(m_node->child1());
3568         LValue storage = lowStorage(m_node->child2());
3569         
3570         switch (m_node->arrayMode().type()) {
3571         case Array::Int32:
3572         case Array::Double:
3573         case Array::Contiguous: {
3574             IndexedAbstractHeap& heap = m_heaps.forArrayType(m_node->arrayMode().type());
3575             
3576             LBasicBlock fastCase = m_out.newBlock();
3577             LBasicBlock slowCase = m_out.newBlock();
3578             LBasicBlock continuation = m_out.newBlock();
3579             
3580             LValue prevLength = m_out.load32(storage, m_heaps.Butterfly_publicLength);
3581             
3582  &n