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