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