Unreviewed, rolling out r202413.
[WebKit.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 "B3StackmapGenerationParams.h"
34 #include "CallFrameShuffler.h"
35 #include "CodeBlockWithJITType.h"
36 #include "DFGAbstractInterpreterInlines.h"
37 #include "DFGDominators.h"
38 #include "DFGInPlaceAbstractState.h"
39 #include "DFGOSRAvailabilityAnalysisPhase.h"
40 #include "DFGOSRExitFuzz.h"
41 #include "DirectArguments.h"
42 #include "FTLAbstractHeapRepository.h"
43 #include "FTLAvailableRecovery.h"
44 #include "FTLExceptionTarget.h"
45 #include "FTLForOSREntryJITCode.h"
46 #include "FTLFormattedValue.h"
47 #include "FTLLazySlowPathCall.h"
48 #include "FTLLoweredNodeValue.h"
49 #include "FTLOperations.h"
50 #include "FTLOutput.h"
51 #include "FTLPatchpointExceptionHandle.h"
52 #include "FTLThunks.h"
53 #include "FTLWeightedTarget.h"
54 #include "JITAddGenerator.h"
55 #include "JITBitAndGenerator.h"
56 #include "JITBitOrGenerator.h"
57 #include "JITBitXorGenerator.h"
58 #include "JITDivGenerator.h"
59 #include "JITInlineCacheGenerator.h"
60 #include "JITLeftShiftGenerator.h"
61 #include "JITMulGenerator.h"
62 #include "JITRightShiftGenerator.h"
63 #include "JITSubGenerator.h"
64 #include "JSCInlines.h"
65 #include "JSGeneratorFunction.h"
66 #include "JSLexicalEnvironment.h"
67 #include "OperandsInlines.h"
68 #include "ScopedArguments.h"
69 #include "ScopedArgumentsTable.h"
70 #include "ScratchRegisterAllocator.h"
71 #include "SetupVarargsFrame.h"
72 #include "ShadowChicken.h"
73 #include "StructureStubInfo.h"
74 #include "VirtualRegister.h"
75 #include "Watchdog.h"
76 #include <atomic>
77 #if !OS(WINDOWS)
78 #include <dlfcn.h>
79 #endif
80 #include <unordered_set>
81 #include <wtf/Box.h>
82 #include <wtf/ProcessID.h>
83
84 namespace JSC { namespace FTL {
85
86 using namespace B3;
87 using namespace DFG;
88
89 namespace {
90
91 std::atomic<int> compileCounter;
92
93 #if ASSERT_DISABLED
94 NO_RETURN_DUE_TO_CRASH static void ftlUnreachable()
95 {
96     CRASH();
97 }
98 #else
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(JSStack::CodeBlock));
194
195         // Stack Overflow Check.
196         unsigned exitFrameSize = m_graph.requiredRegisterCountForExit() * sizeof(Register);
197         MacroAssembler::AbsoluteAddress addressOfStackLimit(vm().addressOfStackLimit());
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(JSStack::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 = m_out.doubleType;
337                     break;
338                 case NodeResultInt32:
339                     type = m_out.int32;
340                     break;
341                 case NodeResultInt52:
342                     type = m_out.int64;
343                     break;
344                 case NodeResultBoolean:
345                     type = m_out.boolean;
346                     break;
347                 case NodeResultJS:
348                     type = m_out.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->index, UINT_MAX);
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 ToString:
732         case CallStringConstructor:
733             compileToStringOrCallStringConstructor();
734             break;
735         case ToPrimitive:
736             compileToPrimitive();
737             break;
738         case MakeRope:
739             compileMakeRope();
740             break;
741         case StringCharAt:
742             compileStringCharAt();
743             break;
744         case StringCharCodeAt:
745             compileStringCharCodeAt();
746             break;
747         case StringFromCharCode:
748             compileStringFromCharCode();
749             break;
750         case GetByOffset:
751         case GetGetterSetterByOffset:
752             compileGetByOffset();
753             break;
754         case GetGetter:
755             compileGetGetter();
756             break;
757         case GetSetter:
758             compileGetSetter();
759             break;
760         case MultiGetByOffset:
761             compileMultiGetByOffset();
762             break;
763         case PutByOffset:
764             compilePutByOffset();
765             break;
766         case MultiPutByOffset:
767             compileMultiPutByOffset();
768             break;
769         case GetGlobalVar:
770         case GetGlobalLexicalVariable:
771             compileGetGlobalVariable();
772             break;
773         case PutGlobalVariable:
774             compilePutGlobalVariable();
775             break;
776         case NotifyWrite:
777             compileNotifyWrite();
778             break;
779         case GetCallee:
780             compileGetCallee();
781             break;
782         case GetArgumentCountIncludingThis:
783             compileGetArgumentCountIncludingThis();
784             break;
785         case GetScope:
786             compileGetScope();
787             break;
788         case SkipScope:
789             compileSkipScope();
790             break;
791         case GetGlobalObject:
792             compileGetGlobalObject();
793             break;
794         case GetClosureVar:
795             compileGetClosureVar();
796             break;
797         case PutClosureVar:
798             compilePutClosureVar();
799             break;
800         case GetFromArguments:
801             compileGetFromArguments();
802             break;
803         case PutToArguments:
804             compilePutToArguments();
805             break;
806         case CompareEq:
807             compileCompareEq();
808             break;
809         case CompareStrictEq:
810             compileCompareStrictEq();
811             break;
812         case CompareLess:
813             compileCompareLess();
814             break;
815         case CompareLessEq:
816             compileCompareLessEq();
817             break;
818         case CompareGreater:
819             compileCompareGreater();
820             break;
821         case CompareGreaterEq:
822             compileCompareGreaterEq();
823             break;
824         case LogicalNot:
825             compileLogicalNot();
826             break;
827         case Call:
828         case TailCallInlinedCaller:
829         case Construct:
830             compileCallOrConstruct();
831             break;
832         case TailCall:
833             compileTailCall();
834             break;
835         case CallVarargs:
836         case CallForwardVarargs:
837         case TailCallVarargs:
838         case TailCallVarargsInlinedCaller:
839         case TailCallForwardVarargs:
840         case TailCallForwardVarargsInlinedCaller:
841         case ConstructVarargs:
842         case ConstructForwardVarargs:
843             compileCallOrConstructVarargs();
844             break;
845         case LoadVarargs:
846             compileLoadVarargs();
847             break;
848         case ForwardVarargs:
849             compileForwardVarargs();
850             break;
851         case DFG::Jump:
852             compileJump();
853             break;
854         case DFG::Branch:
855             compileBranch();
856             break;
857         case DFG::Switch:
858             compileSwitch();
859             break;
860         case DFG::Return:
861             compileReturn();
862             break;
863         case ForceOSRExit:
864             compileForceOSRExit();
865             break;
866         case Throw:
867         case ThrowReferenceError:
868             compileThrow();
869             break;
870         case InvalidationPoint:
871             compileInvalidationPoint();
872             break;
873         case IsEmpty:
874             compileIsEmpty();
875             break;
876         case IsUndefined:
877             compileIsUndefined();
878             break;
879         case IsBoolean:
880             compileIsBoolean();
881             break;
882         case IsNumber:
883             compileIsNumber();
884             break;
885         case IsString:
886             compileIsString();
887             break;
888         case IsJSArray:
889             compileIsJSArray();
890             break;
891         case IsObject:
892             compileIsObject();
893             break;
894         case IsObjectOrNull:
895             compileIsObjectOrNull();
896             break;
897         case IsFunction:
898             compileIsFunction();
899             break;
900         case IsRegExpObject:
901             compileIsRegExpObject();
902             break;
903         case IsTypedArrayView:
904             compileIsTypedArrayView();
905             break;
906         case TypeOf:
907             compileTypeOf();
908             break;
909         case CheckTypeInfoFlags:
910             compileCheckTypeInfoFlags();
911             break;
912         case OverridesHasInstance:
913             compileOverridesHasInstance();
914             break;
915         case InstanceOf:
916             compileInstanceOf();
917             break;
918         case InstanceOfCustom:
919             compileInstanceOfCustom();
920             break;
921         case CountExecution:
922             compileCountExecution();
923             break;
924         case StoreBarrier:
925             compileStoreBarrier();
926             break;
927         case HasIndexedProperty:
928             compileHasIndexedProperty();
929             break;
930         case HasGenericProperty:
931             compileHasGenericProperty();
932             break;
933         case HasStructureProperty:
934             compileHasStructureProperty();
935             break;
936         case GetDirectPname:
937             compileGetDirectPname();
938             break;
939         case GetEnumerableLength:
940             compileGetEnumerableLength();
941             break;
942         case GetPropertyEnumerator:
943             compileGetPropertyEnumerator();
944             break;
945         case GetEnumeratorStructurePname:
946             compileGetEnumeratorStructurePname();
947             break;
948         case GetEnumeratorGenericPname:
949             compileGetEnumeratorGenericPname();
950             break;
951         case ToIndexString:
952             compileToIndexString();
953             break;
954         case CheckStructureImmediate:
955             compileCheckStructureImmediate();
956             break;
957         case MaterializeNewObject:
958             compileMaterializeNewObject();
959             break;
960         case MaterializeCreateActivation:
961             compileMaterializeCreateActivation();
962             break;
963         case CheckWatchdogTimer:
964             compileCheckWatchdogTimer();
965             break;
966         case CopyRest:
967             compileCopyRest();
968             break;
969         case GetRestLength:
970             compileGetRestLength();
971             break;
972         case RegExpExec:
973             compileRegExpExec();
974             break;
975         case RegExpTest:
976             compileRegExpTest();
977             break;
978         case NewRegexp:
979             compileNewRegexp();
980             break;
981         case SetFunctionName:
982             compileSetFunctionName();
983             break;
984         case StringReplace:
985         case StringReplaceRegExp:
986             compileStringReplace();
987             break;
988         case GetRegExpObjectLastIndex:
989             compileGetRegExpObjectLastIndex();
990             break;
991         case SetRegExpObjectLastIndex:
992             compileSetRegExpObjectLastIndex();
993             break;
994         case LogShadowChickenPrologue:
995             compileLogShadowChickenPrologue();
996             break;
997         case LogShadowChickenTail:
998             compileLogShadowChickenTail();
999             break;
1000         case RecordRegExpCachedResult:
1001             compileRecordRegExpCachedResult();
1002             break;
1003         case ResolveScope:
1004             compileResolveScope();
1005             break;
1006         case GetDynamicVar:
1007             compileGetDynamicVar();
1008             break;
1009         case PutDynamicVar:
1010             compilePutDynamicVar();
1011             break;
1012         case Unreachable:
1013             compileUnreachable();
1014             break;
1015
1016         case PhantomLocal:
1017         case LoopHint:
1018         case MovHint:
1019         case ZombieHint:
1020         case ExitOK:
1021         case PhantomNewObject:
1022         case PhantomNewFunction:
1023         case PhantomNewGeneratorFunction:
1024         case PhantomCreateActivation:
1025         case PhantomDirectArguments:
1026         case PhantomClonedArguments:
1027         case PutHint:
1028         case BottomValue:
1029         case KillStack:
1030             break;
1031         default:
1032             DFG_CRASH(m_graph, m_node, "Unrecognized node in FTL backend");
1033             break;
1034         }
1035         
1036         if (m_node->isTerminal())
1037             return false;
1038         
1039         if (!m_state.isValid()) {
1040             safelyInvalidateAfterTermination();
1041             return false;
1042         }
1043
1044         m_availabilityCalculator.executeNode(m_node);
1045         m_interpreter.executeEffects(nodeIndex);
1046         
1047         return true;
1048     }
1049
1050     void compileUpsilon()
1051     {
1052         LValue upsilonValue = nullptr;
1053         switch (m_node->child1().useKind()) {
1054         case DoubleRepUse:
1055             upsilonValue = lowDouble(m_node->child1());
1056             break;
1057         case Int32Use:
1058         case KnownInt32Use:
1059             upsilonValue = lowInt32(m_node->child1());
1060             break;
1061         case Int52RepUse:
1062             upsilonValue = lowInt52(m_node->child1());
1063             break;
1064         case BooleanUse:
1065         case KnownBooleanUse:
1066             upsilonValue = lowBoolean(m_node->child1());
1067             break;
1068         case CellUse:
1069         case KnownCellUse:
1070             upsilonValue = lowCell(m_node->child1());
1071             break;
1072         case UntypedUse:
1073             upsilonValue = lowJSValue(m_node->child1());
1074             break;
1075         default:
1076             DFG_CRASH(m_graph, m_node, "Bad use kind");
1077             break;
1078         }
1079         ValueFromBlock upsilon = m_out.anchor(upsilonValue);
1080         LValue phiNode = m_phis.get(m_node->phi());
1081         m_out.addIncomingToPhi(phiNode, upsilon);
1082     }
1083     
1084     void compilePhi()
1085     {
1086         LValue phi = m_phis.get(m_node);
1087         m_out.m_block->append(phi);
1088
1089         switch (m_node->flags() & NodeResultMask) {
1090         case NodeResultDouble:
1091             setDouble(phi);
1092             break;
1093         case NodeResultInt32:
1094             setInt32(phi);
1095             break;
1096         case NodeResultInt52:
1097             setInt52(phi);
1098             break;
1099         case NodeResultBoolean:
1100             setBoolean(phi);
1101             break;
1102         case NodeResultJS:
1103             setJSValue(phi);
1104             break;
1105         default:
1106             DFG_CRASH(m_graph, m_node, "Bad use kind");
1107             break;
1108         }
1109     }
1110     
1111     void compileDoubleConstant()
1112     {
1113         setDouble(m_out.constDouble(m_node->asNumber()));
1114     }
1115     
1116     void compileInt52Constant()
1117     {
1118         int64_t value = m_node->asAnyInt();
1119         
1120         setInt52(m_out.constInt64(value << JSValue::int52ShiftAmount));
1121         setStrictInt52(m_out.constInt64(value));
1122     }
1123
1124     void compileLazyJSConstant()
1125     {
1126         PatchpointValue* patchpoint = m_out.patchpoint(Int64);
1127         LazyJSValue value = m_node->lazyJSValue();
1128         patchpoint->setGenerator(
1129             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
1130                 value.emit(jit, JSValueRegs(params[0].gpr()));
1131             });
1132         patchpoint->effects = Effects::none();
1133         setJSValue(patchpoint);
1134     }
1135
1136     void compileDoubleRep()
1137     {
1138         switch (m_node->child1().useKind()) {
1139         case RealNumberUse: {
1140             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
1141             
1142             LValue doubleValue = unboxDouble(value);
1143             
1144             LBasicBlock intCase = m_out.newBlock();
1145             LBasicBlock continuation = m_out.newBlock();
1146             
1147             ValueFromBlock fastResult = m_out.anchor(doubleValue);
1148             m_out.branch(
1149                 m_out.doubleEqual(doubleValue, doubleValue),
1150                 usually(continuation), rarely(intCase));
1151             
1152             LBasicBlock lastNext = m_out.appendTo(intCase, continuation);
1153
1154             FTL_TYPE_CHECK(
1155                 jsValueValue(value), m_node->child1(), SpecBytecodeRealNumber,
1156                 isNotInt32(value, provenType(m_node->child1()) & ~SpecDoubleReal));
1157             ValueFromBlock slowResult = m_out.anchor(m_out.intToDouble(unboxInt32(value)));
1158             m_out.jump(continuation);
1159             
1160             m_out.appendTo(continuation, lastNext);
1161             
1162             setDouble(m_out.phi(m_out.doubleType, fastResult, slowResult));
1163             return;
1164         }
1165             
1166         case NotCellUse:
1167         case NumberUse: {
1168             bool shouldConvertNonNumber = m_node->child1().useKind() == NotCellUse;
1169             
1170             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
1171
1172             LBasicBlock intCase = m_out.newBlock();
1173             LBasicBlock doubleTesting = m_out.newBlock();
1174             LBasicBlock doubleCase = m_out.newBlock();
1175             LBasicBlock nonDoubleCase = m_out.newBlock();
1176             LBasicBlock continuation = m_out.newBlock();
1177             
1178             m_out.branch(
1179                 isNotInt32(value, provenType(m_node->child1())),
1180                 unsure(doubleTesting), unsure(intCase));
1181             
1182             LBasicBlock lastNext = m_out.appendTo(intCase, doubleTesting);
1183             
1184             ValueFromBlock intToDouble = m_out.anchor(
1185                 m_out.intToDouble(unboxInt32(value)));
1186             m_out.jump(continuation);
1187             
1188             m_out.appendTo(doubleTesting, doubleCase);
1189             LValue valueIsNumber = isNumber(value, provenType(m_node->child1()));
1190             m_out.branch(valueIsNumber, usually(doubleCase), rarely(nonDoubleCase));
1191
1192             m_out.appendTo(doubleCase, nonDoubleCase);
1193             ValueFromBlock unboxedDouble = m_out.anchor(unboxDouble(value));
1194             m_out.jump(continuation);
1195
1196             if (shouldConvertNonNumber) {
1197                 LBasicBlock undefinedCase = m_out.newBlock();
1198                 LBasicBlock testNullCase = m_out.newBlock();
1199                 LBasicBlock nullCase = m_out.newBlock();
1200                 LBasicBlock testBooleanTrueCase = m_out.newBlock();
1201                 LBasicBlock convertBooleanTrueCase = m_out.newBlock();
1202                 LBasicBlock convertBooleanFalseCase = m_out.newBlock();
1203
1204                 m_out.appendTo(nonDoubleCase, undefinedCase);
1205                 LValue valueIsUndefined = m_out.equal(value, m_out.constInt64(ValueUndefined));
1206                 m_out.branch(valueIsUndefined, unsure(undefinedCase), unsure(testNullCase));
1207
1208                 m_out.appendTo(undefinedCase, testNullCase);
1209                 ValueFromBlock convertedUndefined = m_out.anchor(m_out.constDouble(PNaN));
1210                 m_out.jump(continuation);
1211
1212                 m_out.appendTo(testNullCase, nullCase);
1213                 LValue valueIsNull = m_out.equal(value, m_out.constInt64(ValueNull));
1214                 m_out.branch(valueIsNull, unsure(nullCase), unsure(testBooleanTrueCase));
1215
1216                 m_out.appendTo(nullCase, testBooleanTrueCase);
1217                 ValueFromBlock convertedNull = m_out.anchor(m_out.constDouble(0));
1218                 m_out.jump(continuation);
1219
1220                 m_out.appendTo(testBooleanTrueCase, convertBooleanTrueCase);
1221                 LValue valueIsBooleanTrue = m_out.equal(value, m_out.constInt64(ValueTrue));
1222                 m_out.branch(valueIsBooleanTrue, unsure(convertBooleanTrueCase), unsure(convertBooleanFalseCase));
1223
1224                 m_out.appendTo(convertBooleanTrueCase, convertBooleanFalseCase);
1225                 ValueFromBlock convertedTrue = m_out.anchor(m_out.constDouble(1));
1226                 m_out.jump(continuation);
1227
1228                 m_out.appendTo(convertBooleanFalseCase, continuation);
1229
1230                 LValue valueIsNotBooleanFalse = m_out.notEqual(value, m_out.constInt64(ValueFalse));
1231                 FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), ~SpecCell, valueIsNotBooleanFalse);
1232                 ValueFromBlock convertedFalse = m_out.anchor(m_out.constDouble(0));
1233                 m_out.jump(continuation);
1234
1235                 m_out.appendTo(continuation, lastNext);
1236                 setDouble(m_out.phi(m_out.doubleType, intToDouble, unboxedDouble, convertedUndefined, convertedNull, convertedTrue, convertedFalse));
1237                 return;
1238             }
1239             m_out.appendTo(nonDoubleCase, continuation);
1240             FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), SpecBytecodeNumber, m_out.booleanTrue);
1241             m_out.unreachable();
1242
1243             m_out.appendTo(continuation, lastNext);
1244
1245             setDouble(m_out.phi(m_out.doubleType, intToDouble, unboxedDouble));
1246             return;
1247         }
1248             
1249         case Int52RepUse: {
1250             setDouble(strictInt52ToDouble(lowStrictInt52(m_node->child1())));
1251             return;
1252         }
1253             
1254         default:
1255             DFG_CRASH(m_graph, m_node, "Bad use kind");
1256         }
1257     }
1258
1259     void compileDoubleAsInt32()
1260     {
1261         LValue integerValue = convertDoubleToInt32(lowDouble(m_node->child1()), shouldCheckNegativeZero(m_node->arithMode()));
1262         setInt32(integerValue);
1263     }
1264
1265     void compileValueRep()
1266     {
1267         switch (m_node->child1().useKind()) {
1268         case DoubleRepUse: {
1269             LValue value = lowDouble(m_node->child1());
1270             
1271             if (m_interpreter.needsTypeCheck(m_node->child1(), ~SpecDoubleImpureNaN)) {
1272                 value = m_out.select(
1273                     m_out.doubleEqual(value, value), value, m_out.constDouble(PNaN));
1274             }
1275             
1276             setJSValue(boxDouble(value));
1277             return;
1278         }
1279             
1280         case Int52RepUse: {
1281             setJSValue(strictInt52ToJSValue(lowStrictInt52(m_node->child1())));
1282             return;
1283         }
1284             
1285         default:
1286             DFG_CRASH(m_graph, m_node, "Bad use kind");
1287         }
1288     }
1289     
1290     void compileInt52Rep()
1291     {
1292         switch (m_node->child1().useKind()) {
1293         case Int32Use:
1294             setStrictInt52(m_out.signExt32To64(lowInt32(m_node->child1())));
1295             return;
1296             
1297         case AnyIntUse:
1298             setStrictInt52(
1299                 jsValueToStrictInt52(
1300                     m_node->child1(), lowJSValue(m_node->child1(), ManualOperandSpeculation)));
1301             return;
1302             
1303         case DoubleRepAnyIntUse:
1304             setStrictInt52(
1305                 doubleToStrictInt52(
1306                     m_node->child1(), lowDouble(m_node->child1())));
1307             return;
1308             
1309         default:
1310             RELEASE_ASSERT_NOT_REACHED();
1311         }
1312     }
1313     
1314     void compileValueToInt32()
1315     {
1316         switch (m_node->child1().useKind()) {
1317         case Int52RepUse:
1318             setInt32(m_out.castToInt32(lowStrictInt52(m_node->child1())));
1319             break;
1320             
1321         case DoubleRepUse:
1322             setInt32(doubleToInt32(lowDouble(m_node->child1())));
1323             break;
1324             
1325         case NumberUse:
1326         case NotCellUse: {
1327             LoweredNodeValue value = m_int32Values.get(m_node->child1().node());
1328             if (isValid(value)) {
1329                 setInt32(value.value());
1330                 break;
1331             }
1332             
1333             value = m_jsValueValues.get(m_node->child1().node());
1334             if (isValid(value)) {
1335                 setInt32(numberOrNotCellToInt32(m_node->child1(), value.value()));
1336                 break;
1337             }
1338             
1339             // We'll basically just get here for constants. But it's good to have this
1340             // catch-all since we often add new representations into the mix.
1341             setInt32(
1342                 numberOrNotCellToInt32(
1343                     m_node->child1(),
1344                     lowJSValue(m_node->child1(), ManualOperandSpeculation)));
1345             break;
1346         }
1347             
1348         default:
1349             DFG_CRASH(m_graph, m_node, "Bad use kind");
1350             break;
1351         }
1352     }
1353     
1354     void compileBooleanToNumber()
1355     {
1356         switch (m_node->child1().useKind()) {
1357         case BooleanUse: {
1358             setInt32(m_out.zeroExt(lowBoolean(m_node->child1()), m_out.int32));
1359             return;
1360         }
1361             
1362         case UntypedUse: {
1363             LValue value = lowJSValue(m_node->child1());
1364             
1365             if (!m_interpreter.needsTypeCheck(m_node->child1(), SpecBoolInt32 | SpecBoolean)) {
1366                 setInt32(m_out.bitAnd(m_out.castToInt32(value), m_out.int32One));
1367                 return;
1368             }
1369             
1370             LBasicBlock booleanCase = m_out.newBlock();
1371             LBasicBlock continuation = m_out.newBlock();
1372             
1373             ValueFromBlock notBooleanResult = m_out.anchor(value);
1374             m_out.branch(
1375                 isBoolean(value, provenType(m_node->child1())),
1376                 unsure(booleanCase), unsure(continuation));
1377             
1378             LBasicBlock lastNext = m_out.appendTo(booleanCase, continuation);
1379             ValueFromBlock booleanResult = m_out.anchor(m_out.bitOr(
1380                 m_out.zeroExt(unboxBoolean(value), m_out.int64), m_tagTypeNumber));
1381             m_out.jump(continuation);
1382             
1383             m_out.appendTo(continuation, lastNext);
1384             setJSValue(m_out.phi(m_out.int64, booleanResult, notBooleanResult));
1385             return;
1386         }
1387             
1388         default:
1389             RELEASE_ASSERT_NOT_REACHED();
1390             return;
1391         }
1392     }
1393
1394     void compileExtractOSREntryLocal()
1395     {
1396         EncodedJSValue* buffer = static_cast<EncodedJSValue*>(
1397             m_ftlState.jitCode->ftlForOSREntry()->entryBuffer()->dataBuffer());
1398         setJSValue(m_out.load64(m_out.absolute(buffer + m_node->unlinkedLocal().toLocal())));
1399     }
1400     
1401     void compileGetStack()
1402     {
1403         // GetLocals arise only for captured variables and arguments. For arguments, we might have
1404         // already loaded it.
1405         if (LValue value = m_loadedArgumentValues.get(m_node)) {
1406             setJSValue(value);
1407             return;
1408         }
1409         
1410         StackAccessData* data = m_node->stackAccessData();
1411         AbstractValue& value = m_state.variables().operand(data->local);
1412         
1413         DFG_ASSERT(m_graph, m_node, isConcrete(data->format));
1414         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.
1415         
1416         if (isInt32Speculation(value.m_type))
1417             setInt32(m_out.load32(payloadFor(data->machineLocal)));
1418         else
1419             setJSValue(m_out.load64(addressFor(data->machineLocal)));
1420     }
1421     
1422     void compilePutStack()
1423     {
1424         StackAccessData* data = m_node->stackAccessData();
1425         switch (data->format) {
1426         case FlushedJSValue: {
1427             LValue value = lowJSValue(m_node->child1());
1428             m_out.store64(value, addressFor(data->machineLocal));
1429             break;
1430         }
1431             
1432         case FlushedDouble: {
1433             LValue value = lowDouble(m_node->child1());
1434             m_out.storeDouble(value, addressFor(data->machineLocal));
1435             break;
1436         }
1437             
1438         case FlushedInt32: {
1439             LValue value = lowInt32(m_node->child1());
1440             m_out.store32(value, payloadFor(data->machineLocal));
1441             break;
1442         }
1443             
1444         case FlushedInt52: {
1445             LValue value = lowInt52(m_node->child1());
1446             m_out.store64(value, addressFor(data->machineLocal));
1447             break;
1448         }
1449             
1450         case FlushedCell: {
1451             LValue value = lowCell(m_node->child1());
1452             m_out.store64(value, addressFor(data->machineLocal));
1453             break;
1454         }
1455             
1456         case FlushedBoolean: {
1457             speculateBoolean(m_node->child1());
1458             m_out.store64(
1459                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
1460                 addressFor(data->machineLocal));
1461             break;
1462         }
1463             
1464         default:
1465             DFG_CRASH(m_graph, m_node, "Bad flush format");
1466             break;
1467         }
1468     }
1469     
1470     void compileNoOp()
1471     {
1472         DFG_NODE_DO_TO_CHILDREN(m_graph, m_node, speculate);
1473     }
1474
1475     void compileCallObjectConstructor()
1476     {
1477         JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
1478         LValue value = lowJSValue(m_node->child1());
1479
1480         LBasicBlock isCellCase = m_out.newBlock();
1481         LBasicBlock slowCase = m_out.newBlock();
1482         LBasicBlock continuation = m_out.newBlock();
1483
1484         m_out.branch(isCell(value, provenType(m_node->child1())), usually(isCellCase), rarely(slowCase));
1485
1486         LBasicBlock lastNext = m_out.appendTo(isCellCase, slowCase);
1487         ValueFromBlock fastResult = m_out.anchor(value);
1488         m_out.branch(isObject(value), usually(continuation), rarely(slowCase));
1489
1490         m_out.appendTo(slowCase, continuation);
1491         ValueFromBlock slowResult = m_out.anchor(vmCall(m_out.int64, m_out.operation(operationObjectConstructor), m_callFrame, m_out.constIntPtr(globalObject), value));
1492         m_out.jump(continuation);
1493
1494         m_out.appendTo(continuation, lastNext);
1495         setJSValue(m_out.phi(m_out.int64, fastResult, slowResult));
1496     }
1497     
1498     void compileToThis()
1499     {
1500         LValue value = lowJSValue(m_node->child1());
1501         
1502         LBasicBlock isCellCase = m_out.newBlock();
1503         LBasicBlock slowCase = m_out.newBlock();
1504         LBasicBlock continuation = m_out.newBlock();
1505         
1506         m_out.branch(
1507             isCell(value, provenType(m_node->child1())), usually(isCellCase), rarely(slowCase));
1508         
1509         LBasicBlock lastNext = m_out.appendTo(isCellCase, slowCase);
1510         ValueFromBlock fastResult = m_out.anchor(value);
1511         m_out.branch(
1512             m_out.testIsZero32(
1513                 m_out.load8ZeroExt32(value, m_heaps.JSCell_typeInfoFlags),
1514                 m_out.constInt32(OverridesToThis)),
1515             usually(continuation), rarely(slowCase));
1516         
1517         m_out.appendTo(slowCase, continuation);
1518         J_JITOperation_EJ function;
1519         if (m_graph.isStrictModeFor(m_node->origin.semantic))
1520             function = operationToThisStrict;
1521         else
1522             function = operationToThis;
1523         ValueFromBlock slowResult = m_out.anchor(
1524             vmCall(m_out.int64, m_out.operation(function), m_callFrame, value));
1525         m_out.jump(continuation);
1526         
1527         m_out.appendTo(continuation, lastNext);
1528         setJSValue(m_out.phi(m_out.int64, fastResult, slowResult));
1529     }
1530     
1531     void compileValueAdd()
1532     {
1533         emitBinarySnippet<JITAddGenerator>(operationValueAdd);
1534     }
1535     
1536     void compileStrCat()
1537     {
1538         LValue result;
1539         if (m_node->child3()) {
1540             result = vmCall(
1541                 m_out.int64, m_out.operation(operationStrCat3), m_callFrame,
1542                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
1543                 lowJSValue(m_node->child2(), ManualOperandSpeculation),
1544                 lowJSValue(m_node->child3(), ManualOperandSpeculation));
1545         } else {
1546             result = vmCall(
1547                 m_out.int64, m_out.operation(operationStrCat2), m_callFrame,
1548                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
1549                 lowJSValue(m_node->child2(), ManualOperandSpeculation));
1550         }
1551         setJSValue(result);
1552     }
1553     
1554     void compileArithAddOrSub()
1555     {
1556         bool isSub =  m_node->op() == ArithSub;
1557         switch (m_node->binaryUseKind()) {
1558         case Int32Use: {
1559             LValue left = lowInt32(m_node->child1());
1560             LValue right = lowInt32(m_node->child2());
1561
1562             if (!shouldCheckOverflow(m_node->arithMode())) {
1563                 setInt32(isSub ? m_out.sub(left, right) : m_out.add(left, right));
1564                 break;
1565             }
1566
1567             CheckValue* result =
1568                 isSub ? m_out.speculateSub(left, right) : m_out.speculateAdd(left, right);
1569             blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);
1570             setInt32(result);
1571             break;
1572         }
1573             
1574         case Int52RepUse: {
1575             if (!abstractValue(m_node->child1()).couldBeType(SpecInt52Only)
1576                 && !abstractValue(m_node->child2()).couldBeType(SpecInt52Only)) {
1577                 Int52Kind kind;
1578                 LValue left = lowWhicheverInt52(m_node->child1(), kind);
1579                 LValue right = lowInt52(m_node->child2(), kind);
1580                 setInt52(isSub ? m_out.sub(left, right) : m_out.add(left, right), kind);
1581                 break;
1582             }
1583
1584             LValue left = lowInt52(m_node->child1());
1585             LValue right = lowInt52(m_node->child2());
1586             CheckValue* result =
1587                 isSub ? m_out.speculateSub(left, right) : m_out.speculateAdd(left, right);
1588             blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);
1589             setInt52(result);
1590             break;
1591         }
1592             
1593         case DoubleRepUse: {
1594             LValue C1 = lowDouble(m_node->child1());
1595             LValue C2 = lowDouble(m_node->child2());
1596
1597             setDouble(isSub ? m_out.doubleSub(C1, C2) : m_out.doubleAdd(C1, C2));
1598             break;
1599         }
1600
1601         case UntypedUse: {
1602             if (!isSub) {
1603                 DFG_CRASH(m_graph, m_node, "Bad use kind");
1604                 break;
1605             }
1606
1607             emitBinarySnippet<JITSubGenerator>(operationValueSub);
1608             break;
1609         }
1610
1611         default:
1612             DFG_CRASH(m_graph, m_node, "Bad use kind");
1613             break;
1614         }
1615     }
1616
1617     void compileArithClz32()
1618     {
1619         LValue operand = lowInt32(m_node->child1());
1620         setInt32(m_out.ctlz32(operand));
1621     }
1622     
1623     void compileArithMul()
1624     {
1625         switch (m_node->binaryUseKind()) {
1626         case Int32Use: {
1627             LValue left = lowInt32(m_node->child1());
1628             LValue right = lowInt32(m_node->child2());
1629             
1630             LValue result;
1631
1632             if (!shouldCheckOverflow(m_node->arithMode()))
1633                 result = m_out.mul(left, right);
1634             else {
1635                 CheckValue* speculation = m_out.speculateMul(left, right);
1636                 blessSpeculation(speculation, Overflow, noValue(), nullptr, m_origin);
1637                 result = speculation;
1638             }
1639             
1640             if (shouldCheckNegativeZero(m_node->arithMode())) {
1641                 LBasicBlock slowCase = m_out.newBlock();
1642                 LBasicBlock continuation = m_out.newBlock();
1643                 
1644                 m_out.branch(
1645                     m_out.notZero32(result), usually(continuation), rarely(slowCase));
1646                 
1647                 LBasicBlock lastNext = m_out.appendTo(slowCase, continuation);
1648                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(left, m_out.int32Zero));
1649                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(right, m_out.int32Zero));
1650                 m_out.jump(continuation);
1651                 m_out.appendTo(continuation, lastNext);
1652             }
1653             
1654             setInt32(result);
1655             break;
1656         }
1657             
1658         case Int52RepUse: {
1659             Int52Kind kind;
1660             LValue left = lowWhicheverInt52(m_node->child1(), kind);
1661             LValue right = lowInt52(m_node->child2(), opposite(kind));
1662
1663             CheckValue* result = m_out.speculateMul(left, right);
1664             blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);
1665
1666             if (shouldCheckNegativeZero(m_node->arithMode())) {
1667                 LBasicBlock slowCase = m_out.newBlock();
1668                 LBasicBlock continuation = m_out.newBlock();
1669                 
1670                 m_out.branch(
1671                     m_out.notZero64(result), usually(continuation), rarely(slowCase));
1672                 
1673                 LBasicBlock lastNext = m_out.appendTo(slowCase, continuation);
1674                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(left, m_out.int64Zero));
1675                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(right, m_out.int64Zero));
1676                 m_out.jump(continuation);
1677                 m_out.appendTo(continuation, lastNext);
1678             }
1679             
1680             setInt52(result);
1681             break;
1682         }
1683             
1684         case DoubleRepUse: {
1685             setDouble(
1686                 m_out.doubleMul(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
1687             break;
1688         }
1689
1690         case UntypedUse: {
1691             emitBinarySnippet<JITMulGenerator>(operationValueMul);
1692             break;
1693         }
1694
1695         default:
1696             DFG_CRASH(m_graph, m_node, "Bad use kind");
1697             break;
1698         }
1699     }
1700
1701     void compileArithDiv()
1702     {
1703         switch (m_node->binaryUseKind()) {
1704         case Int32Use: {
1705             LValue numerator = lowInt32(m_node->child1());
1706             LValue denominator = lowInt32(m_node->child2());
1707
1708             if (shouldCheckNegativeZero(m_node->arithMode())) {
1709                 LBasicBlock zeroNumerator = m_out.newBlock();
1710                 LBasicBlock numeratorContinuation = m_out.newBlock();
1711
1712                 m_out.branch(
1713                     m_out.isZero32(numerator),
1714                     rarely(zeroNumerator), usually(numeratorContinuation));
1715
1716                 LBasicBlock innerLastNext = m_out.appendTo(zeroNumerator, numeratorContinuation);
1717
1718                 speculate(
1719                     NegativeZero, noValue(), 0, m_out.lessThan(denominator, m_out.int32Zero));
1720
1721                 m_out.jump(numeratorContinuation);
1722
1723                 m_out.appendTo(numeratorContinuation, innerLastNext);
1724             }
1725             
1726             if (shouldCheckOverflow(m_node->arithMode())) {
1727                 LBasicBlock unsafeDenominator = m_out.newBlock();
1728                 LBasicBlock continuation = m_out.newBlock();
1729
1730                 LValue adjustedDenominator = m_out.add(denominator, m_out.int32One);
1731                 m_out.branch(
1732                     m_out.above(adjustedDenominator, m_out.int32One),
1733                     usually(continuation), rarely(unsafeDenominator));
1734
1735                 LBasicBlock lastNext = m_out.appendTo(unsafeDenominator, continuation);
1736                 LValue neg2ToThe31 = m_out.constInt32(-2147483647-1);
1737                 speculate(Overflow, noValue(), nullptr, m_out.isZero32(denominator));
1738                 speculate(Overflow, noValue(), nullptr, m_out.equal(numerator, neg2ToThe31));
1739                 m_out.jump(continuation);
1740
1741                 m_out.appendTo(continuation, lastNext);
1742                 LValue result = m_out.div(numerator, denominator);
1743                 speculate(
1744                     Overflow, noValue(), 0,
1745                     m_out.notEqual(m_out.mul(result, denominator), numerator));
1746                 setInt32(result);
1747             } else
1748                 setInt32(m_out.chillDiv(numerator, denominator));
1749
1750             break;
1751         }
1752             
1753         case DoubleRepUse: {
1754             setDouble(m_out.doubleDiv(
1755                 lowDouble(m_node->child1()), lowDouble(m_node->child2())));
1756             break;
1757         }
1758
1759         case UntypedUse: {
1760             emitBinarySnippet<JITDivGenerator, NeedScratchFPR>(operationValueDiv);
1761             break;
1762         }
1763
1764         default:
1765             DFG_CRASH(m_graph, m_node, "Bad use kind");
1766             break;
1767         }
1768     }
1769     
1770     void compileArithMod()
1771     {
1772         switch (m_node->binaryUseKind()) {
1773         case Int32Use: {
1774             LValue numerator = lowInt32(m_node->child1());
1775             LValue denominator = lowInt32(m_node->child2());
1776
1777             LValue remainder;
1778             if (shouldCheckOverflow(m_node->arithMode())) {
1779                 LBasicBlock unsafeDenominator = m_out.newBlock();
1780                 LBasicBlock continuation = m_out.newBlock();
1781
1782                 LValue adjustedDenominator = m_out.add(denominator, m_out.int32One);
1783                 m_out.branch(
1784                     m_out.above(adjustedDenominator, m_out.int32One),
1785                     usually(continuation), rarely(unsafeDenominator));
1786
1787                 LBasicBlock lastNext = m_out.appendTo(unsafeDenominator, continuation);
1788                 LValue neg2ToThe31 = m_out.constInt32(-2147483647-1);
1789                 speculate(Overflow, noValue(), nullptr, m_out.isZero32(denominator));
1790                 speculate(Overflow, noValue(), nullptr, m_out.equal(numerator, neg2ToThe31));
1791                 m_out.jump(continuation);
1792
1793                 m_out.appendTo(continuation, lastNext);
1794                 LValue result = m_out.mod(numerator, denominator);
1795                 remainder = result;
1796             } else
1797                 remainder = m_out.chillMod(numerator, denominator);
1798
1799             if (shouldCheckNegativeZero(m_node->arithMode())) {
1800                 LBasicBlock negativeNumerator = m_out.newBlock();
1801                 LBasicBlock numeratorContinuation = m_out.newBlock();
1802
1803                 m_out.branch(
1804                     m_out.lessThan(numerator, m_out.int32Zero),
1805                     unsure(negativeNumerator), unsure(numeratorContinuation));
1806
1807                 LBasicBlock innerLastNext = m_out.appendTo(negativeNumerator, numeratorContinuation);
1808
1809                 speculate(NegativeZero, noValue(), 0, m_out.isZero32(remainder));
1810
1811                 m_out.jump(numeratorContinuation);
1812
1813                 m_out.appendTo(numeratorContinuation, innerLastNext);
1814             }
1815
1816             setInt32(remainder);
1817             break;
1818         }
1819             
1820         case DoubleRepUse: {
1821             setDouble(
1822                 m_out.doubleMod(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
1823             break;
1824         }
1825             
1826         default:
1827             DFG_CRASH(m_graph, m_node, "Bad use kind");
1828             break;
1829         }
1830     }
1831
1832     void compileArithMinOrMax()
1833     {
1834         switch (m_node->binaryUseKind()) {
1835         case Int32Use: {
1836             LValue left = lowInt32(m_node->child1());
1837             LValue right = lowInt32(m_node->child2());
1838             
1839             setInt32(
1840                 m_out.select(
1841                     m_node->op() == ArithMin
1842                         ? m_out.lessThan(left, right)
1843                         : m_out.lessThan(right, left),
1844                     left, right));
1845             break;
1846         }
1847             
1848         case DoubleRepUse: {
1849             LValue left = lowDouble(m_node->child1());
1850             LValue right = lowDouble(m_node->child2());
1851             
1852             LBasicBlock notLessThan = m_out.newBlock();
1853             LBasicBlock continuation = m_out.newBlock();
1854             
1855             Vector<ValueFromBlock, 2> results;
1856             
1857             results.append(m_out.anchor(left));
1858             m_out.branch(
1859                 m_node->op() == ArithMin
1860                     ? m_out.doubleLessThan(left, right)
1861                     : m_out.doubleGreaterThan(left, right),
1862                 unsure(continuation), unsure(notLessThan));
1863             
1864             LBasicBlock lastNext = m_out.appendTo(notLessThan, continuation);
1865             results.append(m_out.anchor(m_out.select(
1866                 m_node->op() == ArithMin
1867                     ? m_out.doubleGreaterThanOrEqual(left, right)
1868                     : m_out.doubleLessThanOrEqual(left, right),
1869                 right, m_out.constDouble(PNaN))));
1870             m_out.jump(continuation);
1871             
1872             m_out.appendTo(continuation, lastNext);
1873             setDouble(m_out.phi(m_out.doubleType, results));
1874             break;
1875         }
1876             
1877         default:
1878             DFG_CRASH(m_graph, m_node, "Bad use kind");
1879             break;
1880         }
1881     }
1882     
1883     void compileArithAbs()
1884     {
1885         switch (m_node->child1().useKind()) {
1886         case Int32Use: {
1887             LValue value = lowInt32(m_node->child1());
1888
1889             LValue mask = m_out.aShr(value, m_out.constInt32(31));
1890             LValue result = m_out.bitXor(mask, m_out.add(mask, value));
1891
1892             if (shouldCheckOverflow(m_node->arithMode()))
1893                 speculate(Overflow, noValue(), 0, m_out.lessThan(result, m_out.int32Zero));
1894
1895             setInt32(result);
1896             break;
1897         }
1898             
1899         case DoubleRepUse: {
1900             setDouble(m_out.doubleAbs(lowDouble(m_node->child1())));
1901             break;
1902         }
1903             
1904         default:
1905             DFG_CRASH(m_graph, m_node, "Bad use kind");
1906             break;
1907         }
1908     }
1909
1910     void compileArithSin() { setDouble(m_out.doubleSin(lowDouble(m_node->child1()))); }
1911
1912     void compileArithCos() { setDouble(m_out.doubleCos(lowDouble(m_node->child1()))); }
1913
1914     void compileArithPow()
1915     {
1916         if (m_node->child2().useKind() == Int32Use)
1917             setDouble(m_out.doublePowi(lowDouble(m_node->child1()), lowInt32(m_node->child2())));
1918         else {
1919             LValue base = lowDouble(m_node->child1());
1920             LValue exponent = lowDouble(m_node->child2());
1921
1922             LBasicBlock integerExponentIsSmallBlock = m_out.newBlock();
1923             LBasicBlock integerExponentPowBlock = m_out.newBlock();
1924             LBasicBlock doubleExponentPowBlockEntry = m_out.newBlock();
1925             LBasicBlock nanExceptionBaseIsOne = m_out.newBlock();
1926             LBasicBlock nanExceptionExponentIsInfinity = m_out.newBlock();
1927             LBasicBlock testExponentIsOneHalf = m_out.newBlock();
1928             LBasicBlock handleBaseZeroExponentIsOneHalf = m_out.newBlock();
1929             LBasicBlock handleInfinityForExponentIsOneHalf = m_out.newBlock();
1930             LBasicBlock exponentIsOneHalfNormal = m_out.newBlock();
1931             LBasicBlock exponentIsOneHalfInfinity = m_out.newBlock();
1932             LBasicBlock testExponentIsNegativeOneHalf = m_out.newBlock();
1933             LBasicBlock testBaseZeroExponentIsNegativeOneHalf = m_out.newBlock();
1934             LBasicBlock handleBaseZeroExponentIsNegativeOneHalf = m_out.newBlock();
1935             LBasicBlock handleInfinityForExponentIsNegativeOneHalf = m_out.newBlock();
1936             LBasicBlock exponentIsNegativeOneHalfNormal = m_out.newBlock();
1937             LBasicBlock exponentIsNegativeOneHalfInfinity = m_out.newBlock();
1938             LBasicBlock powBlock = m_out.newBlock();
1939             LBasicBlock nanExceptionResultIsNaN = m_out.newBlock();
1940             LBasicBlock continuation = m_out.newBlock();
1941
1942             LValue integerExponent = m_out.doubleToInt(exponent);
1943             LValue integerExponentConvertedToDouble = m_out.intToDouble(integerExponent);
1944             LValue exponentIsInteger = m_out.doubleEqual(exponent, integerExponentConvertedToDouble);
1945             m_out.branch(exponentIsInteger, unsure(integerExponentIsSmallBlock), unsure(doubleExponentPowBlockEntry));
1946
1947             LBasicBlock lastNext = m_out.appendTo(integerExponentIsSmallBlock, integerExponentPowBlock);
1948             LValue integerExponentBelowMax = m_out.belowOrEqual(integerExponent, m_out.constInt32(maxExponentForIntegerMathPow));
1949             m_out.branch(integerExponentBelowMax, usually(integerExponentPowBlock), rarely(doubleExponentPowBlockEntry));
1950
1951             m_out.appendTo(integerExponentPowBlock, doubleExponentPowBlockEntry);
1952             ValueFromBlock powDoubleIntResult = m_out.anchor(m_out.doublePowi(base, integerExponent));
1953             m_out.jump(continuation);
1954
1955             // If y is NaN, the result is NaN.
1956             m_out.appendTo(doubleExponentPowBlockEntry, nanExceptionBaseIsOne);
1957             LValue exponentIsNaN;
1958             if (provenType(m_node->child2()) & SpecDoubleNaN)
1959                 exponentIsNaN = m_out.doubleNotEqualOrUnordered(exponent, exponent);
1960             else
1961                 exponentIsNaN = m_out.booleanFalse;
1962             m_out.branch(exponentIsNaN, rarely(nanExceptionResultIsNaN), usually(nanExceptionBaseIsOne));
1963
1964             // If abs(x) is 1 and y is +infinity, the result is NaN.
1965             // If abs(x) is 1 and y is -infinity, the result is NaN.
1966
1967             //     Test if base == 1.
1968             m_out.appendTo(nanExceptionBaseIsOne, nanExceptionExponentIsInfinity);
1969             LValue absoluteBase = m_out.doubleAbs(base);
1970             LValue absoluteBaseIsOne = m_out.doubleEqual(absoluteBase, m_out.constDouble(1));
1971             m_out.branch(absoluteBaseIsOne, rarely(nanExceptionExponentIsInfinity), usually(testExponentIsOneHalf));
1972
1973             //     Test if abs(y) == Infinity.
1974             m_out.appendTo(nanExceptionExponentIsInfinity, testExponentIsOneHalf);
1975             LValue absoluteExponent = m_out.doubleAbs(exponent);
1976             LValue absoluteExponentIsInfinity = m_out.doubleEqual(absoluteExponent, m_out.constDouble(std::numeric_limits<double>::infinity()));
1977             m_out.branch(absoluteExponentIsInfinity, rarely(nanExceptionResultIsNaN), usually(testExponentIsOneHalf));
1978
1979             // If y == 0.5 or y == -0.5, handle it through SQRT.
1980             // We have be carefuly with -0 and -Infinity.
1981
1982             //     Test if y == 0.5
1983             m_out.appendTo(testExponentIsOneHalf, handleBaseZeroExponentIsOneHalf);
1984             LValue exponentIsOneHalf = m_out.doubleEqual(exponent, m_out.constDouble(0.5));
1985             m_out.branch(exponentIsOneHalf, rarely(handleBaseZeroExponentIsOneHalf), usually(testExponentIsNegativeOneHalf));
1986
1987             //     Handle x == -0.
1988             m_out.appendTo(handleBaseZeroExponentIsOneHalf, handleInfinityForExponentIsOneHalf);
1989             LValue baseIsZeroExponentIsOneHalf = m_out.doubleEqual(base, m_out.doubleZero);
1990             ValueFromBlock zeroResultExponentIsOneHalf = m_out.anchor(m_out.doubleZero);
1991             m_out.branch(baseIsZeroExponentIsOneHalf, rarely(continuation), usually(handleInfinityForExponentIsOneHalf));
1992
1993             //     Test if abs(x) == Infinity.
1994             m_out.appendTo(handleInfinityForExponentIsOneHalf, exponentIsOneHalfNormal);
1995             LValue absoluteBaseIsInfinityOneHalf = m_out.doubleEqual(absoluteBase, m_out.constDouble(std::numeric_limits<double>::infinity()));
1996             m_out.branch(absoluteBaseIsInfinityOneHalf, rarely(exponentIsOneHalfInfinity), usually(exponentIsOneHalfNormal));
1997
1998             //     The exponent is 0.5, the base is finite or NaN, we can use SQRT.
1999             m_out.appendTo(exponentIsOneHalfNormal, exponentIsOneHalfInfinity);
2000             ValueFromBlock sqrtResult = m_out.anchor(m_out.doubleSqrt(base));
2001             m_out.jump(continuation);
2002
2003             //     The exponent is 0.5, the base is infinite, the result is always infinite.
2004             m_out.appendTo(exponentIsOneHalfInfinity, testExponentIsNegativeOneHalf);
2005             ValueFromBlock sqrtInfinityResult = m_out.anchor(m_out.constDouble(std::numeric_limits<double>::infinity()));
2006             m_out.jump(continuation);
2007
2008             //     Test if y == -0.5
2009             m_out.appendTo(testExponentIsNegativeOneHalf, testBaseZeroExponentIsNegativeOneHalf);
2010             LValue exponentIsNegativeOneHalf = m_out.doubleEqual(exponent, m_out.constDouble(-0.5));
2011             m_out.branch(exponentIsNegativeOneHalf, rarely(testBaseZeroExponentIsNegativeOneHalf), usually(powBlock));
2012
2013             //     Handle x == -0.
2014             m_out.appendTo(testBaseZeroExponentIsNegativeOneHalf, handleBaseZeroExponentIsNegativeOneHalf);
2015             LValue baseIsZeroExponentIsNegativeOneHalf = m_out.doubleEqual(base, m_out.doubleZero);
2016             m_out.branch(baseIsZeroExponentIsNegativeOneHalf, rarely(handleBaseZeroExponentIsNegativeOneHalf), usually(handleInfinityForExponentIsNegativeOneHalf));
2017
2018             m_out.appendTo(handleBaseZeroExponentIsNegativeOneHalf, handleInfinityForExponentIsNegativeOneHalf);
2019             ValueFromBlock oneOverSqrtZeroResult = m_out.anchor(m_out.constDouble(std::numeric_limits<double>::infinity()));
2020             m_out.jump(continuation);
2021
2022             //     Test if abs(x) == Infinity.
2023             m_out.appendTo(handleInfinityForExponentIsNegativeOneHalf, exponentIsNegativeOneHalfNormal);
2024             LValue absoluteBaseIsInfinityNegativeOneHalf = m_out.doubleEqual(absoluteBase, m_out.constDouble(std::numeric_limits<double>::infinity()));
2025             m_out.branch(absoluteBaseIsInfinityNegativeOneHalf, rarely(exponentIsNegativeOneHalfInfinity), usually(exponentIsNegativeOneHalfNormal));
2026
2027             //     The exponent is -0.5, the base is finite or NaN, we can use 1/SQRT.
2028             m_out.appendTo(exponentIsNegativeOneHalfNormal, exponentIsNegativeOneHalfInfinity);
2029             LValue sqrtBase = m_out.doubleSqrt(base);
2030             ValueFromBlock oneOverSqrtResult = m_out.anchor(m_out.div(m_out.constDouble(1.), sqrtBase));
2031             m_out.jump(continuation);
2032
2033             //     The exponent is -0.5, the base is infinite, the result is always zero.
2034             m_out.appendTo(exponentIsNegativeOneHalfInfinity, powBlock);
2035             ValueFromBlock oneOverSqrtInfinityResult = m_out.anchor(m_out.doubleZero);
2036             m_out.jump(continuation);
2037
2038             m_out.appendTo(powBlock, nanExceptionResultIsNaN);
2039             ValueFromBlock powResult = m_out.anchor(m_out.doublePow(base, exponent));
2040             m_out.jump(continuation);
2041
2042             m_out.appendTo(nanExceptionResultIsNaN, continuation);
2043             ValueFromBlock pureNan = m_out.anchor(m_out.constDouble(PNaN));
2044             m_out.jump(continuation);
2045
2046             m_out.appendTo(continuation, lastNext);
2047             setDouble(m_out.phi(m_out.doubleType, powDoubleIntResult, zeroResultExponentIsOneHalf, sqrtResult, sqrtInfinityResult, oneOverSqrtZeroResult, oneOverSqrtResult, oneOverSqrtInfinityResult, powResult, pureNan));
2048         }
2049     }
2050
2051     void compileArithRandom()
2052     {
2053         JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
2054
2055         // Inlined WeakRandom::advance().
2056         // uint64_t x = m_low;
2057         void* lowAddress = reinterpret_cast<uint8_t*>(globalObject) + JSGlobalObject::weakRandomOffset() + WeakRandom::lowOffset();
2058         LValue low = m_out.load64(m_out.absolute(lowAddress));
2059         // uint64_t y = m_high;
2060         void* highAddress = reinterpret_cast<uint8_t*>(globalObject) + JSGlobalObject::weakRandomOffset() + WeakRandom::highOffset();
2061         LValue high = m_out.load64(m_out.absolute(highAddress));
2062         // m_low = y;
2063         m_out.store64(high, m_out.absolute(lowAddress));
2064
2065         // x ^= x << 23;
2066         LValue phase1 = m_out.bitXor(m_out.shl(low, m_out.constInt64(23)), low);
2067
2068         // x ^= x >> 17;
2069         LValue phase2 = m_out.bitXor(m_out.lShr(phase1, m_out.constInt64(17)), phase1);
2070
2071         // x ^= y ^ (y >> 26);
2072         LValue phase3 = m_out.bitXor(m_out.bitXor(high, m_out.lShr(high, m_out.constInt64(26))), phase2);
2073
2074         // m_high = x;
2075         m_out.store64(phase3, m_out.absolute(highAddress));
2076
2077         // return x + y;
2078         LValue random64 = m_out.add(phase3, high);
2079
2080         // Extract random 53bit. [0, 53] bit is safe integer number ranges in double representation.
2081         LValue random53 = m_out.bitAnd(random64, m_out.constInt64((1ULL << 53) - 1));
2082
2083         LValue double53Integer = m_out.intToDouble(random53);
2084
2085         // Convert `(53bit double integer value) / (1 << 53)` to `(53bit double integer value) * (1.0 / (1 << 53))`.
2086         // In latter case, `1.0 / (1 << 53)` will become a double value represented as (mantissa = 0 & exp = 970, it means 1e-(2**54)).
2087         static const double scale = 1.0 / (1ULL << 53);
2088
2089         // Multiplying 1e-(2**54) with the double integer does not change anything of the mantissa part of the double integer.
2090         // It just reduces the exp part of the given 53bit double integer.
2091         // (Except for 0.0. This is specially handled and in this case, exp just becomes 0.)
2092         // Now we get 53bit precision random double value in [0, 1).
2093         LValue result = m_out.doubleMul(double53Integer, m_out.constDouble(scale));
2094
2095         setDouble(result);
2096     }
2097
2098     void compileArithRound()
2099     {
2100         LValue result = nullptr;
2101
2102         if (producesInteger(m_node->arithRoundingMode()) && !shouldCheckNegativeZero(m_node->arithRoundingMode())) {
2103             LValue value = lowDouble(m_node->child1());
2104             result = m_out.doubleFloor(m_out.doubleAdd(value, m_out.constDouble(0.5)));
2105         } else {
2106             LBasicBlock realPartIsMoreThanHalf = m_out.newBlock();
2107             LBasicBlock continuation = m_out.newBlock();
2108
2109             LValue value = lowDouble(m_node->child1());
2110             LValue integerValue = m_out.doubleCeil(value);
2111             ValueFromBlock integerValueResult = m_out.anchor(integerValue);
2112
2113             LValue realPart = m_out.doubleSub(integerValue, value);
2114
2115             m_out.branch(m_out.doubleGreaterThanOrUnordered(realPart, m_out.constDouble(0.5)), unsure(realPartIsMoreThanHalf), unsure(continuation));
2116
2117             LBasicBlock lastNext = m_out.appendTo(realPartIsMoreThanHalf, continuation);
2118             LValue integerValueRoundedDown = m_out.doubleSub(integerValue, m_out.constDouble(1));
2119             ValueFromBlock integerValueRoundedDownResult = m_out.anchor(integerValueRoundedDown);
2120             m_out.jump(continuation);
2121             m_out.appendTo(continuation, lastNext);
2122
2123             result = m_out.phi(m_out.doubleType, integerValueResult, integerValueRoundedDownResult);
2124         }
2125
2126         if (producesInteger(m_node->arithRoundingMode())) {
2127             LValue integerValue = convertDoubleToInt32(result, shouldCheckNegativeZero(m_node->arithRoundingMode()));
2128             setInt32(integerValue);
2129         } else
2130             setDouble(result);
2131     }
2132
2133     void compileArithFloor()
2134     {
2135         LValue value = lowDouble(m_node->child1());
2136         LValue integerValue = m_out.doubleFloor(value);
2137         if (producesInteger(m_node->arithRoundingMode()))
2138             setInt32(convertDoubleToInt32(integerValue, shouldCheckNegativeZero(m_node->arithRoundingMode())));
2139         else
2140             setDouble(integerValue);
2141     }
2142
2143     void compileArithCeil()
2144     {
2145         LValue value = lowDouble(m_node->child1());
2146         LValue integerValue = m_out.doubleCeil(value);
2147         if (producesInteger(m_node->arithRoundingMode()))
2148             setInt32(convertDoubleToInt32(integerValue, shouldCheckNegativeZero(m_node->arithRoundingMode())));
2149         else
2150             setDouble(integerValue);
2151     }
2152
2153     void compileArithTrunc()
2154     {
2155         LValue value = lowDouble(m_node->child1());
2156         LValue result = m_out.doubleTrunc(value);
2157         if (producesInteger(m_node->arithRoundingMode()))
2158             setInt32(convertDoubleToInt32(result, shouldCheckNegativeZero(m_node->arithRoundingMode())));
2159         else
2160             setDouble(result);
2161     }
2162
2163     void compileArithSqrt() { setDouble(m_out.doubleSqrt(lowDouble(m_node->child1()))); }
2164
2165     void compileArithLog() { setDouble(m_out.doubleLog(lowDouble(m_node->child1()))); }
2166     
2167     void compileArithFRound()
2168     {
2169         setDouble(m_out.fround(lowDouble(m_node->child1())));
2170     }
2171     
2172     void compileArithNegate()
2173     {
2174         switch (m_node->child1().useKind()) {
2175         case Int32Use: {
2176             LValue value = lowInt32(m_node->child1());
2177             
2178             LValue result;
2179             if (!shouldCheckOverflow(m_node->arithMode()))
2180                 result = m_out.neg(value);
2181             else if (!shouldCheckNegativeZero(m_node->arithMode())) {
2182                 CheckValue* check = m_out.speculateSub(m_out.int32Zero, value);
2183                 blessSpeculation(check, Overflow, noValue(), nullptr, m_origin);
2184                 result = check;
2185             } else {
2186                 speculate(Overflow, noValue(), 0, m_out.testIsZero32(value, m_out.constInt32(0x7fffffff)));
2187                 result = m_out.neg(value);
2188             }
2189
2190             setInt32(result);
2191             break;
2192         }
2193             
2194         case Int52RepUse: {
2195             if (!abstractValue(m_node->child1()).couldBeType(SpecInt52Only)) {
2196                 Int52Kind kind;
2197                 LValue value = lowWhicheverInt52(m_node->child1(), kind);
2198                 LValue result = m_out.neg(value);
2199                 if (shouldCheckNegativeZero(m_node->arithMode()))
2200                     speculate(NegativeZero, noValue(), 0, m_out.isZero64(result));
2201                 setInt52(result, kind);
2202                 break;
2203             }
2204             
2205             LValue value = lowInt52(m_node->child1());
2206             CheckValue* result = m_out.speculateSub(m_out.int64Zero, value);
2207             blessSpeculation(result, Int52Overflow, noValue(), nullptr, m_origin);
2208             speculate(NegativeZero, noValue(), 0, m_out.isZero64(result));
2209             setInt52(result);
2210             break;
2211         }
2212             
2213         case DoubleRepUse: {
2214             setDouble(m_out.doubleNeg(lowDouble(m_node->child1())));
2215             break;
2216         }
2217             
2218         default:
2219             DFG_CRASH(m_graph, m_node, "Bad use kind");
2220             break;
2221         }
2222     }
2223     
2224     void compileBitAnd()
2225     {
2226         if (m_node->isBinaryUseKind(UntypedUse)) {
2227             emitBinaryBitOpSnippet<JITBitAndGenerator>(operationValueBitAnd);
2228             return;
2229         }
2230         setInt32(m_out.bitAnd(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2231     }
2232     
2233     void compileBitOr()
2234     {
2235         if (m_node->isBinaryUseKind(UntypedUse)) {
2236             emitBinaryBitOpSnippet<JITBitOrGenerator>(operationValueBitOr);
2237             return;
2238         }
2239         setInt32(m_out.bitOr(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2240     }
2241     
2242     void compileBitXor()
2243     {
2244         if (m_node->isBinaryUseKind(UntypedUse)) {
2245             emitBinaryBitOpSnippet<JITBitXorGenerator>(operationValueBitXor);
2246             return;
2247         }
2248         setInt32(m_out.bitXor(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2249     }
2250     
2251     void compileBitRShift()
2252     {
2253         if (m_node->isBinaryUseKind(UntypedUse)) {
2254             emitRightShiftSnippet(JITRightShiftGenerator::SignedShift);
2255             return;
2256         }
2257         setInt32(m_out.aShr(
2258             lowInt32(m_node->child1()),
2259             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2260     }
2261     
2262     void compileBitLShift()
2263     {
2264         if (m_node->isBinaryUseKind(UntypedUse)) {
2265             emitBinaryBitOpSnippet<JITLeftShiftGenerator>(operationValueBitLShift);
2266             return;
2267         }
2268         setInt32(m_out.shl(
2269             lowInt32(m_node->child1()),
2270             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2271     }
2272     
2273     void compileBitURShift()
2274     {
2275         if (m_node->isBinaryUseKind(UntypedUse)) {
2276             emitRightShiftSnippet(JITRightShiftGenerator::UnsignedShift);
2277             return;
2278         }
2279         setInt32(m_out.lShr(
2280             lowInt32(m_node->child1()),
2281             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2282     }
2283     
2284     void compileUInt32ToNumber()
2285     {
2286         LValue value = lowInt32(m_node->child1());
2287
2288         if (doesOverflow(m_node->arithMode())) {
2289             setStrictInt52(m_out.zeroExtPtr(value));
2290             return;
2291         }
2292
2293         speculate(Overflow, noValue(), 0, m_out.lessThan(value, m_out.int32Zero));
2294         setInt32(value);
2295     }
2296     
2297     void compileCheckStructure()
2298     {
2299         ExitKind exitKind;
2300         if (m_node->child1()->hasConstant())
2301             exitKind = BadConstantCache;
2302         else
2303             exitKind = BadCache;
2304
2305         switch (m_node->child1().useKind()) {
2306         case CellUse:
2307         case KnownCellUse: {
2308             LValue cell = lowCell(m_node->child1());
2309             
2310             checkStructure(
2311                 m_out.load32(cell, m_heaps.JSCell_structureID), jsValueValue(cell),
2312                 exitKind, m_node->structureSet(),
2313                 [&] (Structure* structure) {
2314                     return weakStructureID(structure);
2315                 });
2316             return;
2317         }
2318
2319         case CellOrOtherUse: {
2320             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
2321
2322             LBasicBlock cellCase = m_out.newBlock();
2323             LBasicBlock notCellCase = m_out.newBlock();
2324             LBasicBlock continuation = m_out.newBlock();
2325
2326             m_out.branch(
2327                 isCell(value, provenType(m_node->child1())), unsure(cellCase), unsure(notCellCase));
2328
2329             LBasicBlock lastNext = m_out.appendTo(cellCase, notCellCase);
2330             checkStructure(
2331                 m_out.load32(value, m_heaps.JSCell_structureID), jsValueValue(value),
2332                 exitKind, m_node->structureSet(),
2333                 [&] (Structure* structure) {
2334                     return weakStructureID(structure);
2335                 });
2336             m_out.jump(continuation);
2337
2338             m_out.appendTo(notCellCase, continuation);
2339             FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), SpecCell | SpecOther, isNotOther(value));
2340             m_out.jump(continuation);
2341
2342             m_out.appendTo(continuation, lastNext);
2343             return;
2344         }
2345
2346         default:
2347             DFG_CRASH(m_graph, m_node, "Bad use kind");
2348             return;
2349         }
2350     }
2351     
2352     void compileCheckCell()
2353     {
2354         LValue cell = lowCell(m_node->child1());
2355         
2356         speculate(
2357             BadCell, jsValueValue(cell), m_node->child1().node(),
2358             m_out.notEqual(cell, weakPointer(m_node->cellOperand()->cell())));
2359     }
2360     
2361     void compileCheckBadCell()
2362     {
2363         terminate(BadCell);
2364     }
2365
2366     void compileCheckNotEmpty()
2367     {
2368         speculate(TDZFailure, noValue(), nullptr, m_out.isZero64(lowJSValue(m_node->child1())));
2369     }
2370
2371     void compileCheckIdent()
2372     {
2373         UniquedStringImpl* uid = m_node->uidOperand();
2374         if (uid->isSymbol()) {
2375             LValue symbol = lowSymbol(m_node->child1());
2376             LValue stringImpl = m_out.loadPtr(symbol, m_heaps.Symbol_privateName);
2377             speculate(BadIdent, noValue(), nullptr, m_out.notEqual(stringImpl, m_out.constIntPtr(uid)));
2378         } else {
2379             LValue string = lowStringIdent(m_node->child1());
2380             LValue stringImpl = m_out.loadPtr(string, m_heaps.JSString_value);
2381             speculate(BadIdent, noValue(), nullptr, m_out.notEqual(stringImpl, m_out.constIntPtr(uid)));
2382         }
2383     }
2384
2385     void compileGetExecutable()
2386     {
2387         LValue cell = lowCell(m_node->child1());
2388         speculateFunction(m_node->child1(), cell);
2389         setJSValue(m_out.loadPtr(cell, m_heaps.JSFunction_executable));
2390     }
2391     
2392     void compileArrayifyToStructure()
2393     {
2394         LValue cell = lowCell(m_node->child1());
2395         LValue property = !!m_node->child2() ? lowInt32(m_node->child2()) : 0;
2396         
2397         LBasicBlock unexpectedStructure = m_out.newBlock();
2398         LBasicBlock continuation = m_out.newBlock();
2399         
2400         LValue structureID = m_out.load32(cell, m_heaps.JSCell_structureID);
2401         
2402         m_out.branch(
2403             m_out.notEqual(structureID, weakStructureID(m_node->structure())),
2404             rarely(unexpectedStructure), usually(continuation));
2405         
2406         LBasicBlock lastNext = m_out.appendTo(unexpectedStructure, continuation);
2407         
2408         if (property) {
2409             switch (m_node->arrayMode().type()) {
2410             case Array::Int32:
2411             case Array::Double:
2412             case Array::Contiguous:
2413                 speculate(
2414                     Uncountable, noValue(), 0,
2415                     m_out.aboveOrEqual(property, m_out.constInt32(MIN_SPARSE_ARRAY_INDEX)));
2416                 break;
2417             default:
2418                 break;
2419             }
2420         }
2421         
2422         switch (m_node->arrayMode().type()) {
2423         case Array::Int32:
2424             vmCall(m_out.voidType, m_out.operation(operationEnsureInt32), m_callFrame, cell);
2425             break;
2426         case Array::Double:
2427             vmCall(m_out.voidType, m_out.operation(operationEnsureDouble), m_callFrame, cell);
2428             break;
2429         case Array::Contiguous:
2430             vmCall(m_out.voidType, m_out.operation(operationEnsureContiguous), m_callFrame, cell);
2431             break;
2432         case Array::ArrayStorage:
2433         case Array::SlowPutArrayStorage:
2434             vmCall(m_out.voidType, m_out.operation(operationEnsureArrayStorage), m_callFrame, cell);
2435             break;
2436         default:
2437             DFG_CRASH(m_graph, m_node, "Bad array type");
2438             break;
2439         }
2440         
2441         structureID = m_out.load32(cell, m_heaps.JSCell_structureID);
2442         speculate(
2443             BadIndexingType, jsValueValue(cell), 0,
2444             m_out.notEqual(structureID, weakStructureID(m_node->structure())));
2445         m_out.jump(continuation);
2446         
2447         m_out.appendTo(continuation, lastNext);
2448     }
2449     
2450     void compilePutStructure()
2451     {
2452         m_ftlState.jitCode->common.notifyCompilingStructureTransition(m_graph.m_plan, codeBlock(), m_node);
2453
2454         Structure* oldStructure = m_node->transition()->previous;
2455         Structure* newStructure = m_node->transition()->next;
2456         ASSERT_UNUSED(oldStructure, oldStructure->indexingType() == newStructure->indexingType());
2457         ASSERT(oldStructure->typeInfo().inlineTypeFlags() == newStructure->typeInfo().inlineTypeFlags());
2458         ASSERT(oldStructure->typeInfo().type() == newStructure->typeInfo().type());
2459
2460         LValue cell = lowCell(m_node->child1()); 
2461         m_out.store32(
2462             weakStructureID(newStructure),
2463             cell, m_heaps.JSCell_structureID);
2464     }
2465     
2466     void compileGetById(AccessType type)
2467     {
2468         ASSERT(type == AccessType::Get || type == AccessType::GetPure);
2469         switch (m_node->child1().useKind()) {
2470         case CellUse: {
2471             setJSValue(getById(lowCell(m_node->child1()), type));
2472             return;
2473         }
2474             
2475         case UntypedUse: {
2476             // This is pretty weird, since we duplicate the slow path both here and in the
2477             // code generated by the IC. We should investigate making this less bad.
2478             // https://bugs.webkit.org/show_bug.cgi?id=127830
2479             LValue value = lowJSValue(m_node->child1());
2480             
2481             LBasicBlock cellCase = m_out.newBlock();
2482             LBasicBlock notCellCase = m_out.newBlock();
2483             LBasicBlock continuation = m_out.newBlock();
2484             
2485             m_out.branch(
2486                 isCell(value, provenType(m_node->child1())), unsure(cellCase), unsure(notCellCase));
2487             
2488             LBasicBlock lastNext = m_out.appendTo(cellCase, notCellCase);
2489             ValueFromBlock cellResult = m_out.anchor(getById(value, type));
2490             m_out.jump(continuation);
2491
2492             J_JITOperation_EJI getByIdFunction;
2493             if (type == AccessType::Get)
2494                 getByIdFunction = operationGetByIdGeneric;
2495             else
2496                 getByIdFunction = operationTryGetByIdGeneric;
2497
2498             m_out.appendTo(notCellCase, continuation);
2499             ValueFromBlock notCellResult = m_out.anchor(vmCall(
2500                 m_out.int64, m_out.operation(getByIdFunction),
2501                 m_callFrame, value,
2502                 m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()])));
2503             m_out.jump(continuation);
2504             
2505             m_out.appendTo(continuation, lastNext);
2506             setJSValue(m_out.phi(m_out.int64, cellResult, notCellResult));
2507             return;
2508         }
2509             
2510         default:
2511             DFG_CRASH(m_graph, m_node, "Bad use kind");
2512             return;
2513         }
2514     }
2515
2516     void compileGetByIdWithThis()
2517     {
2518         LValue base = lowJSValue(m_node->child1());
2519         LValue thisValue = lowJSValue(m_node->child2());
2520         LValue result = vmCall(m_out.int64, m_out.operation(operationGetByIdWithThis), m_callFrame, base, thisValue, m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()]));
2521         setJSValue(result);
2522     }
2523
2524     void compileGetByValWithThis()
2525     {
2526         LValue base = lowJSValue(m_node->child1());
2527         LValue thisValue = lowJSValue(m_node->child2());
2528         LValue subscript = lowJSValue(m_node->child3());
2529
2530         LValue result = vmCall(m_out.int64, m_out.operation(operationGetByValWithThis), m_callFrame, base, thisValue, subscript);
2531         setJSValue(result);
2532     }
2533
2534     void compilePutByIdWithThis()
2535     {
2536         LValue base = lowJSValue(m_node->child1());
2537         LValue thisValue = lowJSValue(m_node->child2());
2538         LValue value = lowJSValue(m_node->child3());
2539
2540         vmCall(m_out.voidType, m_out.operation(m_graph.isStrictModeFor(m_node->origin.semantic) ? operationPutByIdWithThisStrict : operationPutByIdWithThis),
2541             m_callFrame, base, thisValue, value, m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()]));
2542     }
2543
2544     void compilePutByValWithThis()
2545     {
2546         LValue base = lowJSValue(m_graph.varArgChild(m_node, 0));
2547         LValue thisValue = lowJSValue(m_graph.varArgChild(m_node, 1));
2548         LValue property = lowJSValue(m_graph.varArgChild(m_node, 2));
2549         LValue value = lowJSValue(m_graph.varArgChild(m_node, 3));
2550
2551         vmCall(m_out.voidType, m_out.operation(m_graph.isStrictModeFor(m_node->origin.semantic) ? operationPutByValWithThisStrict : operationPutByValWithThis),
2552             m_callFrame, base, thisValue, property, value);
2553     }
2554     
2555     void compilePutById()
2556     {
2557         Node* node = m_node;
2558         
2559         // See above; CellUse is easier so we do only that for now.
2560         ASSERT(node->child1().useKind() == CellUse);
2561
2562         LValue base = lowCell(node->child1());
2563         LValue value = lowJSValue(node->child2());
2564         auto uid = m_graph.identifiers()[node->identifierNumber()];
2565
2566         B3::PatchpointValue* patchpoint = m_out.patchpoint(Void);
2567         patchpoint->appendSomeRegister(base);
2568         patchpoint->appendSomeRegister(value);
2569         patchpoint->append(m_tagMask, ValueRep::reg(GPRInfo::tagMaskRegister));
2570         patchpoint->append(m_tagTypeNumber, ValueRep::reg(GPRInfo::tagTypeNumberRegister));
2571         patchpoint->clobber(RegisterSet::macroScratchRegisters());
2572
2573         // FIXME: If this is a PutByIdFlush, we might want to late-clobber volatile registers.
2574         // https://bugs.webkit.org/show_bug.cgi?id=152848
2575
2576         RefPtr<PatchpointExceptionHandle> exceptionHandle =
2577             preparePatchpointForExceptions(patchpoint);
2578
2579         State* state = &m_ftlState;
2580         ECMAMode ecmaMode = m_graph.executableFor(node->origin.semantic)->ecmaMode();
2581         
2582         patchpoint->setGenerator(
2583             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
2584                 AllowMacroScratchRegisterUsage allowScratch(jit);
2585
2586                 CallSiteIndex callSiteIndex =
2587                     state->jitCode->common.addUniqueCallSiteIndex(node->origin.semantic);
2588
2589                 Box<CCallHelpers::JumpList> exceptions =
2590                     exceptionHandle->scheduleExitCreation(params)->jumps(jit);
2591
2592                 // JS setter call ICs generated by the PutById IC will need this.
2593                 exceptionHandle->scheduleExitCreationForUnwind(params, callSiteIndex);
2594
2595                 auto generator = Box<JITPutByIdGenerator>::create(
2596                     jit.codeBlock(), node->origin.semantic, callSiteIndex,
2597                     params.unavailableRegisters(), JSValueRegs(params[0].gpr()),
2598                     JSValueRegs(params[1].gpr()), GPRInfo::patchpointScratchRegister, ecmaMode,
2599                     node->op() == PutByIdDirect ? Direct : NotDirect);
2600
2601                 generator->generateFastPath(jit);
2602                 CCallHelpers::Label done = jit.label();
2603
2604                 params.addLatePath(
2605                     [=] (CCallHelpers& jit) {
2606                         AllowMacroScratchRegisterUsage allowScratch(jit);
2607
2608                         generator->slowPathJump().link(&jit);
2609                         CCallHelpers::Label slowPathBegin = jit.label();
2610                         CCallHelpers::Call slowPathCall = callOperation(
2611                             *state, params.unavailableRegisters(), jit, node->origin.semantic,
2612                             exceptions.get(), generator->slowPathFunction(), InvalidGPRReg,
2613                             CCallHelpers::TrustedImmPtr(generator->stubInfo()), params[1].gpr(),
2614                             params[0].gpr(), CCallHelpers::TrustedImmPtr(uid)).call();
2615                         jit.jump().linkTo(done, &jit);
2616
2617                         generator->reportSlowPathCall(slowPathBegin, slowPathCall);
2618
2619                         jit.addLinkTask(
2620                             [=] (LinkBuffer& linkBuffer) {
2621                                 generator->finalize(linkBuffer);
2622                             });
2623                     });
2624             });
2625     }
2626     
2627     void compileGetButterfly()
2628     {
2629         setStorage(m_out.loadPtr(lowCell(m_node->child1()), m_heaps.JSObject_butterfly));
2630     }
2631
2632     void compileConstantStoragePointer()
2633     {
2634         setStorage(m_out.constIntPtr(m_node->storagePointer()));
2635     }
2636     
2637     void compileGetIndexedPropertyStorage()
2638     {
2639         LValue cell = lowCell(m_node->child1());
2640         
2641         if (m_node->arrayMode().type() == Array::String) {
2642             LBasicBlock slowPath = m_out.newBlock();
2643             LBasicBlock continuation = m_out.newBlock();
2644
2645             LValue fastResultValue = m_out.loadPtr(cell, m_heaps.JSString_value);
2646             ValueFromBlock fastResult = m_out.anchor(fastResultValue);
2647             
2648             m_out.branch(
2649                 m_out.notNull(fastResultValue), usually(continuation), rarely(slowPath));
2650             
2651             LBasicBlock lastNext = m_out.appendTo(slowPath, continuation);
2652             
2653             ValueFromBlock slowResult = m_out.anchor(
2654                 vmCall(m_out.intPtr, m_out.operation(operationResolveRope), m_callFrame, cell));
2655             
2656             m_out.jump(continuation);
2657             
2658             m_out.appendTo(continuation, lastNext);
2659             
2660             setStorage(m_out.loadPtr(m_out.phi(m_out.intPtr, fastResult, slowResult), m_heaps.StringImpl_data));
2661             return;
2662         }
2663         
2664         setStorage(m_out.loadPtr(cell, m_heaps.JSArrayBufferView_vector));
2665     }
2666     
2667     void compileCheckArray()
2668     {
2669         Edge edge = m_node->child1();
2670         LValue cell = lowCell(edge);
2671         
2672         if (m_node->arrayMode().alreadyChecked(m_graph, m_node, abstractValue(edge)))
2673             return;
2674         
2675         speculate(
2676             BadIndexingType, jsValueValue(cell), 0,
2677             m_out.logicalNot(isArrayType(cell, m_node->arrayMode())));
2678     }
2679
2680     void compileGetTypedArrayByteOffset()
2681     {
2682         LValue basePtr = lowCell(m_node->child1());    
2683
2684         LBasicBlock simpleCase = m_out.newBlock();
2685         LBasicBlock wastefulCase = m_out.newBlock();
2686         LBasicBlock continuation = m_out.newBlock();
2687         
2688         LValue mode = m_out.load32(basePtr, m_heaps.JSArrayBufferView_mode);
2689         m_out.branch(
2690             m_out.notEqual(mode, m_out.constInt32(WastefulTypedArray)),
2691             unsure(simpleCase), unsure(wastefulCase));
2692
2693         LBasicBlock lastNext = m_out.appendTo(simpleCase, wastefulCase);
2694
2695         ValueFromBlock simpleOut = m_out.anchor(m_out.constIntPtr(0));
2696
2697         m_out.jump(continuation);
2698
2699         m_out.appendTo(wastefulCase, continuation);
2700
2701         LValue vectorPtr = m_out.loadPtr(basePtr, m_heaps.JSArrayBufferView_vector);
2702         LValue butterflyPtr = m_out.loadPtr(basePtr, m_heaps.JSObject_butterfly);
2703         LValue arrayBufferPtr = m_out.loadPtr(butterflyPtr, m_heaps.Butterfly_arrayBuffer);
2704         LValue dataPtr = m_out.loadPtr(arrayBufferPtr, m_heaps.ArrayBuffer_data);
2705
2706         ValueFromBlock wastefulOut = m_out.anchor(m_out.sub(vectorPtr, dataPtr));
2707
2708         m_out.jump(continuation);
2709         m_out.appendTo(continuation, lastNext);
2710
2711         setInt32(m_out.castToInt32(m_out.phi(m_out.intPtr, simpleOut, wastefulOut)));
2712     }
2713     
2714     void compileGetArrayLength()
2715     {
2716         switch (m_node->arrayMode().type()) {
2717         case Array::Int32:
2718         case Array::Double:
2719         case Array::Contiguous: {
2720             setInt32(m_out.load32NonNegative(lowStorage(m_node->child2()), m_heaps.Butterfly_publicLength));
2721             return;
2722         }
2723             
2724         case Array::String: {
2725             LValue string = lowCell(m_node->child1());
2726             setInt32(m_out.load32NonNegative(string, m_heaps.JSString_length));
2727             return;
2728         }
2729             
2730         case Array::DirectArguments: {
2731             LValue arguments = lowCell(m_node->child1());
2732             speculate(
2733                 ExoticObjectMode, noValue(), nullptr,
2734                 m_out.notNull(m_out.loadPtr(arguments, m_heaps.DirectArguments_overrides)));
2735             setInt32(m_out.load32NonNegative(arguments, m_heaps.DirectArguments_length));
2736             return;
2737         }
2738             
2739         case Array::ScopedArguments: {
2740             LValue arguments = lowCell(m_node->child1());
2741             speculate(
2742                 ExoticObjectMode, noValue(), nullptr,
2743                 m_out.notZero32(m_out.load8ZeroExt32(arguments, m_heaps.ScopedArguments_overrodeThings)));
2744             setInt32(m_out.load32NonNegative(arguments, m_heaps.ScopedArguments_totalLength));
2745             return;
2746         }
2747             
2748         default:
2749             if (m_node->arrayMode().isSomeTypedArrayView()) {
2750                 setInt32(
2751                     m_out.load32NonNegative(lowCell(m_node->child1()), m_heaps.JSArrayBufferView_length));
2752                 return;
2753             }
2754             
2755             DFG_CRASH(m_graph, m_node, "Bad array type");
2756             return;
2757         }
2758     }
2759     
2760     void compileCheckInBounds()
2761     {
2762         speculate(
2763             OutOfBounds, noValue(), 0,
2764             m_out.aboveOrEqual(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2765     }
2766     
2767     void compileGetByVal()
2768     {
2769         switch (m_node->arrayMode().type()) {
2770         case Array::Int32:
2771         case Array::Contiguous: {
2772             LValue index = lowInt32(m_node->child2());
2773             LValue storage = lowStorage(m_node->child3());
2774             
2775             IndexedAbstractHeap& heap = m_node->arrayMode().type() == Array::Int32 ?
2776                 m_heaps.indexedInt32Properties : m_heaps.indexedContiguousProperties;
2777             
2778             if (m_node->arrayMode().isInBounds()) {
2779                 LValue result = m_out.load64(baseIndex(heap, storage, index, m_node->child2()));
2780                 LValue isHole = m_out.isZero64(result);
2781                 if (m_node->arrayMode().isSaneChain()) {
2782                     DFG_ASSERT(
2783                         m_graph, m_node, m_node->arrayMode().type() == Array::Contiguous);
2784                     result = m_out.select(
2785                         isHole, m_out.constInt64(JSValue::encode(jsUndefined())), result);
2786                 } else
2787                     speculate(LoadFromHole, noValue(), 0, isHole);
2788                 setJSValue(result);
2789                 return;
2790             }
2791             
2792             LValue base = lowCell(m_node->child1());
2793             
2794             LBasicBlock fastCase = m_out.newBlock();
2795             LBasicBlock slowCase = m_out.newBlock();
2796             LBasicBlock continuation = m_out.newBlock();
2797             
2798             m_out.branch(
2799                 m_out.aboveOrEqual(
2800                     index, m_out.load32NonNegative(storage, m_heaps.Butterfly_publicLength)),
2801                 rarely(slowCase), usually(fastCase));
2802             
2803             LBasicBlock lastNext = m_out.appendTo(fastCase, slowCase);
2804
2805             LValue fastResultValue = m_out.load64(baseIndex(heap, storage, index, m_node->child2()));
2806             ValueFromBlock fastResult = m_out.anchor(fastResultValue);
2807             m_out.branch(
2808                 m_out.isZero64(fastResultValue), rarely(slowCase), usually(continuation));
2809             
2810             m_out.appendTo(slowCase, continuation);
2811             ValueFromBlock slowResult = m_out.anchor(
2812                 vmCall(m_out.int64, m_out.operation(operationGetByValArrayInt), m_callFrame, base, index));
2813             m_out.jump(continuation);
2814             
2815             m_out.appendTo(continuation, lastNext);
2816             setJSValue(m_out.phi(m_out.int64, fastResult, slowResult));
2817             return;
2818         }
2819             
2820         case Array::Double: {
2821             LValue index = lowInt32(m_node->child2());
2822             LValue storage = lowStorage(m_node->child3());
2823             
2824             IndexedAbstractHeap& heap = m_heaps.indexedDoubleProperties;
2825             
2826             if (m_node->arrayMode().isInBounds()) {
2827                 LValue result = m_out.loadDouble(
2828                     baseIndex(heap, storage, index, m_node->child2()));
2829                 
2830                 if (!m_node->arrayMode().isSaneChain()) {
2831                     speculate(
2832                         LoadFromHole, noValue(), 0,
2833                         m_out.doubleNotEqualOrUnordered(result, result));
2834                 }
2835                 setDouble(result);
2836                 break;
2837             }
2838             
2839             LValue base = lowCell(m_node->child1());
2840             
2841             LBasicBlock inBounds = m_out.newBlock();
2842             LBasicBlock boxPath = m_out.newBlock();
2843             LBasicBlock slowCase = m_out.newBlock();
2844             LBasicBlock continuation = m_out.newBlock();
2845             
2846             m_out.branch(
2847                 m_out.aboveOrEqual(
2848                     index, m_out.load32NonNegative(storage, m_heaps.Butterfly_publicLength)),
2849                 rarely(slowCase), usually(inBounds));
2850             
2851             LBasicBlock lastNext = m_out.appendTo(inBounds, boxPath);
2852             LValue doubleValue = m_out.loadDouble(
2853                 baseIndex(heap, storage, index, m_node->child2()));
2854             m_out.branch(
2855                 m_out.doubleNotEqualOrUnordered(doubleValue, doubleValue),
2856                 rarely(slowCase), usually(boxPath));
2857             
2858             m_out.appendTo(boxPath, slowCase);
2859             ValueFromBlock fastResult = m_out.anchor(boxDouble(doubleValue));
2860             m_out.jump(continuation);
2861             
2862             m_out.appendTo(slowCase, continuation);
2863             ValueFromBlock slowResult = m_out.anchor(
2864                 vmCall(m_out.int64, m_out.operation(operationGetByValArrayInt), m_callFrame, base, index));
2865             m_out.jump(continuation);
2866             
2867             m_out.appendTo(continuation, lastNext);
2868             setJSValue(m_out.phi(m_out.int64, fastResult, slowResult));
2869             return;
2870         }
2871
2872         case Array::Undecided: {
2873             LValue index = lowInt32(m_node->child2());
2874
2875             speculate(OutOfBounds, noValue(), m_node, m_out.lessThan(index, m_out.int32Zero));
2876             setJSValue(m_out.constInt64(ValueUndefined));
2877             return;
2878         }
2879             
2880         case Array::DirectArguments: {
2881             LValue base = lowCell(m_node->child1());
2882             LValue index = lowInt32(m_node->child2());
2883             
2884             speculate(
2885                 ExoticObjectMode, noValue(), nullptr,
2886                 m_out.notNull(m_out.loadPtr(base, m_heaps.DirectArguments_overrides)));
2887             speculate(
2888                 ExoticObjectMode, noValue(), nullptr,
2889                 m_out.aboveOrEqual(
2890                     index,
2891                     m_out.load32NonNegative(base, m_heaps.DirectArguments_length)));
2892
2893             TypedPointer address = m_out.baseIndex(
2894                 m_heaps.DirectArguments_storage, base, m_out.zeroExtPtr(index));
2895             setJSValue(m_out.load64(address));
2896             return;
2897         }
2898             
2899         case Array::ScopedArguments: {
2900             LValue base = lowCell(m_node->child1());
2901             LValue index = lowInt32(m_node->child2());
2902             
2903             speculate(
2904                 ExoticObjectMode, noValue(), nullptr,
2905                 m_out.aboveOrEqual(
2906                     index,
2907                     m_out.load32NonNegative(base, m_heaps.ScopedArguments_totalLength)));
2908             
2909             LValue table = m_out.loadPtr(base, m_heaps.ScopedArguments_table);
2910             LValue namedLength = m_out.load32(table, m_heaps.ScopedArgumentsTable_length);
2911             
2912             LBasicBlock namedCase = m_out.newBlock();
2913             LBasicBlock overflowCase = m_out.newBlock();
2914             LBasicBlock continuation = m_out.newBlock();
2915             
2916             m_out.branch(
2917                 m_out.aboveOrEqual(index, namedLength), unsure(overflowCase), unsure(namedCase));
2918             
2919             LBasicBlock lastNext = m_out.appendTo(namedCase, overflowCase);
2920             
2921             LValue scope = m_out.loadPtr(base, m_heaps.ScopedArguments_scope);
2922             LValue arguments = m_out.loadPtr(table, m_heaps.ScopedArgumentsTable_arguments);
2923             
2924             TypedPointer address = m_out.baseIndex(
2925                 m_heaps.scopedArgumentsTableArguments, arguments, m_out.zeroExtPtr(index));
2926             LValue scopeOffset = m_out.load32(address);
2927             
2928             speculate(
2929                 ExoticObjectMode, noValue(), nullptr,
2930                 m_out.equal(scopeOffset, m_out.constInt32(ScopeOffset::invalidOffset)));
2931             
2932             address = m_out.baseIndex(
2933                 m_heaps.JSEnvironmentRecord_variables, scope, m_out.zeroExtPtr(scopeOffset));
2934             ValueFromBlock namedResult = m_out.anchor(m_out.load64(address));
2935             m_out.jump(continuation);
2936             
2937             m_out.appendTo(overflowCase, continuation);
2938             
2939             address = m_out.baseIndex(
2940                 m_heaps.ScopedArguments_overflowStorage, base,
2941                 m_out.zeroExtPtr(m_out.sub(index, namedLength)));
2942             LValue overflowValue = m_out.load64(address);
2943             speculate(ExoticObjectMode, noValue(), nullptr, m_out.isZero64(overflowValue));
2944             ValueFromBlock overflowResult = m_out.anchor(overflowValue);
2945             m_out.jump(continuation);
2946             
2947             m_out.appendTo(continuation, lastNext);
2948             setJSValue(m_out.phi(m_out.int64, namedResult, overflowResult));
2949             return;
2950         }
2951             
2952         case Array::Generic: {
2953             setJSValue(vmCall(
2954                 m_out.int64, m_out.operation(operationGetByVal), m_callFrame,
2955                 lowJSValue(m_node->child1()), lowJSValue(m_node->child2())));
2956             return;
2957         }
2958             
2959         case Array::String: {
2960             compileStringCharAt();
2961             return;
2962         }
2963             
2964         default: {
2965             LValue index = lowInt32(m_node->child2());
2966             LValue storage = lowStorage(m_node->child3());
2967             
2968             TypedArrayType type = m_node->arrayMode().typedArrayType();
2969             
2970             if (isTypedView(type)) {
2971                 TypedPointer pointer = TypedPointer(
2972                     m_heaps.typedArrayProperties,
2973                     m_out.add(
2974                         storage,
2975                         m_out.shl(
2976                             m_out.zeroExtPtr(index),
2977                             m_out.constIntPtr(logElementSize(type)))));
2978                 
2979                 if (isInt(type)) {
2980                     LValue result;
2981                     switch (elementSize(type)) {
2982                     case 1:
2983                         result = isSigned(type) ? m_out.load8SignExt32(pointer) :  m_out.load8ZeroExt32(pointer);
2984                         break;
2985                     case 2:
2986                         result = isSigned(type) ? m_out.load16SignExt32(pointer) :  m_out.load16ZeroExt32(pointer);
2987                         break;
2988                     case 4:
2989                         result = m_out.load32(pointer);
2990                         break;
2991                     default:
2992                         DFG_CRASH(m_graph, m_node, "Bad element size");
2993                     }
2994                     
2995                     if (elementSize(type) < 4 || isSigned(type)) {
2996                         setInt32(result);
2997                         return;
2998                     }
2999
3000                     if (m_node->shouldSpeculateInt32()) {
3001                         speculate(
3002                             Overflow, noValue(), 0, m_out.lessThan(result, m_out.int32Zero));
3003                         setInt32(result);
3004                         return;
3005                     }
3006                     
3007                     if (m_node->shouldSpeculateAnyInt()) {
3008                         setStrictInt52(m_out.zeroExt(result, m_out.int64));
3009                         return;
3010                     }
3011                     
3012                     setDouble(m_out.unsignedToDouble(result));
3013                     return;
3014                 }
3015             
3016                 ASSERT(isFloat(type));
3017                 
3018                 LValue result;
3019                 switch (type) {
3020                 case TypeFloat32:
3021                     result = m_out.floatToDouble(m_out.loadFloat(pointer));
3022                     break;
3023                 case TypeFloat64:
3024                     result = m_out.loadDouble(pointer);
3025                     break;
3026                 default:
3027                     DFG_CRASH(m_graph, m_node, "Bad typed array type");
3028                 }
3029                 
3030                 setDouble(result);
3031                 return;
3032             }
3033             
3034             DFG_CRASH(m_graph, m_node, "Bad array type");
3035             return;
3036         } }
3037     }
3038     
3039     void compileGetMyArgumentByVal()
3040     {
3041         InlineCallFrame* inlineCallFrame = m_node->child1()->origin.semantic.inlineCallFrame;
3042         
3043         LValue index = lowInt32(m_node->child2());
3044         
3045         LValue limit;
3046         if (inlineCallFrame && !inlineCallFrame->isVarargs())
3047             limit = m_out.constInt32(inlineCallFrame->arguments.size() - 1);
3048         else {
3049             VirtualRegister argumentCountRegister;
3050             if (!inlineCallFrame)
3051                 argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
3052             else
3053                 argumentCountRegister = inlineCallFrame->argumentCountRegister;
3054             limit = m_out.sub(m_out.load32(payloadFor(argumentCountRegister)), m_out.int32One);
3055         }
3056         
3057         LValue isOutOfBounds = m_out.aboveOrEqual(index, limit);
3058         LBasicBlock continuation = nullptr;
3059         LBasicBlock lastNext = nullptr;
3060         ValueFromBlock slowResult;
3061         if (m_node->op() == GetMyArgumentByValOutOfBounds) {
3062             LBasicBlock normalCase = m_out.newBlock();
3063             continuation = m_out.newBlock();
3064             
3065             slowResult = m_out.anchor(m_out.constInt64(JSValue::encode(jsUndefined())));
3066             m_out.branch(isOutOfBounds, unsure(continuation), unsure(normalCase));
3067             
3068             lastNext = m_out.appendTo(normalCase, continuation);
3069         } else
3070             speculate(ExoticObjectMode, noValue(), 0, isOutOfBounds);
3071         
3072         TypedPointer base;
3073         if (inlineCallFrame) {
3074             if (inlineCallFrame->arguments.size() > 1)
3075                 base = addressFor(inlineCallFrame->arguments[1].virtualRegister());
3076         } else
3077             base = addressFor(virtualRegisterForArgument(1));
3078         
3079         LValue result;
3080         if (base) {
3081             LValue pointer = m_out.baseIndex(
3082                 base.value(), m_out.zeroExt(index, m_out.intPtr), ScaleEight);
3083             result = m_out.load64(TypedPointer(m_heaps.variables.atAnyIndex(), pointer));
3084         } else
3085             result = m_out.constInt64(JSValue::encode(jsUndefined()));
3086         
3087         if (m_node->op() == GetMyArgumentByValOutOfBounds) {
3088             ValueFromBlock normalResult = m_out.anchor(result);
3089             m_out.jump(continuation);
3090             
3091             m_out.appendTo(continuation, lastNext);
3092             result = m_out.phi(Int64, slowResult, normalResult);
3093         }
3094         
3095         setJSValue(result);
3096     }
3097     
3098     void compilePutByVal()
3099     {
3100         Edge child1 = m_graph.varArgChild(m_node, 0);
3101         Edge child2 = m_graph.varArgChild(m_node, 1);
3102         Edge child3 = m_graph.varArgChild(m_node, 2);
3103         Edge child4 = m_graph.varArgChild(m_node, 3);
3104         Edge child5 = m_graph.varArgChild(m_node, 4);
3105         
3106         switch (m_node->arrayMode().type()) {
3107         case Array::Generic: {
3108             V_JITOperation_EJJJ operation;
3109             if (m_node->op() == PutByValDirect) {
3110                 if (m_graph.isStrictModeFor(m_node->origin.semantic))
3111                     operation = operationPutByValDirectStrict;
3112                 else
3113                     operation = operationPutByValDirectNonStrict;
3114             } else {
3115                 if (m_graph.isStrictModeFor(m_node->origin.semantic))
3116                     operation = operationPutByValStrict;
3117                 else
3118                     operation = operationPutByValNonStrict;
3119             }
3120                 
3121             vmCall(
3122                 m_out.voidType, m_out.operation(operation), m_callFrame,
3123                 lowJSValue(child1), lowJSValue(child2), lowJSValue(child3));
3124             return;
3125         }
3126             
3127         default:
3128             break;
3129         }
3130
3131         LValue base = lowCell(child1);
3132         LValue index = lowInt32(child2);
3133         LValue storage = lowStorage(child4);
3134         
3135         switch (m_node->arrayMode().type()) {
3136         case Array::Int32:
3137         case Array::Double:
3138         case Array::Contiguous: {
3139             LBasicBlock continuation = m_out.newBlock();
3140             LBasicBlock outerLastNext = m_out.appendTo(m_out.m_block, continuation);
3141             
3142             switch (m_node->arrayMode().type()) {
3143             case Array::Int32:
3144             case Array::Contiguous: {
3145                 LValue value = lowJSValue(child3, ManualOperandSpeculation);
3146                 
3147                 if (m_node->arrayMode().type() == Array::Int32)
3148                     FTL_TYPE_CHECK(jsValueValue(value), child3, SpecInt32Only, isNotInt32(value));
3149                 
3150                 TypedPointer elementPointer = m_out.baseIndex(
3151                     m_node->arrayMode().type() == Array::Int32 ?
3152                     m_heaps.indexedInt32Properties : m_heaps.indexedContiguousProperties,
3153                     storage, m_out.zeroExtPtr(index), provenValue(child2));
3154                 
3155                 if (m_node->op() == PutByValAlias) {
3156                     m_out.store64(value, elementPointer);
3157                     break;
3158                 }
3159                 
3160                 contiguousPutByValOutOfBounds(
3161                     codeBlock()->isStrictMode()
3162                     ? operationPutByValBeyondArrayBoundsStrict
3163                     : operationPutByValBeyondArrayBoundsNonStrict,
3164                     base, storage, index, value, continuation);
3165                 
3166                 m_out.store64(value, elementPointer);
3167                 break;
3168             }
3169                 
3170             case Array::Double: {
3171                 LValue value = lowDouble(child3);
3172                 
3173                 FTL_TYPE_CHECK(
3174                     doubleValue(value), child3, SpecDoubleReal,
3175                     m_out.doubleNotEqualOrUnordered(value, value));
3176                 
3177                 TypedPointer elementPointer = m_out.baseIndex(
3178                     m_heaps.indexedDoubleProperties, storage, m_out.zeroExtPtr(index),
3179                     provenValue(child2));
3180                 
3181                 if (m_node->op() == PutByValAlias) {
3182                     m_out.storeDouble(value, elementPointer);
3183                     break;
3184                 }
3185                 
3186                 contiguousPutByValOutOfBounds(
3187                     codeBlock()->isStrictMode()
3188                     ? operationPutDoubleByValBeyondArrayBoundsStrict
3189                     : operationPutDoubleByValBeyondArrayBoundsNonStrict,
3190                     base, storage, index, value, continuation);
3191                 
3192                 m_out.storeDouble(value, elementPointer);
3193                 break;
3194             }
3195                 
3196             default:
3197                 DFG_CRASH(m_graph, m_node, "Bad array type");
3198             }
3199
3200             m_out.jump(continuation);
3201             m_out.appendTo(continuation, outerLastNext);
3202             return;
3203         }