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