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