11c67012ba05a320c113e7c4b579ad55b33b4dd0
[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 DeleteById:
710             compileDeleteById();
711             break;
712         case DeleteByVal:
713             compileDeleteByVal();
714             break;
715         case GetButterfly:
716             compileGetButterfly();
717             break;
718         case ConstantStoragePointer:
719             compileConstantStoragePointer();
720             break;
721         case GetIndexedPropertyStorage:
722             compileGetIndexedPropertyStorage();
723             break;
724         case CheckArray:
725             compileCheckArray();
726             break;
727         case GetArrayLength:
728             compileGetArrayLength();
729             break;
730         case GetVectorLength:
731             compileGetVectorLength();
732             break;
733         case CheckInBounds:
734             compileCheckInBounds();
735             break;
736         case GetByVal:
737             compileGetByVal();
738             break;
739         case GetMyArgumentByVal:
740         case GetMyArgumentByValOutOfBounds:
741             compileGetMyArgumentByVal();
742             break;
743         case GetByValWithThis:
744             compileGetByValWithThis();
745             break;
746         case PutByVal:
747         case PutByValAlias:
748         case PutByValDirect:
749             compilePutByVal();
750             break;
751         case PutByValWithThis:
752             compilePutByValWithThis();
753             break;
754         case AtomicsAdd:
755         case AtomicsAnd:
756         case AtomicsCompareExchange:
757         case AtomicsExchange:
758         case AtomicsLoad:
759         case AtomicsOr:
760         case AtomicsStore:
761         case AtomicsSub:
762         case AtomicsXor:
763             compileAtomicsReadModifyWrite();
764             break;
765         case AtomicsIsLockFree:
766             compileAtomicsIsLockFree();
767             break;
768         case DefineDataProperty:
769             compileDefineDataProperty();
770             break;
771         case DefineAccessorProperty:
772             compileDefineAccessorProperty();
773             break;
774         case ArrayPush:
775             compileArrayPush();
776             break;
777         case ArrayPop:
778             compileArrayPop();
779             break;
780         case ArraySlice:
781             compileArraySlice();
782             break;
783         case ArrayIndexOf:
784             compileArrayIndexOf();
785             break;
786         case CreateActivation:
787             compileCreateActivation();
788             break;
789         case PushWithScope:
790             compilePushWithScope();
791             break;
792         case NewFunction:
793         case NewGeneratorFunction:
794         case NewAsyncGeneratorFunction:
795         case NewAsyncFunction:
796             compileNewFunction();
797             break;
798         case CreateDirectArguments:
799             compileCreateDirectArguments();
800             break;
801         case CreateScopedArguments:
802             compileCreateScopedArguments();
803             break;
804         case CreateClonedArguments:
805             compileCreateClonedArguments();
806             break;
807         case NewObject:
808             compileNewObject();
809             break;
810         case NewStringObject:
811             compileNewStringObject();
812             break;
813         case NewArray:
814             compileNewArray();
815             break;
816         case NewArrayWithSpread:
817             compileNewArrayWithSpread();
818             break;
819         case Spread:
820             compileSpread();
821             break;
822         case NewArrayBuffer:
823             compileNewArrayBuffer();
824             break;
825         case NewArrayWithSize:
826             compileNewArrayWithSize();
827             break;
828         case NewTypedArray:
829             compileNewTypedArray();
830             break;
831         case GetTypedArrayByteOffset:
832             compileGetTypedArrayByteOffset();
833             break;
834         case GetPrototypeOf:
835             compileGetPrototypeOf();
836             break;
837         case AllocatePropertyStorage:
838             compileAllocatePropertyStorage();
839             break;
840         case ReallocatePropertyStorage:
841             compileReallocatePropertyStorage();
842             break;
843         case NukeStructureAndSetButterfly:
844             compileNukeStructureAndSetButterfly();
845             break;
846         case ToNumber:
847             compileToNumber();
848             break;
849         case ToString:
850         case CallStringConstructor:
851             compileToStringOrCallStringConstructor();
852             break;
853         case ToPrimitive:
854             compileToPrimitive();
855             break;
856         case MakeRope:
857             compileMakeRope();
858             break;
859         case StringCharAt:
860             compileStringCharAt();
861             break;
862         case StringCharCodeAt:
863             compileStringCharCodeAt();
864             break;
865         case StringFromCharCode:
866             compileStringFromCharCode();
867             break;
868         case GetByOffset:
869         case GetGetterSetterByOffset:
870             compileGetByOffset();
871             break;
872         case GetGetter:
873             compileGetGetter();
874             break;
875         case GetSetter:
876             compileGetSetter();
877             break;
878         case MultiGetByOffset:
879             compileMultiGetByOffset();
880             break;
881         case PutByOffset:
882             compilePutByOffset();
883             break;
884         case MultiPutByOffset:
885             compileMultiPutByOffset();
886             break;
887         case GetGlobalVar:
888         case GetGlobalLexicalVariable:
889             compileGetGlobalVariable();
890             break;
891         case PutGlobalVariable:
892             compilePutGlobalVariable();
893             break;
894         case NotifyWrite:
895             compileNotifyWrite();
896             break;
897         case GetCallee:
898             compileGetCallee();
899             break;
900         case GetArgumentCountIncludingThis:
901             compileGetArgumentCountIncludingThis();
902             break;
903         case GetScope:
904             compileGetScope();
905             break;
906         case SkipScope:
907             compileSkipScope();
908             break;
909         case GetGlobalObject:
910             compileGetGlobalObject();
911             break;
912         case GetGlobalThis:
913             compileGetGlobalThis();
914             break;
915         case GetClosureVar:
916             compileGetClosureVar();
917             break;
918         case PutClosureVar:
919             compilePutClosureVar();
920             break;
921         case GetFromArguments:
922             compileGetFromArguments();
923             break;
924         case PutToArguments:
925             compilePutToArguments();
926             break;
927         case GetArgument:
928             compileGetArgument();
929             break;
930         case CompareEq:
931             compileCompareEq();
932             break;
933         case CompareStrictEq:
934             compileCompareStrictEq();
935             break;
936         case CompareLess:
937             compileCompareLess();
938             break;
939         case CompareLessEq:
940             compileCompareLessEq();
941             break;
942         case CompareGreater:
943             compileCompareGreater();
944             break;
945         case CompareGreaterEq:
946             compileCompareGreaterEq();
947             break;
948         case CompareBelow:
949             compileCompareBelow();
950             break;
951         case CompareBelowEq:
952             compileCompareBelowEq();
953             break;
954         case CompareEqPtr:
955             compileCompareEqPtr();
956             break;
957         case LogicalNot:
958             compileLogicalNot();
959             break;
960         case Call:
961         case TailCallInlinedCaller:
962         case Construct:
963             compileCallOrConstruct();
964             break;
965         case DirectCall:
966         case DirectTailCallInlinedCaller:
967         case DirectConstruct:
968         case DirectTailCall:
969             compileDirectCallOrConstruct();
970             break;
971         case TailCall:
972             compileTailCall();
973             break;
974         case CallVarargs:
975         case CallForwardVarargs:
976         case TailCallVarargs:
977         case TailCallVarargsInlinedCaller:
978         case TailCallForwardVarargs:
979         case TailCallForwardVarargsInlinedCaller:
980         case ConstructVarargs:
981         case ConstructForwardVarargs:
982             compileCallOrConstructVarargs();
983             break;
984         case CallEval:
985             compileCallEval();
986             break;
987         case LoadVarargs:
988             compileLoadVarargs();
989             break;
990         case ForwardVarargs:
991             compileForwardVarargs();
992             break;
993         case DFG::Jump:
994             compileJump();
995             break;
996         case DFG::Branch:
997             compileBranch();
998             break;
999         case DFG::Switch:
1000             compileSwitch();
1001             break;
1002         case DFG::EntrySwitch:
1003             compileEntrySwitch();
1004             break;
1005         case DFG::Return:
1006             compileReturn();
1007             break;
1008         case ForceOSRExit:
1009             compileForceOSRExit();
1010             break;
1011         case CPUIntrinsic:
1012 #if CPU(X86_64)
1013             compileCPUIntrinsic();
1014 #else
1015             RELEASE_ASSERT_NOT_REACHED();
1016 #endif
1017             break;
1018         case Throw:
1019             compileThrow();
1020             break;
1021         case ThrowStaticError:
1022             compileThrowStaticError();
1023             break;
1024         case InvalidationPoint:
1025             compileInvalidationPoint();
1026             break;
1027         case IsEmpty:
1028             compileIsEmpty();
1029             break;
1030         case IsUndefined:
1031             compileIsUndefined();
1032             break;
1033         case IsBoolean:
1034             compileIsBoolean();
1035             break;
1036         case IsNumber:
1037             compileIsNumber();
1038             break;
1039         case IsCellWithType:
1040             compileIsCellWithType();
1041             break;
1042         case MapHash:
1043             compileMapHash();
1044             break;
1045         case NormalizeMapKey:
1046             compileNormalizeMapKey();
1047             break;
1048         case GetMapBucket:
1049             compileGetMapBucket();
1050             break;
1051         case GetMapBucketHead:
1052             compileGetMapBucketHead();
1053             break;
1054         case GetMapBucketNext:
1055             compileGetMapBucketNext();
1056             break;
1057         case LoadKeyFromMapBucket:
1058             compileLoadKeyFromMapBucket();
1059             break;
1060         case LoadValueFromMapBucket:
1061             compileLoadValueFromMapBucket();
1062             break;
1063         case SetAdd:
1064             compileSetAdd();
1065             break;
1066         case MapSet:
1067             compileMapSet();
1068             break;
1069         case WeakMapGet:
1070             compileWeakMapGet();
1071             break;
1072         case IsObject:
1073             compileIsObject();
1074             break;
1075         case IsObjectOrNull:
1076             compileIsObjectOrNull();
1077             break;
1078         case IsFunction:
1079             compileIsFunction();
1080             break;
1081         case IsTypedArrayView:
1082             compileIsTypedArrayView();
1083             break;
1084         case ParseInt:
1085             compileParseInt();
1086             break;
1087         case TypeOf:
1088             compileTypeOf();
1089             break;
1090         case CheckTypeInfoFlags:
1091             compileCheckTypeInfoFlags();
1092             break;
1093         case OverridesHasInstance:
1094             compileOverridesHasInstance();
1095             break;
1096         case InstanceOf:
1097             compileInstanceOf();
1098             break;
1099         case InstanceOfCustom:
1100             compileInstanceOfCustom();
1101             break;
1102         case CountExecution:
1103             compileCountExecution();
1104             break;
1105         case SuperSamplerBegin:
1106             compileSuperSamplerBegin();
1107             break;
1108         case SuperSamplerEnd:
1109             compileSuperSamplerEnd();
1110             break;
1111         case StoreBarrier:
1112         case FencedStoreBarrier:
1113             compileStoreBarrier();
1114             break;
1115         case HasIndexedProperty:
1116             compileHasIndexedProperty();
1117             break;
1118         case HasGenericProperty:
1119             compileHasGenericProperty();
1120             break;
1121         case HasStructureProperty:
1122             compileHasStructureProperty();
1123             break;
1124         case GetDirectPname:
1125             compileGetDirectPname();
1126             break;
1127         case GetEnumerableLength:
1128             compileGetEnumerableLength();
1129             break;
1130         case GetPropertyEnumerator:
1131             compileGetPropertyEnumerator();
1132             break;
1133         case GetEnumeratorStructurePname:
1134             compileGetEnumeratorStructurePname();
1135             break;
1136         case GetEnumeratorGenericPname:
1137             compileGetEnumeratorGenericPname();
1138             break;
1139         case ToIndexString:
1140             compileToIndexString();
1141             break;
1142         case CheckStructureImmediate:
1143             compileCheckStructureImmediate();
1144             break;
1145         case MaterializeNewObject:
1146             compileMaterializeNewObject();
1147             break;
1148         case MaterializeCreateActivation:
1149             compileMaterializeCreateActivation();
1150             break;
1151         case CheckTraps:
1152             if (Options::usePollingTraps())
1153                 compileCheckTraps();
1154             break;
1155         case CreateRest:
1156             compileCreateRest();
1157             break;
1158         case GetRestLength:
1159             compileGetRestLength();
1160             break;
1161         case RegExpExec:
1162             compileRegExpExec();
1163             break;
1164         case RegExpTest:
1165             compileRegExpTest();
1166             break;
1167         case NewRegexp:
1168             compileNewRegexp();
1169             break;
1170         case SetFunctionName:
1171             compileSetFunctionName();
1172             break;
1173         case StringReplace:
1174         case StringReplaceRegExp:
1175             compileStringReplace();
1176             break;
1177         case GetRegExpObjectLastIndex:
1178             compileGetRegExpObjectLastIndex();
1179             break;
1180         case SetRegExpObjectLastIndex:
1181             compileSetRegExpObjectLastIndex();
1182             break;
1183         case LogShadowChickenPrologue:
1184             compileLogShadowChickenPrologue();
1185             break;
1186         case LogShadowChickenTail:
1187             compileLogShadowChickenTail();
1188             break;
1189         case RecordRegExpCachedResult:
1190             compileRecordRegExpCachedResult();
1191             break;
1192         case ResolveScopeForHoistingFuncDeclInEval:
1193             compileResolveScopeForHoistingFuncDeclInEval();
1194             break;
1195         case ResolveScope:
1196             compileResolveScope();
1197             break;
1198         case GetDynamicVar:
1199             compileGetDynamicVar();
1200             break;
1201         case PutDynamicVar:
1202             compilePutDynamicVar();
1203             break;
1204         case Unreachable:
1205             compileUnreachable();
1206             break;
1207         case StringSlice:
1208             compileStringSlice();
1209             break;
1210         case ToLowerCase:
1211             compileToLowerCase();
1212             break;
1213         case NumberToStringWithRadix:
1214             compileNumberToStringWithRadix();
1215             break;
1216         case NumberToStringWithValidRadixConstant:
1217             compileNumberToStringWithValidRadixConstant();
1218             break;
1219         case CheckSubClass:
1220             compileCheckSubClass();
1221             break;
1222         case CallDOM:
1223             compileCallDOM();
1224             break;
1225         case CallDOMGetter:
1226             compileCallDOMGetter();
1227             break;
1228
1229         case PhantomLocal:
1230         case LoopHint:
1231         case MovHint:
1232         case ZombieHint:
1233         case ExitOK:
1234         case PhantomNewObject:
1235         case PhantomNewFunction:
1236         case PhantomNewGeneratorFunction:
1237         case PhantomNewAsyncGeneratorFunction:
1238         case PhantomNewAsyncFunction:
1239         case PhantomCreateActivation:
1240         case PhantomDirectArguments:
1241         case PhantomCreateRest:
1242         case PhantomSpread:
1243         case PhantomNewArrayWithSpread:
1244         case PhantomClonedArguments:
1245         case PutHint:
1246         case BottomValue:
1247         case KillStack:
1248         case InitializeEntrypointArguments:
1249             break;
1250         default:
1251             DFG_CRASH(m_graph, m_node, "Unrecognized node in FTL backend");
1252             break;
1253         }
1254         
1255         if (m_node->isTerminal())
1256             return false;
1257         
1258         if (!m_state.isValid()) {
1259             safelyInvalidateAfterTermination();
1260             return false;
1261         }
1262
1263         m_availabilityCalculator.executeNode(m_node);
1264         m_interpreter.executeEffects(nodeIndex);
1265         
1266         return true;
1267     }
1268
1269     void compileUpsilon()
1270     {
1271         LValue upsilonValue = nullptr;
1272         switch (m_node->child1().useKind()) {
1273         case DoubleRepUse:
1274             upsilonValue = lowDouble(m_node->child1());
1275             break;
1276         case Int32Use:
1277         case KnownInt32Use:
1278             upsilonValue = lowInt32(m_node->child1());
1279             break;
1280         case Int52RepUse:
1281             upsilonValue = lowInt52(m_node->child1());
1282             break;
1283         case BooleanUse:
1284         case KnownBooleanUse:
1285             upsilonValue = lowBoolean(m_node->child1());
1286             break;
1287         case CellUse:
1288         case KnownCellUse:
1289             upsilonValue = lowCell(m_node->child1());
1290             break;
1291         case UntypedUse:
1292             upsilonValue = lowJSValue(m_node->child1());
1293             break;
1294         default:
1295             DFG_CRASH(m_graph, m_node, "Bad use kind");
1296             break;
1297         }
1298         ValueFromBlock upsilon = m_out.anchor(upsilonValue);
1299         LValue phiNode = m_phis.get(m_node->phi());
1300         m_out.addIncomingToPhi(phiNode, upsilon);
1301     }
1302     
1303     void compilePhi()
1304     {
1305         LValue phi = m_phis.get(m_node);
1306         m_out.m_block->append(phi);
1307
1308         switch (m_node->flags() & NodeResultMask) {
1309         case NodeResultDouble:
1310             setDouble(phi);
1311             break;
1312         case NodeResultInt32:
1313             setInt32(phi);
1314             break;
1315         case NodeResultInt52:
1316             setInt52(phi);
1317             break;
1318         case NodeResultBoolean:
1319             setBoolean(phi);
1320             break;
1321         case NodeResultJS:
1322             setJSValue(phi);
1323             break;
1324         default:
1325             DFG_CRASH(m_graph, m_node, "Bad use kind");
1326             break;
1327         }
1328     }
1329     
1330     void compileDoubleConstant()
1331     {
1332         setDouble(m_out.constDouble(m_node->asNumber()));
1333     }
1334     
1335     void compileInt52Constant()
1336     {
1337         int64_t value = m_node->asAnyInt();
1338         
1339         setInt52(m_out.constInt64(value << JSValue::int52ShiftAmount));
1340         setStrictInt52(m_out.constInt64(value));
1341     }
1342
1343     void compileLazyJSConstant()
1344     {
1345         PatchpointValue* patchpoint = m_out.patchpoint(Int64);
1346         LazyJSValue value = m_node->lazyJSValue();
1347         patchpoint->setGenerator(
1348             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
1349                 value.emit(jit, JSValueRegs(params[0].gpr()));
1350             });
1351         patchpoint->effects = Effects::none();
1352         setJSValue(patchpoint);
1353     }
1354
1355     void compileDoubleRep()
1356     {
1357         switch (m_node->child1().useKind()) {
1358         case RealNumberUse: {
1359             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
1360             
1361             LValue doubleValue = unboxDouble(value);
1362             
1363             LBasicBlock intCase = m_out.newBlock();
1364             LBasicBlock continuation = m_out.newBlock();
1365             
1366             ValueFromBlock fastResult = m_out.anchor(doubleValue);
1367             m_out.branch(
1368                 m_out.doubleEqual(doubleValue, doubleValue),
1369                 usually(continuation), rarely(intCase));
1370             
1371             LBasicBlock lastNext = m_out.appendTo(intCase, continuation);
1372
1373             FTL_TYPE_CHECK(
1374                 jsValueValue(value), m_node->child1(), SpecBytecodeRealNumber,
1375                 isNotInt32(value, provenType(m_node->child1()) & ~SpecDoubleReal));
1376             ValueFromBlock slowResult = m_out.anchor(m_out.intToDouble(unboxInt32(value)));
1377             m_out.jump(continuation);
1378             
1379             m_out.appendTo(continuation, lastNext);
1380             
1381             setDouble(m_out.phi(Double, fastResult, slowResult));
1382             return;
1383         }
1384             
1385         case NotCellUse:
1386         case NumberUse: {
1387             bool shouldConvertNonNumber = m_node->child1().useKind() == NotCellUse;
1388             
1389             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
1390
1391             LBasicBlock intCase = m_out.newBlock();
1392             LBasicBlock doubleTesting = m_out.newBlock();
1393             LBasicBlock doubleCase = m_out.newBlock();
1394             LBasicBlock nonDoubleCase = m_out.newBlock();
1395             LBasicBlock continuation = m_out.newBlock();
1396             
1397             m_out.branch(
1398                 isNotInt32(value, provenType(m_node->child1())),
1399                 unsure(doubleTesting), unsure(intCase));
1400             
1401             LBasicBlock lastNext = m_out.appendTo(intCase, doubleTesting);
1402             
1403             ValueFromBlock intToDouble = m_out.anchor(
1404                 m_out.intToDouble(unboxInt32(value)));
1405             m_out.jump(continuation);
1406             
1407             m_out.appendTo(doubleTesting, doubleCase);
1408             LValue valueIsNumber = isNumber(value, provenType(m_node->child1()));
1409             m_out.branch(valueIsNumber, usually(doubleCase), rarely(nonDoubleCase));
1410
1411             m_out.appendTo(doubleCase, nonDoubleCase);
1412             ValueFromBlock unboxedDouble = m_out.anchor(unboxDouble(value));
1413             m_out.jump(continuation);
1414
1415             if (shouldConvertNonNumber) {
1416                 LBasicBlock undefinedCase = m_out.newBlock();
1417                 LBasicBlock testNullCase = m_out.newBlock();
1418                 LBasicBlock nullCase = m_out.newBlock();
1419                 LBasicBlock testBooleanTrueCase = m_out.newBlock();
1420                 LBasicBlock convertBooleanTrueCase = m_out.newBlock();
1421                 LBasicBlock convertBooleanFalseCase = m_out.newBlock();
1422
1423                 m_out.appendTo(nonDoubleCase, undefinedCase);
1424                 LValue valueIsUndefined = m_out.equal(value, m_out.constInt64(ValueUndefined));
1425                 m_out.branch(valueIsUndefined, unsure(undefinedCase), unsure(testNullCase));
1426
1427                 m_out.appendTo(undefinedCase, testNullCase);
1428                 ValueFromBlock convertedUndefined = m_out.anchor(m_out.constDouble(PNaN));
1429                 m_out.jump(continuation);
1430
1431                 m_out.appendTo(testNullCase, nullCase);
1432                 LValue valueIsNull = m_out.equal(value, m_out.constInt64(ValueNull));
1433                 m_out.branch(valueIsNull, unsure(nullCase), unsure(testBooleanTrueCase));
1434
1435                 m_out.appendTo(nullCase, testBooleanTrueCase);
1436                 ValueFromBlock convertedNull = m_out.anchor(m_out.constDouble(0));
1437                 m_out.jump(continuation);
1438
1439                 m_out.appendTo(testBooleanTrueCase, convertBooleanTrueCase);
1440                 LValue valueIsBooleanTrue = m_out.equal(value, m_out.constInt64(ValueTrue));
1441                 m_out.branch(valueIsBooleanTrue, unsure(convertBooleanTrueCase), unsure(convertBooleanFalseCase));
1442
1443                 m_out.appendTo(convertBooleanTrueCase, convertBooleanFalseCase);
1444                 ValueFromBlock convertedTrue = m_out.anchor(m_out.constDouble(1));
1445                 m_out.jump(continuation);
1446
1447                 m_out.appendTo(convertBooleanFalseCase, continuation);
1448
1449                 LValue valueIsNotBooleanFalse = m_out.notEqual(value, m_out.constInt64(ValueFalse));
1450                 FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), ~SpecCellCheck, valueIsNotBooleanFalse);
1451                 ValueFromBlock convertedFalse = m_out.anchor(m_out.constDouble(0));
1452                 m_out.jump(continuation);
1453
1454                 m_out.appendTo(continuation, lastNext);
1455                 setDouble(m_out.phi(Double, intToDouble, unboxedDouble, convertedUndefined, convertedNull, convertedTrue, convertedFalse));
1456                 return;
1457             }
1458             m_out.appendTo(nonDoubleCase, continuation);
1459             FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), SpecBytecodeNumber, m_out.booleanTrue);
1460             m_out.unreachable();
1461
1462             m_out.appendTo(continuation, lastNext);
1463
1464             setDouble(m_out.phi(Double, intToDouble, unboxedDouble));
1465             return;
1466         }
1467             
1468         case Int52RepUse: {
1469             setDouble(strictInt52ToDouble(lowStrictInt52(m_node->child1())));
1470             return;
1471         }
1472             
1473         default:
1474             DFG_CRASH(m_graph, m_node, "Bad use kind");
1475         }
1476     }
1477
1478     void compileDoubleAsInt32()
1479     {
1480         LValue integerValue = convertDoubleToInt32(lowDouble(m_node->child1()), shouldCheckNegativeZero(m_node->arithMode()));
1481         setInt32(integerValue);
1482     }
1483
1484     void compileValueRep()
1485     {
1486         switch (m_node->child1().useKind()) {
1487         case DoubleRepUse: {
1488             LValue value = lowDouble(m_node->child1());
1489             
1490             if (m_interpreter.needsTypeCheck(m_node->child1(), ~SpecDoubleImpureNaN)) {
1491                 value = m_out.select(
1492                     m_out.doubleEqual(value, value), value, m_out.constDouble(PNaN));
1493             }
1494             
1495             setJSValue(boxDouble(value));
1496             return;
1497         }
1498             
1499         case Int52RepUse: {
1500             setJSValue(strictInt52ToJSValue(lowStrictInt52(m_node->child1())));
1501             return;
1502         }
1503             
1504         default:
1505             DFG_CRASH(m_graph, m_node, "Bad use kind");
1506         }
1507     }
1508     
1509     void compileInt52Rep()
1510     {
1511         switch (m_node->child1().useKind()) {
1512         case Int32Use:
1513             setStrictInt52(m_out.signExt32To64(lowInt32(m_node->child1())));
1514             return;
1515             
1516         case AnyIntUse:
1517             setStrictInt52(
1518                 jsValueToStrictInt52(
1519                     m_node->child1(), lowJSValue(m_node->child1(), ManualOperandSpeculation)));
1520             return;
1521             
1522         case DoubleRepAnyIntUse:
1523             setStrictInt52(
1524                 doubleToStrictInt52(
1525                     m_node->child1(), lowDouble(m_node->child1())));
1526             return;
1527             
1528         default:
1529             RELEASE_ASSERT_NOT_REACHED();
1530         }
1531     }
1532     
1533     void compileValueToInt32()
1534     {
1535         switch (m_node->child1().useKind()) {
1536         case Int52RepUse:
1537             setInt32(m_out.castToInt32(lowStrictInt52(m_node->child1())));
1538             break;
1539             
1540         case DoubleRepUse:
1541             setInt32(doubleToInt32(lowDouble(m_node->child1())));
1542             break;
1543             
1544         case NumberUse:
1545         case NotCellUse: {
1546             LoweredNodeValue value = m_int32Values.get(m_node->child1().node());
1547             if (isValid(value)) {
1548                 setInt32(value.value());
1549                 break;
1550             }
1551             
1552             value = m_jsValueValues.get(m_node->child1().node());
1553             if (isValid(value)) {
1554                 setInt32(numberOrNotCellToInt32(m_node->child1(), value.value()));
1555                 break;
1556             }
1557             
1558             // We'll basically just get here for constants. But it's good to have this
1559             // catch-all since we often add new representations into the mix.
1560             setInt32(
1561                 numberOrNotCellToInt32(
1562                     m_node->child1(),
1563                     lowJSValue(m_node->child1(), ManualOperandSpeculation)));
1564             break;
1565         }
1566             
1567         default:
1568             DFG_CRASH(m_graph, m_node, "Bad use kind");
1569             break;
1570         }
1571     }
1572     
1573     void compileBooleanToNumber()
1574     {
1575         switch (m_node->child1().useKind()) {
1576         case BooleanUse: {
1577             setInt32(m_out.zeroExt(lowBoolean(m_node->child1()), Int32));
1578             return;
1579         }
1580             
1581         case UntypedUse: {
1582             LValue value = lowJSValue(m_node->child1());
1583             
1584             if (!m_interpreter.needsTypeCheck(m_node->child1(), SpecBoolInt32 | SpecBoolean)) {
1585                 setInt32(m_out.bitAnd(m_out.castToInt32(value), m_out.int32One));
1586                 return;
1587             }
1588             
1589             LBasicBlock booleanCase = m_out.newBlock();
1590             LBasicBlock continuation = m_out.newBlock();
1591             
1592             ValueFromBlock notBooleanResult = m_out.anchor(value);
1593             m_out.branch(
1594                 isBoolean(value, provenType(m_node->child1())),
1595                 unsure(booleanCase), unsure(continuation));
1596             
1597             LBasicBlock lastNext = m_out.appendTo(booleanCase, continuation);
1598             ValueFromBlock booleanResult = m_out.anchor(m_out.bitOr(
1599                 m_out.zeroExt(unboxBoolean(value), Int64), m_tagTypeNumber));
1600             m_out.jump(continuation);
1601             
1602             m_out.appendTo(continuation, lastNext);
1603             setJSValue(m_out.phi(Int64, booleanResult, notBooleanResult));
1604             return;
1605         }
1606             
1607         default:
1608             RELEASE_ASSERT_NOT_REACHED();
1609             return;
1610         }
1611     }
1612
1613     void compileExtractOSREntryLocal()
1614     {
1615         EncodedJSValue* buffer = static_cast<EncodedJSValue*>(
1616             m_ftlState.jitCode->ftlForOSREntry()->entryBuffer()->dataBuffer());
1617         setJSValue(m_out.load64(m_out.absolute(buffer + m_node->unlinkedLocal().toLocal())));
1618     }
1619
1620     void compileExtractCatchLocal()
1621     {
1622         EncodedJSValue* buffer = static_cast<EncodedJSValue*>(m_ftlState.jitCode->common.catchOSREntryBuffer->dataBuffer());
1623         setJSValue(m_out.load64(m_out.absolute(buffer + m_node->catchOSREntryIndex())));
1624     }
1625     
1626     void compileGetStack()
1627     {
1628         StackAccessData* data = m_node->stackAccessData();
1629         AbstractValue& value = m_state.variables().operand(data->local);
1630         
1631         DFG_ASSERT(m_graph, m_node, isConcrete(data->format));
1632         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.
1633         
1634         if (isInt32Speculation(value.m_type))
1635             setInt32(m_out.load32(payloadFor(data->machineLocal)));
1636         else
1637             setJSValue(m_out.load64(addressFor(data->machineLocal)));
1638     }
1639     
1640     void compilePutStack()
1641     {
1642         StackAccessData* data = m_node->stackAccessData();
1643         switch (data->format) {
1644         case FlushedJSValue: {
1645             LValue value = lowJSValue(m_node->child1());
1646             m_out.store64(value, addressFor(data->machineLocal));
1647             break;
1648         }
1649             
1650         case FlushedDouble: {
1651             LValue value = lowDouble(m_node->child1());
1652             m_out.storeDouble(value, addressFor(data->machineLocal));
1653             break;
1654         }
1655             
1656         case FlushedInt32: {
1657             LValue value = lowInt32(m_node->child1());
1658             m_out.store32(value, payloadFor(data->machineLocal));
1659             break;
1660         }
1661             
1662         case FlushedInt52: {
1663             LValue value = lowInt52(m_node->child1());
1664             m_out.store64(value, addressFor(data->machineLocal));
1665             break;
1666         }
1667             
1668         case FlushedCell: {
1669             LValue value = lowCell(m_node->child1());
1670             m_out.store64(value, addressFor(data->machineLocal));
1671             break;
1672         }
1673             
1674         case FlushedBoolean: {
1675             speculateBoolean(m_node->child1());
1676             m_out.store64(
1677                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
1678                 addressFor(data->machineLocal));
1679             break;
1680         }
1681             
1682         default:
1683             DFG_CRASH(m_graph, m_node, "Bad flush format");
1684             break;
1685         }
1686     }
1687     
1688     void compileNoOp()
1689     {
1690         DFG_NODE_DO_TO_CHILDREN(m_graph, m_node, speculate);
1691     }
1692
1693     void compileToObjectOrCallObjectConstructor()
1694     {
1695         LValue value = lowJSValue(m_node->child1());
1696
1697         LBasicBlock isCellCase = m_out.newBlock();
1698         LBasicBlock slowCase = m_out.newBlock();
1699         LBasicBlock continuation = m_out.newBlock();
1700
1701         m_out.branch(isCell(value, provenType(m_node->child1())), usually(isCellCase), rarely(slowCase));
1702
1703         LBasicBlock lastNext = m_out.appendTo(isCellCase, slowCase);
1704         ValueFromBlock fastResult = m_out.anchor(value);
1705         m_out.branch(isObject(value), usually(continuation), rarely(slowCase));
1706
1707         m_out.appendTo(slowCase, continuation);
1708
1709         ValueFromBlock slowResult;
1710         if (m_node->op() == ToObject) {
1711             auto* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
1712             slowResult = m_out.anchor(vmCall(Int64, m_out.operation(operationToObject), m_callFrame, weakPointer(globalObject), value, m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()])));
1713         } else
1714             slowResult = m_out.anchor(vmCall(Int64, m_out.operation(operationCallObjectConstructor), m_callFrame, frozenPointer(m_node->cellOperand()), value));
1715         m_out.jump(continuation);
1716
1717         m_out.appendTo(continuation, lastNext);
1718         setJSValue(m_out.phi(Int64, fastResult, slowResult));
1719     }
1720     
1721     void compileToThis()
1722     {
1723         LValue value = lowJSValue(m_node->child1());
1724         
1725         LBasicBlock isCellCase = m_out.newBlock();
1726         LBasicBlock slowCase = m_out.newBlock();
1727         LBasicBlock continuation = m_out.newBlock();
1728         
1729         m_out.branch(
1730             isCell(value, provenType(m_node->child1())), usually(isCellCase), rarely(slowCase));
1731         
1732         LBasicBlock lastNext = m_out.appendTo(isCellCase, slowCase);
1733         ValueFromBlock fastResult = m_out.anchor(value);
1734         m_out.branch(
1735             m_out.testIsZero32(
1736                 m_out.load8ZeroExt32(value, m_heaps.JSCell_typeInfoFlags),
1737                 m_out.constInt32(OverridesToThis)),
1738             usually(continuation), rarely(slowCase));
1739         
1740         m_out.appendTo(slowCase, continuation);
1741         J_JITOperation_EJ function;
1742         if (m_graph.isStrictModeFor(m_node->origin.semantic))
1743             function = operationToThisStrict;
1744         else
1745             function = operationToThis;
1746         ValueFromBlock slowResult = m_out.anchor(
1747             vmCall(Int64, m_out.operation(function), m_callFrame, value));
1748         m_out.jump(continuation);
1749         
1750         m_out.appendTo(continuation, lastNext);
1751         setJSValue(m_out.phi(Int64, fastResult, slowResult));
1752     }
1753
1754     void compileValueAdd()
1755     {
1756         ArithProfile* arithProfile = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic)->arithProfileForBytecodeOffset(m_node->origin.semantic.bytecodeIndex);
1757         JITAddIC* addIC = codeBlock()->addJITAddIC(arithProfile);
1758         auto repatchingFunction = operationValueAddOptimize;
1759         auto nonRepatchingFunction = operationValueAdd;
1760         compileMathIC(addIC, repatchingFunction, nonRepatchingFunction);
1761     }
1762
1763     template <typename Generator>
1764     void compileMathIC(JITUnaryMathIC<Generator>* mathIC, FunctionPtr repatchingFunction, FunctionPtr nonRepatchingFunction)
1765     {
1766         Node* node = m_node;
1767
1768         LValue operand = lowJSValue(node->child1());
1769
1770         PatchpointValue* patchpoint = m_out.patchpoint(Int64);
1771         patchpoint->appendSomeRegister(operand);
1772         patchpoint->append(m_tagMask, ValueRep::lateReg(GPRInfo::tagMaskRegister));
1773         patchpoint->append(m_tagTypeNumber, ValueRep::lateReg(GPRInfo::tagTypeNumberRegister));
1774         RefPtr<PatchpointExceptionHandle> exceptionHandle = preparePatchpointForExceptions(patchpoint);
1775         patchpoint->numGPScratchRegisters = 1;
1776         patchpoint->clobber(RegisterSet::macroScratchRegisters());
1777         State* state = &m_ftlState;
1778         patchpoint->setGenerator(
1779             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
1780                 AllowMacroScratchRegisterUsage allowScratch(jit);
1781
1782                 Box<CCallHelpers::JumpList> exceptions =
1783                     exceptionHandle->scheduleExitCreation(params)->jumps(jit);
1784
1785 #if ENABLE(MATH_IC_STATS)
1786                 auto inlineStart = jit.label();
1787 #endif
1788
1789                 Box<MathICGenerationState> mathICGenerationState = Box<MathICGenerationState>::create();
1790                 mathIC->m_generator = Generator(JSValueRegs(params[0].gpr()), JSValueRegs(params[1].gpr()), params.gpScratch(0));
1791
1792                 bool shouldEmitProfiling = false;
1793                 bool generatedInline = mathIC->generateInline(jit, *mathICGenerationState, shouldEmitProfiling);
1794
1795                 if (generatedInline) {
1796                     ASSERT(!mathICGenerationState->slowPathJumps.empty());
1797                     auto done = jit.label();
1798                     params.addLatePath([=] (CCallHelpers& jit) {
1799                         AllowMacroScratchRegisterUsage allowScratch(jit);
1800                         mathICGenerationState->slowPathJumps.link(&jit);
1801                         mathICGenerationState->slowPathStart = jit.label();
1802 #if ENABLE(MATH_IC_STATS)
1803                         auto slowPathStart = jit.label();
1804 #endif
1805
1806                         if (mathICGenerationState->shouldSlowPathRepatch) {
1807                             SlowPathCall call = callOperation(*state, params.unavailableRegisters(), jit, node->origin.semantic, exceptions.get(),
1808                                 repatchingFunction, params[0].gpr(), params[1].gpr(), CCallHelpers::TrustedImmPtr(mathIC));
1809                             mathICGenerationState->slowPathCall = call.call();
1810                         } else {
1811                             SlowPathCall call = callOperation(*state, params.unavailableRegisters(), jit, node->origin.semantic,
1812                                 exceptions.get(), nonRepatchingFunction, params[0].gpr(), params[1].gpr());
1813                             mathICGenerationState->slowPathCall = call.call();
1814                         }
1815                         jit.jump().linkTo(done, &jit);
1816
1817                         jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1818                             mathIC->finalizeInlineCode(*mathICGenerationState, linkBuffer);
1819                         });
1820
1821 #if ENABLE(MATH_IC_STATS)
1822                         auto slowPathEnd = jit.label();
1823                         jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1824                             size_t size = static_cast<char*>(linkBuffer.locationOf(slowPathEnd).executableAddress()) - static_cast<char*>(linkBuffer.locationOf(slowPathStart).executableAddress());
1825                             mathIC->m_generatedCodeSize += size;
1826                         });
1827 #endif
1828                     });
1829                 } else {
1830                     callOperation(
1831                         *state, params.unavailableRegisters(), jit, node->origin.semantic, exceptions.get(),
1832                         nonRepatchingFunction, params[0].gpr(), params[1].gpr());
1833                 }
1834
1835 #if ENABLE(MATH_IC_STATS)
1836                 auto inlineEnd = jit.label();
1837                 jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1838                     size_t size = static_cast<char*>(linkBuffer.locationOf(inlineEnd).executableAddress()) - static_cast<char*>(linkBuffer.locationOf(inlineStart).executableAddress());
1839                     mathIC->m_generatedCodeSize += size;
1840                 });
1841 #endif
1842             });
1843
1844         setJSValue(patchpoint);
1845     }
1846
1847     template <typename Generator>
1848     void compileMathIC(JITBinaryMathIC<Generator>* mathIC, FunctionPtr repatchingFunction, FunctionPtr nonRepatchingFunction)
1849     {
1850         Node* node = m_node;
1851         
1852         LValue left = lowJSValue(node->child1());
1853         LValue right = lowJSValue(node->child2());
1854
1855         SnippetOperand leftOperand(m_state.forNode(node->child1()).resultType());
1856         SnippetOperand rightOperand(m_state.forNode(node->child2()).resultType());
1857             
1858         PatchpointValue* patchpoint = m_out.patchpoint(Int64);
1859         patchpoint->appendSomeRegister(left);
1860         patchpoint->appendSomeRegister(right);
1861         patchpoint->append(m_tagMask, ValueRep::lateReg(GPRInfo::tagMaskRegister));
1862         patchpoint->append(m_tagTypeNumber, ValueRep::lateReg(GPRInfo::tagTypeNumberRegister));
1863         RefPtr<PatchpointExceptionHandle> exceptionHandle =
1864             preparePatchpointForExceptions(patchpoint);
1865         patchpoint->numGPScratchRegisters = 1;
1866         patchpoint->numFPScratchRegisters = 2;
1867         patchpoint->clobber(RegisterSet::macroScratchRegisters());
1868         State* state = &m_ftlState;
1869         patchpoint->setGenerator(
1870             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
1871                 AllowMacroScratchRegisterUsage allowScratch(jit);
1872
1873                 Box<CCallHelpers::JumpList> exceptions =
1874                     exceptionHandle->scheduleExitCreation(params)->jumps(jit);
1875
1876 #if ENABLE(MATH_IC_STATS)
1877                 auto inlineStart = jit.label();
1878 #endif
1879
1880                 Box<MathICGenerationState> mathICGenerationState = Box<MathICGenerationState>::create();
1881                 mathIC->m_generator = Generator(leftOperand, rightOperand, JSValueRegs(params[0].gpr()),
1882                     JSValueRegs(params[1].gpr()), JSValueRegs(params[2].gpr()), params.fpScratch(0),
1883                     params.fpScratch(1), params.gpScratch(0), InvalidFPRReg);
1884
1885                 bool shouldEmitProfiling = false;
1886                 bool generatedInline = mathIC->generateInline(jit, *mathICGenerationState, shouldEmitProfiling);
1887
1888                 if (generatedInline) {
1889                     ASSERT(!mathICGenerationState->slowPathJumps.empty());
1890                     auto done = jit.label();
1891                     params.addLatePath([=] (CCallHelpers& jit) {
1892                         AllowMacroScratchRegisterUsage allowScratch(jit);
1893                         mathICGenerationState->slowPathJumps.link(&jit);
1894                         mathICGenerationState->slowPathStart = jit.label();
1895 #if ENABLE(MATH_IC_STATS)
1896                         auto slowPathStart = jit.label();
1897 #endif
1898
1899                         if (mathICGenerationState->shouldSlowPathRepatch) {
1900                             SlowPathCall call = callOperation(*state, params.unavailableRegisters(), jit, node->origin.semantic, exceptions.get(),
1901                                 repatchingFunction, params[0].gpr(), params[1].gpr(), params[2].gpr(), CCallHelpers::TrustedImmPtr(mathIC));
1902                             mathICGenerationState->slowPathCall = call.call();
1903                         } else {
1904                             SlowPathCall call = callOperation(*state, params.unavailableRegisters(), jit, node->origin.semantic,
1905                                 exceptions.get(), nonRepatchingFunction, params[0].gpr(), params[1].gpr(), params[2].gpr());
1906                             mathICGenerationState->slowPathCall = call.call();
1907                         }
1908                         jit.jump().linkTo(done, &jit);
1909
1910                         jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1911                             mathIC->finalizeInlineCode(*mathICGenerationState, linkBuffer);
1912                         });
1913
1914 #if ENABLE(MATH_IC_STATS)
1915                         auto slowPathEnd = jit.label();
1916                         jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1917                             size_t size = static_cast<char*>(linkBuffer.locationOf(slowPathEnd).executableAddress()) - static_cast<char*>(linkBuffer.locationOf(slowPathStart).executableAddress());
1918                             mathIC->m_generatedCodeSize += size;
1919                         });
1920 #endif
1921                     });
1922                 } else {
1923                     callOperation(
1924                         *state, params.unavailableRegisters(), jit, node->origin.semantic, exceptions.get(),
1925                         nonRepatchingFunction, params[0].gpr(), params[1].gpr(), params[2].gpr());
1926                 }
1927
1928 #if ENABLE(MATH_IC_STATS)
1929                 auto inlineEnd = jit.label();
1930                 jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1931                     size_t size = static_cast<char*>(linkBuffer.locationOf(inlineEnd).executableAddress()) - static_cast<char*>(linkBuffer.locationOf(inlineStart).executableAddress());
1932                     mathIC->m_generatedCodeSize += size;
1933                 });
1934 #endif
1935             });
1936
1937         setJSValue(patchpoint);
1938     }
1939     
1940     void compileStrCat()
1941     {
1942         LValue result;
1943         if (m_node->child3()) {
1944             result = vmCall(
1945                 Int64, m_out.operation(operationStrCat3), m_callFrame,
1946                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
1947                 lowJSValue(m_node->child2(), ManualOperandSpeculation),
1948                 lowJSValue(m_node->child3(), ManualOperandSpeculation));
1949         } else {
1950             result = vmCall(
1951                 Int64, m_out.operation(operationStrCat2), m_callFrame,
1952                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
1953                 lowJSValue(m_node->child2(), ManualOperandSpeculation));
1954         }
1955         setJSValue(result);
1956     }
1957     
1958     void compileArithAddOrSub()
1959     {
1960         bool isSub =  m_node->op() == ArithSub;
1961         switch (m_node->binaryUseKind()) {
1962         case Int32Use: {
1963             LValue left = lowInt32(m_node->child1());
1964             LValue right = lowInt32(m_node->child2());
1965
1966             if (!shouldCheckOverflow(m_node->arithMode())) {
1967                 setInt32(isSub ? m_out.sub(left, right) : m_out.add(left, right));
1968                 break;
1969             }
1970
1971             CheckValue* result =
1972                 isSub ? m_out.speculateSub(left, right) : m_out.speculateAdd(left, right);
1973             blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);
1974             setInt32(result);
1975             break;
1976         }
1977             
1978         case Int52RepUse: {
1979             if (!abstractValue(m_node->child1()).couldBeType(SpecInt52Only)
1980                 && !abstractValue(m_node->child2()).couldBeType(SpecInt52Only)) {
1981                 Int52Kind kind;
1982                 LValue left = lowWhicheverInt52(m_node->child1(), kind);
1983                 LValue right = lowInt52(m_node->child2(), kind);
1984                 setInt52(isSub ? m_out.sub(left, right) : m_out.add(left, right), kind);
1985                 break;
1986             }
1987
1988             LValue left = lowInt52(m_node->child1());
1989             LValue right = lowInt52(m_node->child2());
1990             CheckValue* result =
1991                 isSub ? m_out.speculateSub(left, right) : m_out.speculateAdd(left, right);
1992             blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);
1993             setInt52(result);
1994             break;
1995         }
1996             
1997         case DoubleRepUse: {
1998             LValue C1 = lowDouble(m_node->child1());
1999             LValue C2 = lowDouble(m_node->child2());
2000
2001             setDouble(isSub ? m_out.doubleSub(C1, C2) : m_out.doubleAdd(C1, C2));
2002             break;
2003         }
2004
2005         case UntypedUse: {
2006             if (!isSub) {
2007                 DFG_CRASH(m_graph, m_node, "Bad use kind");
2008                 break;
2009             }
2010
2011             ArithProfile* arithProfile = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic)->arithProfileForBytecodeOffset(m_node->origin.semantic.bytecodeIndex);
2012             JITSubIC* subIC = codeBlock()->addJITSubIC(arithProfile);
2013             auto repatchingFunction = operationValueSubOptimize;
2014             auto nonRepatchingFunction = operationValueSub;
2015             compileMathIC(subIC, repatchingFunction, nonRepatchingFunction);
2016             break;
2017         }
2018
2019         default:
2020             DFG_CRASH(m_graph, m_node, "Bad use kind");
2021             break;
2022         }
2023     }
2024
2025     void compileArithClz32()
2026     {
2027         if (m_node->child1().useKind() == Int32Use || m_node->child1().useKind() == KnownInt32Use) {
2028             LValue operand = lowInt32(m_node->child1());
2029             setInt32(m_out.ctlz32(operand));
2030             return;
2031         }
2032         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
2033         LValue argument = lowJSValue(m_node->child1());
2034         LValue result = vmCall(Int32, m_out.operation(operationArithClz32), m_callFrame, argument);
2035         setInt32(result);
2036     }
2037     
2038     void compileArithMul()
2039     {
2040         switch (m_node->binaryUseKind()) {
2041         case Int32Use: {
2042             LValue left = lowInt32(m_node->child1());
2043             LValue right = lowInt32(m_node->child2());
2044             
2045             LValue result;
2046
2047             if (!shouldCheckOverflow(m_node->arithMode()))
2048                 result = m_out.mul(left, right);
2049             else {
2050                 CheckValue* speculation = m_out.speculateMul(left, right);
2051                 blessSpeculation(speculation, Overflow, noValue(), nullptr, m_origin);
2052                 result = speculation;
2053             }
2054             
2055             if (shouldCheckNegativeZero(m_node->arithMode())) {
2056                 LBasicBlock slowCase = m_out.newBlock();
2057                 LBasicBlock continuation = m_out.newBlock();
2058                 
2059                 m_out.branch(
2060                     m_out.notZero32(result), usually(continuation), rarely(slowCase));
2061                 
2062                 LBasicBlock lastNext = m_out.appendTo(slowCase, continuation);
2063                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(left, m_out.int32Zero));
2064                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(right, m_out.int32Zero));
2065                 m_out.jump(continuation);
2066                 m_out.appendTo(continuation, lastNext);
2067             }
2068             
2069             setInt32(result);
2070             break;
2071         }
2072             
2073         case Int52RepUse: {
2074             Int52Kind kind;
2075             LValue left = lowWhicheverInt52(m_node->child1(), kind);
2076             LValue right = lowInt52(m_node->child2(), opposite(kind));
2077
2078             CheckValue* result = m_out.speculateMul(left, right);
2079             blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);
2080
2081             if (shouldCheckNegativeZero(m_node->arithMode())) {
2082                 LBasicBlock slowCase = m_out.newBlock();
2083                 LBasicBlock continuation = m_out.newBlock();
2084                 
2085                 m_out.branch(
2086                     m_out.notZero64(result), usually(continuation), rarely(slowCase));
2087                 
2088                 LBasicBlock lastNext = m_out.appendTo(slowCase, continuation);
2089                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(left, m_out.int64Zero));
2090                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(right, m_out.int64Zero));
2091                 m_out.jump(continuation);
2092                 m_out.appendTo(continuation, lastNext);
2093             }
2094             
2095             setInt52(result);
2096             break;
2097         }
2098             
2099         case DoubleRepUse: {
2100             setDouble(
2101                 m_out.doubleMul(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
2102             break;
2103         }
2104
2105         case UntypedUse: {
2106             ArithProfile* arithProfile = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic)->arithProfileForBytecodeOffset(m_node->origin.semantic.bytecodeIndex);
2107             JITMulIC* mulIC = codeBlock()->addJITMulIC(arithProfile);
2108             auto repatchingFunction = operationValueMulOptimize;
2109             auto nonRepatchingFunction = operationValueMul;
2110             compileMathIC(mulIC, repatchingFunction, nonRepatchingFunction);
2111             break;
2112         }
2113
2114         default:
2115             DFG_CRASH(m_graph, m_node, "Bad use kind");
2116             break;
2117         }
2118     }
2119
2120     void compileArithDiv()
2121     {
2122         switch (m_node->binaryUseKind()) {
2123         case Int32Use: {
2124             LValue numerator = lowInt32(m_node->child1());
2125             LValue denominator = lowInt32(m_node->child2());
2126
2127             if (shouldCheckNegativeZero(m_node->arithMode())) {
2128                 LBasicBlock zeroNumerator = m_out.newBlock();
2129                 LBasicBlock numeratorContinuation = m_out.newBlock();
2130
2131                 m_out.branch(
2132                     m_out.isZero32(numerator),
2133                     rarely(zeroNumerator), usually(numeratorContinuation));
2134
2135                 LBasicBlock innerLastNext = m_out.appendTo(zeroNumerator, numeratorContinuation);
2136
2137                 speculate(
2138                     NegativeZero, noValue(), 0, m_out.lessThan(denominator, m_out.int32Zero));
2139
2140                 m_out.jump(numeratorContinuation);
2141
2142                 m_out.appendTo(numeratorContinuation, innerLastNext);
2143             }
2144             
2145             if (shouldCheckOverflow(m_node->arithMode())) {
2146                 LBasicBlock unsafeDenominator = m_out.newBlock();
2147                 LBasicBlock continuation = m_out.newBlock();
2148
2149                 LValue adjustedDenominator = m_out.add(denominator, m_out.int32One);
2150                 m_out.branch(
2151                     m_out.above(adjustedDenominator, m_out.int32One),
2152                     usually(continuation), rarely(unsafeDenominator));
2153
2154                 LBasicBlock lastNext = m_out.appendTo(unsafeDenominator, continuation);
2155                 LValue neg2ToThe31 = m_out.constInt32(-2147483647-1);
2156                 speculate(Overflow, noValue(), nullptr, m_out.isZero32(denominator));
2157                 speculate(Overflow, noValue(), nullptr, m_out.equal(numerator, neg2ToThe31));
2158                 m_out.jump(continuation);
2159
2160                 m_out.appendTo(continuation, lastNext);
2161                 LValue result = m_out.div(numerator, denominator);
2162                 speculate(
2163                     Overflow, noValue(), 0,
2164                     m_out.notEqual(m_out.mul(result, denominator), numerator));
2165                 setInt32(result);
2166             } else
2167                 setInt32(m_out.chillDiv(numerator, denominator));
2168
2169             break;
2170         }
2171             
2172         case DoubleRepUse: {
2173             setDouble(m_out.doubleDiv(
2174                 lowDouble(m_node->child1()), lowDouble(m_node->child2())));
2175             break;
2176         }
2177
2178         case UntypedUse: {
2179             emitBinarySnippet<JITDivGenerator, NeedScratchFPR>(operationValueDiv);
2180             break;
2181         }
2182
2183         default:
2184             DFG_CRASH(m_graph, m_node, "Bad use kind");
2185             break;
2186         }
2187     }
2188     
2189     void compileArithMod()
2190     {
2191         switch (m_node->binaryUseKind()) {
2192         case Int32Use: {
2193             LValue numerator = lowInt32(m_node->child1());
2194             LValue denominator = lowInt32(m_node->child2());
2195
2196             LValue remainder;
2197             if (shouldCheckOverflow(m_node->arithMode())) {
2198                 LBasicBlock unsafeDenominator = m_out.newBlock();
2199                 LBasicBlock continuation = m_out.newBlock();
2200
2201                 LValue adjustedDenominator = m_out.add(denominator, m_out.int32One);
2202                 m_out.branch(
2203                     m_out.above(adjustedDenominator, m_out.int32One),
2204                     usually(continuation), rarely(unsafeDenominator));
2205
2206                 LBasicBlock lastNext = m_out.appendTo(unsafeDenominator, continuation);
2207                 LValue neg2ToThe31 = m_out.constInt32(-2147483647-1);
2208                 speculate(Overflow, noValue(), nullptr, m_out.isZero32(denominator));
2209                 speculate(Overflow, noValue(), nullptr, m_out.equal(numerator, neg2ToThe31));
2210                 m_out.jump(continuation);
2211
2212                 m_out.appendTo(continuation, lastNext);
2213                 LValue result = m_out.mod(numerator, denominator);
2214                 remainder = result;
2215             } else
2216                 remainder = m_out.chillMod(numerator, denominator);
2217
2218             if (shouldCheckNegativeZero(m_node->arithMode())) {
2219                 LBasicBlock negativeNumerator = m_out.newBlock();
2220                 LBasicBlock numeratorContinuation = m_out.newBlock();
2221
2222                 m_out.branch(
2223                     m_out.lessThan(numerator, m_out.int32Zero),
2224                     unsure(negativeNumerator), unsure(numeratorContinuation));
2225
2226                 LBasicBlock innerLastNext = m_out.appendTo(negativeNumerator, numeratorContinuation);
2227
2228                 speculate(NegativeZero, noValue(), 0, m_out.isZero32(remainder));
2229
2230                 m_out.jump(numeratorContinuation);
2231
2232                 m_out.appendTo(numeratorContinuation, innerLastNext);
2233             }
2234
2235             setInt32(remainder);
2236             break;
2237         }
2238             
2239         case DoubleRepUse: {
2240             setDouble(
2241                 m_out.doubleMod(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
2242             break;
2243         }
2244             
2245         default:
2246             DFG_CRASH(m_graph, m_node, "Bad use kind");
2247             break;
2248         }
2249     }
2250
2251     void compileArithMinOrMax()
2252     {
2253         switch (m_node->binaryUseKind()) {
2254         case Int32Use: {
2255             LValue left = lowInt32(m_node->child1());
2256             LValue right = lowInt32(m_node->child2());
2257             
2258             setInt32(
2259                 m_out.select(
2260                     m_node->op() == ArithMin
2261                         ? m_out.lessThan(left, right)
2262                         : m_out.lessThan(right, left),
2263                     left, right));
2264             break;
2265         }
2266             
2267         case DoubleRepUse: {
2268             LValue left = lowDouble(m_node->child1());
2269             LValue right = lowDouble(m_node->child2());
2270             
2271             LBasicBlock notLessThan = m_out.newBlock();
2272             LBasicBlock continuation = m_out.newBlock();
2273             
2274             Vector<ValueFromBlock, 2> results;
2275             
2276             results.append(m_out.anchor(left));
2277             m_out.branch(
2278                 m_node->op() == ArithMin
2279                     ? m_out.doubleLessThan(left, right)
2280                     : m_out.doubleGreaterThan(left, right),
2281                 unsure(continuation), unsure(notLessThan));
2282             
2283             LBasicBlock lastNext = m_out.appendTo(notLessThan, continuation);
2284             results.append(m_out.anchor(m_out.select(
2285                 m_node->op() == ArithMin
2286                     ? m_out.doubleGreaterThanOrEqual(left, right)
2287                     : m_out.doubleLessThanOrEqual(left, right),
2288                 right, m_out.constDouble(PNaN))));
2289             m_out.jump(continuation);
2290             
2291             m_out.appendTo(continuation, lastNext);
2292             setDouble(m_out.phi(Double, results));
2293             break;
2294         }
2295             
2296         default:
2297             DFG_CRASH(m_graph, m_node, "Bad use kind");
2298             break;
2299         }
2300     }
2301     
2302     void compileArithAbs()
2303     {
2304         switch (m_node->child1().useKind()) {
2305         case Int32Use: {
2306             LValue value = lowInt32(m_node->child1());
2307
2308             LValue mask = m_out.aShr(value, m_out.constInt32(31));
2309             LValue result = m_out.bitXor(mask, m_out.add(mask, value));
2310
2311             if (shouldCheckOverflow(m_node->arithMode()))
2312                 speculate(Overflow, noValue(), 0, m_out.lessThan(result, m_out.int32Zero));
2313
2314             setInt32(result);
2315             break;
2316         }
2317             
2318         case DoubleRepUse: {
2319             setDouble(m_out.doubleAbs(lowDouble(m_node->child1())));
2320             break;
2321         }
2322             
2323         default: {
2324             DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
2325             LValue argument = lowJSValue(m_node->child1());
2326             LValue result = vmCall(Double, m_out.operation(operationArithAbs), m_callFrame, argument);
2327             setDouble(result);
2328             break;
2329         }
2330         }
2331     }
2332
2333     void compileArithUnary()
2334     {
2335         if (m_node->child1().useKind() == DoubleRepUse) {
2336             setDouble(m_out.doubleUnary(m_node->arithUnaryType(), lowDouble(m_node->child1())));
2337             return;
2338         }
2339         LValue argument = lowJSValue(m_node->child1());
2340         LValue result = vmCall(Double, m_out.operation(DFG::arithUnaryOperation(m_node->arithUnaryType())), m_callFrame, argument);
2341         setDouble(result);
2342     }
2343
2344     void compileArithPow()
2345     {
2346         if (m_node->child2().useKind() == Int32Use)
2347             setDouble(m_out.doublePowi(lowDouble(m_node->child1()), lowInt32(m_node->child2())));
2348         else {
2349             LValue base = lowDouble(m_node->child1());
2350             LValue exponent = lowDouble(m_node->child2());
2351
2352             LBasicBlock integerExponentIsSmallBlock = m_out.newBlock();
2353             LBasicBlock integerExponentPowBlock = m_out.newBlock();
2354             LBasicBlock doubleExponentPowBlockEntry = m_out.newBlock();
2355             LBasicBlock nanExceptionBaseIsOne = m_out.newBlock();
2356             LBasicBlock nanExceptionExponentIsInfinity = m_out.newBlock();
2357             LBasicBlock testExponentIsOneHalf = m_out.newBlock();
2358             LBasicBlock handleBaseZeroExponentIsOneHalf = m_out.newBlock();
2359             LBasicBlock handleInfinityForExponentIsOneHalf = m_out.newBlock();
2360             LBasicBlock exponentIsOneHalfNormal = m_out.newBlock();
2361             LBasicBlock exponentIsOneHalfInfinity = m_out.newBlock();
2362             LBasicBlock testExponentIsNegativeOneHalf = m_out.newBlock();
2363             LBasicBlock testBaseZeroExponentIsNegativeOneHalf = m_out.newBlock();
2364             LBasicBlock handleBaseZeroExponentIsNegativeOneHalf = m_out.newBlock();
2365             LBasicBlock handleInfinityForExponentIsNegativeOneHalf = m_out.newBlock();
2366             LBasicBlock exponentIsNegativeOneHalfNormal = m_out.newBlock();
2367             LBasicBlock exponentIsNegativeOneHalfInfinity = m_out.newBlock();
2368             LBasicBlock powBlock = m_out.newBlock();
2369             LBasicBlock nanExceptionResultIsNaN = m_out.newBlock();
2370             LBasicBlock continuation = m_out.newBlock();
2371
2372             LValue integerExponent = m_out.doubleToInt(exponent);
2373             LValue integerExponentConvertedToDouble = m_out.intToDouble(integerExponent);
2374             LValue exponentIsInteger = m_out.doubleEqual(exponent, integerExponentConvertedToDouble);
2375             m_out.branch(exponentIsInteger, unsure(integerExponentIsSmallBlock), unsure(doubleExponentPowBlockEntry));
2376
2377             LBasicBlock lastNext = m_out.appendTo(integerExponentIsSmallBlock, integerExponentPowBlock);
2378             LValue integerExponentBelowMax = m_out.belowOrEqual(integerExponent, m_out.constInt32(maxExponentForIntegerMathPow));
2379             m_out.branch(integerExponentBelowMax, usually(integerExponentPowBlock), rarely(doubleExponentPowBlockEntry));
2380
2381             m_out.appendTo(integerExponentPowBlock, doubleExponentPowBlockEntry);
2382             ValueFromBlock powDoubleIntResult = m_out.anchor(m_out.doublePowi(base, integerExponent));
2383             m_out.jump(continuation);
2384
2385             // If y is NaN, the result is NaN.
2386             m_out.appendTo(doubleExponentPowBlockEntry, nanExceptionBaseIsOne);
2387             LValue exponentIsNaN;
2388             if (provenType(m_node->child2()) & SpecDoubleNaN)
2389                 exponentIsNaN = m_out.doubleNotEqualOrUnordered(exponent, exponent);
2390             else
2391                 exponentIsNaN = m_out.booleanFalse;
2392             m_out.branch(exponentIsNaN, rarely(nanExceptionResultIsNaN), usually(nanExceptionBaseIsOne));
2393
2394             // If abs(x) is 1 and y is +infinity, the result is NaN.
2395             // If abs(x) is 1 and y is -infinity, the result is NaN.
2396
2397             //     Test if base == 1.
2398             m_out.appendTo(nanExceptionBaseIsOne, nanExceptionExponentIsInfinity);
2399             LValue absoluteBase = m_out.doubleAbs(base);
2400             LValue absoluteBaseIsOne = m_out.doubleEqual(absoluteBase, m_out.constDouble(1));
2401             m_out.branch(absoluteBaseIsOne, rarely(nanExceptionExponentIsInfinity), usually(testExponentIsOneHalf));
2402
2403             //     Test if abs(y) == Infinity.
2404             m_out.appendTo(nanExceptionExponentIsInfinity, testExponentIsOneHalf);
2405             LValue absoluteExponent = m_out.doubleAbs(exponent);
2406             LValue absoluteExponentIsInfinity = m_out.doubleEqual(absoluteExponent, m_out.constDouble(std::numeric_limits<double>::infinity()));
2407             m_out.branch(absoluteExponentIsInfinity, rarely(nanExceptionResultIsNaN), usually(testExponentIsOneHalf));
2408
2409             // If y == 0.5 or y == -0.5, handle it through SQRT.
2410             // We have be carefuly with -0 and -Infinity.
2411
2412             //     Test if y == 0.5
2413             m_out.appendTo(testExponentIsOneHalf, handleBaseZeroExponentIsOneHalf);
2414             LValue exponentIsOneHalf = m_out.doubleEqual(exponent, m_out.constDouble(0.5));
2415             m_out.branch(exponentIsOneHalf, rarely(handleBaseZeroExponentIsOneHalf), usually(testExponentIsNegativeOneHalf));
2416
2417             //     Handle x == -0.
2418             m_out.appendTo(handleBaseZeroExponentIsOneHalf, handleInfinityForExponentIsOneHalf);
2419             LValue baseIsZeroExponentIsOneHalf = m_out.doubleEqual(base, m_out.doubleZero);
2420             ValueFromBlock zeroResultExponentIsOneHalf = m_out.anchor(m_out.doubleZero);
2421             m_out.branch(baseIsZeroExponentIsOneHalf, rarely(continuation), usually(handleInfinityForExponentIsOneHalf));
2422
2423             //     Test if abs(x) == Infinity.
2424             m_out.appendTo(handleInfinityForExponentIsOneHalf, exponentIsOneHalfNormal);
2425             LValue absoluteBaseIsInfinityOneHalf = m_out.doubleEqual(absoluteBase, m_out.constDouble(std::numeric_limits<double>::infinity()));
2426             m_out.branch(absoluteBaseIsInfinityOneHalf, rarely(exponentIsOneHalfInfinity), usually(exponentIsOneHalfNormal));
2427
2428             //     The exponent is 0.5, the base is finite or NaN, we can use SQRT.
2429             m_out.appendTo(exponentIsOneHalfNormal, exponentIsOneHalfInfinity);
2430             ValueFromBlock sqrtResult = m_out.anchor(m_out.doubleSqrt(base));
2431             m_out.jump(continuation);
2432
2433             //     The exponent is 0.5, the base is infinite, the result is always infinite.
2434             m_out.appendTo(exponentIsOneHalfInfinity, testExponentIsNegativeOneHalf);
2435             ValueFromBlock sqrtInfinityResult = m_out.anchor(m_out.constDouble(std::numeric_limits<double>::infinity()));
2436             m_out.jump(continuation);
2437
2438             //     Test if y == -0.5
2439             m_out.appendTo(testExponentIsNegativeOneHalf, testBaseZeroExponentIsNegativeOneHalf);
2440             LValue exponentIsNegativeOneHalf = m_out.doubleEqual(exponent, m_out.constDouble(-0.5));
2441             m_out.branch(exponentIsNegativeOneHalf, rarely(testBaseZeroExponentIsNegativeOneHalf), usually(powBlock));
2442
2443             //     Handle x == -0.
2444             m_out.appendTo(testBaseZeroExponentIsNegativeOneHalf, handleBaseZeroExponentIsNegativeOneHalf);
2445             LValue baseIsZeroExponentIsNegativeOneHalf = m_out.doubleEqual(base, m_out.doubleZero);
2446             m_out.branch(baseIsZeroExponentIsNegativeOneHalf, rarely(handleBaseZeroExponentIsNegativeOneHalf), usually(handleInfinityForExponentIsNegativeOneHalf));
2447
2448             m_out.appendTo(handleBaseZeroExponentIsNegativeOneHalf, handleInfinityForExponentIsNegativeOneHalf);
2449             ValueFromBlock oneOverSqrtZeroResult = m_out.anchor(m_out.constDouble(std::numeric_limits<double>::infinity()));
2450             m_out.jump(continuation);
2451
2452             //     Test if abs(x) == Infinity.
2453             m_out.appendTo(handleInfinityForExponentIsNegativeOneHalf, exponentIsNegativeOneHalfNormal);
2454             LValue absoluteBaseIsInfinityNegativeOneHalf = m_out.doubleEqual(absoluteBase, m_out.constDouble(std::numeric_limits<double>::infinity()));
2455             m_out.branch(absoluteBaseIsInfinityNegativeOneHalf, rarely(exponentIsNegativeOneHalfInfinity), usually(exponentIsNegativeOneHalfNormal));
2456
2457             //     The exponent is -0.5, the base is finite or NaN, we can use 1/SQRT.
2458             m_out.appendTo(exponentIsNegativeOneHalfNormal, exponentIsNegativeOneHalfInfinity);
2459             LValue sqrtBase = m_out.doubleSqrt(base);
2460             ValueFromBlock oneOverSqrtResult = m_out.anchor(m_out.div(m_out.constDouble(1.), sqrtBase));
2461             m_out.jump(continuation);
2462
2463             //     The exponent is -0.5, the base is infinite, the result is always zero.
2464             m_out.appendTo(exponentIsNegativeOneHalfInfinity, powBlock);
2465             ValueFromBlock oneOverSqrtInfinityResult = m_out.anchor(m_out.doubleZero);
2466             m_out.jump(continuation);
2467
2468             m_out.appendTo(powBlock, nanExceptionResultIsNaN);
2469             ValueFromBlock powResult = m_out.anchor(m_out.doublePow(base, exponent));
2470             m_out.jump(continuation);
2471
2472             m_out.appendTo(nanExceptionResultIsNaN, continuation);
2473             ValueFromBlock pureNan = m_out.anchor(m_out.constDouble(PNaN));
2474             m_out.jump(continuation);
2475
2476             m_out.appendTo(continuation, lastNext);
2477             setDouble(m_out.phi(Double, powDoubleIntResult, zeroResultExponentIsOneHalf, sqrtResult, sqrtInfinityResult, oneOverSqrtZeroResult, oneOverSqrtResult, oneOverSqrtInfinityResult, powResult, pureNan));
2478         }
2479     }
2480
2481     void compileArithRandom()
2482     {
2483         JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
2484
2485         // Inlined WeakRandom::advance().
2486         // uint64_t x = m_low;
2487         void* lowAddress = reinterpret_cast<uint8_t*>(globalObject) + JSGlobalObject::weakRandomOffset() + WeakRandom::lowOffset();
2488         LValue low = m_out.load64(m_out.absolute(lowAddress));
2489         // uint64_t y = m_high;
2490         void* highAddress = reinterpret_cast<uint8_t*>(globalObject) + JSGlobalObject::weakRandomOffset() + WeakRandom::highOffset();
2491         LValue high = m_out.load64(m_out.absolute(highAddress));
2492         // m_low = y;
2493         m_out.store64(high, m_out.absolute(lowAddress));
2494
2495         // x ^= x << 23;
2496         LValue phase1 = m_out.bitXor(m_out.shl(low, m_out.constInt64(23)), low);
2497
2498         // x ^= x >> 17;
2499         LValue phase2 = m_out.bitXor(m_out.lShr(phase1, m_out.constInt64(17)), phase1);
2500
2501         // x ^= y ^ (y >> 26);
2502         LValue phase3 = m_out.bitXor(m_out.bitXor(high, m_out.lShr(high, m_out.constInt64(26))), phase2);
2503
2504         // m_high = x;
2505         m_out.store64(phase3, m_out.absolute(highAddress));
2506
2507         // return x + y;
2508         LValue random64 = m_out.add(phase3, high);
2509
2510         // Extract random 53bit. [0, 53] bit is safe integer number ranges in double representation.
2511         LValue random53 = m_out.bitAnd(random64, m_out.constInt64((1ULL << 53) - 1));
2512
2513         LValue double53Integer = m_out.intToDouble(random53);
2514
2515         // Convert `(53bit double integer value) / (1 << 53)` to `(53bit double integer value) * (1.0 / (1 << 53))`.
2516         // In latter case, `1.0 / (1 << 53)` will become a double value represented as (mantissa = 0 & exp = 970, it means 1e-(2**54)).
2517         static const double scale = 1.0 / (1ULL << 53);
2518
2519         // Multiplying 1e-(2**54) with the double integer does not change anything of the mantissa part of the double integer.
2520         // It just reduces the exp part of the given 53bit double integer.
2521         // (Except for 0.0. This is specially handled and in this case, exp just becomes 0.)
2522         // Now we get 53bit precision random double value in [0, 1).
2523         LValue result = m_out.doubleMul(double53Integer, m_out.constDouble(scale));
2524
2525         setDouble(result);
2526     }
2527
2528     void compileArithRound()
2529     {
2530         if (m_node->child1().useKind() == DoubleRepUse) {
2531             LValue result = nullptr;
2532             if (producesInteger(m_node->arithRoundingMode()) && !shouldCheckNegativeZero(m_node->arithRoundingMode())) {
2533                 LValue value = lowDouble(m_node->child1());
2534                 result = m_out.doubleFloor(m_out.doubleAdd(value, m_out.constDouble(0.5)));
2535             } else {
2536                 LBasicBlock realPartIsMoreThanHalf = m_out.newBlock();
2537                 LBasicBlock continuation = m_out.newBlock();
2538
2539                 LValue value = lowDouble(m_node->child1());
2540                 LValue integerValue = m_out.doubleCeil(value);
2541                 ValueFromBlock integerValueResult = m_out.anchor(integerValue);
2542
2543                 LValue realPart = m_out.doubleSub(integerValue, value);
2544
2545                 m_out.branch(m_out.doubleGreaterThanOrUnordered(realPart, m_out.constDouble(0.5)), unsure(realPartIsMoreThanHalf), unsure(continuation));
2546
2547                 LBasicBlock lastNext = m_out.appendTo(realPartIsMoreThanHalf, continuation);
2548                 LValue integerValueRoundedDown = m_out.doubleSub(integerValue, m_out.constDouble(1));
2549                 ValueFromBlock integerValueRoundedDownResult = m_out.anchor(integerValueRoundedDown);
2550                 m_out.jump(continuation);
2551                 m_out.appendTo(continuation, lastNext);
2552
2553                 result = m_out.phi(Double, integerValueResult, integerValueRoundedDownResult);
2554             }
2555
2556             if (producesInteger(m_node->arithRoundingMode())) {
2557                 LValue integerValue = convertDoubleToInt32(result, shouldCheckNegativeZero(m_node->arithRoundingMode()));
2558                 setInt32(integerValue);
2559             } else
2560                 setDouble(result);
2561             return;
2562         }
2563
2564         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
2565         LValue argument = lowJSValue(m_node->child1());
2566         setJSValue(vmCall(Int64, m_out.operation(operationArithRound), m_callFrame, argument));
2567     }
2568
2569     void compileArithFloor()
2570     {
2571         if (m_node->child1().useKind() == DoubleRepUse) {
2572             LValue value = lowDouble(m_node->child1());
2573             LValue integerValue = m_out.doubleFloor(value);
2574             if (producesInteger(m_node->arithRoundingMode()))
2575                 setInt32(convertDoubleToInt32(integerValue, shouldCheckNegativeZero(m_node->arithRoundingMode())));
2576             else
2577                 setDouble(integerValue);
2578             return;
2579         }
2580         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
2581         LValue argument = lowJSValue(m_node->child1());
2582         setJSValue(vmCall(Int64, m_out.operation(operationArithFloor), m_callFrame, argument));
2583     }
2584
2585     void compileArithCeil()
2586     {
2587         if (m_node->child1().useKind() == DoubleRepUse) {
2588             LValue value = lowDouble(m_node->child1());
2589             LValue integerValue = m_out.doubleCeil(value);
2590             if (producesInteger(m_node->arithRoundingMode()))
2591                 setInt32(convertDoubleToInt32(integerValue, shouldCheckNegativeZero(m_node->arithRoundingMode())));
2592             else
2593                 setDouble(integerValue);
2594             return;
2595         }
2596         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
2597         LValue argument = lowJSValue(m_node->child1());
2598         setJSValue(vmCall(Int64, m_out.operation(operationArithCeil), m_callFrame, argument));
2599     }
2600
2601     void compileArithTrunc()
2602     {
2603         if (m_node->child1().useKind() == DoubleRepUse) {
2604             LValue value = lowDouble(m_node->child1());
2605             LValue result = m_out.doubleTrunc(value);
2606             if (producesInteger(m_node->arithRoundingMode()))
2607                 setInt32(convertDoubleToInt32(result, shouldCheckNegativeZero(m_node->arithRoundingMode())));
2608             else
2609                 setDouble(result);
2610             return;
2611         }
2612         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
2613         LValue argument = lowJSValue(m_node->child1());
2614         setJSValue(vmCall(Int64, m_out.operation(operationArithTrunc), m_callFrame, argument));
2615     }
2616
2617     void compileArithSqrt()
2618     {
2619         if (m_node->child1().useKind() == DoubleRepUse) {
2620             setDouble(m_out.doubleSqrt(lowDouble(m_node->child1())));
2621             return;
2622         }
2623         LValue argument = lowJSValue(m_node->child1());
2624         LValue result = vmCall(Double, m_out.operation(operationArithSqrt), m_callFrame, argument);
2625         setDouble(result);
2626     }
2627
2628     void compileArithFRound()
2629     {
2630         if (m_node->child1().useKind() == DoubleRepUse) {
2631             setDouble(m_out.fround(lowDouble(m_node->child1())));
2632             return;
2633         }
2634         LValue argument = lowJSValue(m_node->child1());
2635         LValue result = vmCall(Double, m_out.operation(operationArithFRound), m_callFrame, argument);
2636         setDouble(result);
2637     }
2638     
2639     void compileArithNegate()
2640     {
2641         switch (m_node->child1().useKind()) {
2642         case Int32Use: {
2643             LValue value = lowInt32(m_node->child1());
2644             
2645             LValue result;
2646             if (!shouldCheckOverflow(m_node->arithMode()))
2647                 result = m_out.neg(value);
2648             else if (!shouldCheckNegativeZero(m_node->arithMode())) {
2649                 CheckValue* check = m_out.speculateSub(m_out.int32Zero, value);
2650                 blessSpeculation(check, Overflow, noValue(), nullptr, m_origin);
2651                 result = check;
2652             } else {
2653                 speculate(Overflow, noValue(), 0, m_out.testIsZero32(value, m_out.constInt32(0x7fffffff)));
2654                 result = m_out.neg(value);
2655             }
2656
2657             setInt32(result);
2658             break;
2659         }
2660             
2661         case Int52RepUse: {
2662             if (!abstractValue(m_node->child1()).couldBeType(SpecInt52Only)) {
2663                 Int52Kind kind;
2664                 LValue value = lowWhicheverInt52(m_node->child1(), kind);
2665                 LValue result = m_out.neg(value);
2666                 if (shouldCheckNegativeZero(m_node->arithMode()))
2667                     speculate(NegativeZero, noValue(), 0, m_out.isZero64(result));
2668                 setInt52(result, kind);
2669                 break;
2670             }
2671             
2672             LValue value = lowInt52(m_node->child1());
2673             CheckValue* result = m_out.speculateSub(m_out.int64Zero, value);
2674             blessSpeculation(result, Int52Overflow, noValue(), nullptr, m_origin);
2675             if (shouldCheckNegativeZero(m_node->arithMode()))
2676                 speculate(NegativeZero, noValue(), 0, m_out.isZero64(result));
2677             setInt52(result);
2678             break;
2679         }
2680             
2681         case DoubleRepUse: {
2682             setDouble(m_out.doubleNeg(lowDouble(m_node->child1())));
2683             break;
2684         }
2685             
2686         default:
2687             DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
2688             ArithProfile* arithProfile = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic)->arithProfileForBytecodeOffset(m_node->origin.semantic.bytecodeIndex);
2689             JITNegIC* negIC = codeBlock()->addJITNegIC(arithProfile);
2690             auto repatchingFunction = operationArithNegateOptimize;
2691             auto nonRepatchingFunction = operationArithNegate;
2692             compileMathIC(negIC, repatchingFunction, nonRepatchingFunction);
2693             break;
2694         }
2695     }
2696     
2697     void compileBitAnd()
2698     {
2699         if (m_node->isBinaryUseKind(UntypedUse)) {
2700             emitBinaryBitOpSnippet<JITBitAndGenerator>(operationValueBitAnd);
2701             return;
2702         }
2703         setInt32(m_out.bitAnd(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2704     }
2705     
2706     void compileBitOr()
2707     {
2708         if (m_node->isBinaryUseKind(UntypedUse)) {
2709             emitBinaryBitOpSnippet<JITBitOrGenerator>(operationValueBitOr);
2710             return;
2711         }
2712         setInt32(m_out.bitOr(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2713     }
2714     
2715     void compileBitXor()
2716     {
2717         if (m_node->isBinaryUseKind(UntypedUse)) {
2718             emitBinaryBitOpSnippet<JITBitXorGenerator>(operationValueBitXor);
2719             return;
2720         }
2721         setInt32(m_out.bitXor(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2722     }
2723     
2724     void compileBitRShift()
2725     {
2726         if (m_node->isBinaryUseKind(UntypedUse)) {
2727             emitRightShiftSnippet(JITRightShiftGenerator::SignedShift);
2728             return;
2729         }
2730         setInt32(m_out.aShr(
2731             lowInt32(m_node->child1()),
2732             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2733     }
2734     
2735     void compileBitLShift()
2736     {
2737         if (m_node->isBinaryUseKind(UntypedUse)) {
2738             emitBinaryBitOpSnippet<JITLeftShiftGenerator>(operationValueBitLShift);
2739             return;
2740         }
2741         setInt32(m_out.shl(
2742             lowInt32(m_node->child1()),
2743             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2744     }
2745     
2746     void compileBitURShift()
2747     {
2748         if (m_node->isBinaryUseKind(UntypedUse)) {
2749             emitRightShiftSnippet(JITRightShiftGenerator::UnsignedShift);
2750             return;
2751         }
2752         setInt32(m_out.lShr(
2753             lowInt32(m_node->child1()),
2754             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2755     }
2756     
2757     void compileUInt32ToNumber()
2758     {
2759         LValue value = lowInt32(m_node->child1());
2760
2761         if (doesOverflow(m_node->arithMode())) {
2762             setStrictInt52(m_out.zeroExtPtr(value));
2763             return;
2764         }
2765
2766         speculate(Overflow, noValue(), 0, m_out.lessThan(value, m_out.int32Zero));
2767         setInt32(value);
2768     }
2769     
2770     void compileCheckStructure()
2771     {
2772         ExitKind exitKind;
2773         if (m_node->child1()->hasConstant())
2774             exitKind = BadConstantCache;
2775         else
2776             exitKind = BadCache;
2777
2778         switch (m_node->child1().useKind()) {
2779         case CellUse:
2780         case KnownCellUse: {
2781             LValue cell = lowCell(m_node->child1());
2782             
2783             checkStructure(
2784                 m_out.load32(cell, m_heaps.JSCell_structureID), jsValueValue(cell),
2785                 exitKind, m_node->structureSet(),
2786                 [&] (RegisteredStructure structure) {
2787                     return weakStructureID(structure);
2788                 });
2789             return;
2790         }
2791
2792         case CellOrOtherUse: {
2793             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
2794
2795             LBasicBlock cellCase = m_out.newBlock();
2796             LBasicBlock notCellCase = m_out.newBlock();
2797             LBasicBlock continuation = m_out.newBlock();
2798
2799             m_out.branch(
2800                 isCell(value, provenType(m_node->child1())), unsure(cellCase), unsure(notCellCase));
2801
2802             LBasicBlock lastNext = m_out.appendTo(cellCase, notCellCase);
2803             checkStructure(
2804                 m_out.load32(value, m_heaps.JSCell_structureID), jsValueValue(value),
2805                 exitKind, m_node->structureSet(),
2806                 [&] (RegisteredStructure structure) {
2807                     return weakStructureID(structure);
2808                 });
2809             m_out.jump(continuation);
2810
2811             m_out.appendTo(notCellCase, continuation);
2812             FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), SpecCell | SpecOther, isNotOther(value));
2813             m_out.jump(continuation);
2814
2815             m_out.appendTo(continuation, lastNext);
2816             return;
2817         }
2818
2819         default:
2820             DFG_CRASH(m_graph, m_node, "Bad use kind");
2821             return;
2822         }
2823     }
2824
2825     void compileCheckStructureOrEmpty()
2826     {
2827         ExitKind exitKind;
2828         if (m_node->child1()->hasConstant())
2829             exitKind = BadConstantCache;
2830         else
2831             exitKind = BadCache;
2832
2833         LValue cell = lowCell(m_node->child1());
2834         bool maySeeEmptyValue = m_interpreter.forNode(m_node->child1()).m_type & SpecEmpty;
2835         LBasicBlock notEmpty;
2836         LBasicBlock continuation;
2837         LBasicBlock lastNext;
2838         if (maySeeEmptyValue) {
2839             notEmpty = m_out.newBlock();
2840             continuation = m_out.newBlock();
2841             m_out.branch(m_out.isZero64(cell), unsure(continuation), unsure(notEmpty));
2842             lastNext = m_out.appendTo(notEmpty, continuation);
2843         }
2844
2845         checkStructure(
2846             m_out.load32(cell, m_heaps.JSCell_structureID), jsValueValue(cell),
2847             exitKind, m_node->structureSet(),
2848             [&] (RegisteredStructure structure) {
2849                 return weakStructureID(structure);
2850             });
2851
2852         if (maySeeEmptyValue) {
2853             m_out.jump(continuation);
2854             m_out.appendTo(continuation, lastNext);
2855         }
2856     }
2857     
2858     void compileCheckCell()
2859     {
2860         LValue cell = lowCell(m_node->child1());
2861         
2862         speculate(
2863             BadCell, jsValueValue(cell), m_node->child1().node(),
2864             m_out.notEqual(cell, weakPointer(m_node->cellOperand()->cell())));
2865     }
2866     
2867     void compileCheckBadCell()
2868     {
2869         terminate(BadCell);
2870     }
2871
2872     void compileCheckNotEmpty()
2873     {
2874         speculate(TDZFailure, noValue(), nullptr, m_out.isZero64(lowJSValue(m_node->child1())));
2875     }
2876
2877     void compileCheckStringIdent()
2878     {
2879         UniquedStringImpl* uid = m_node->uidOperand();
2880         LValue stringImpl = lowStringIdent(m_node->child1());
2881         speculate(BadIdent, noValue(), nullptr, m_out.notEqual(stringImpl, m_out.constIntPtr(uid)));
2882     }
2883
2884     void compileGetExecutable()
2885     {
2886         LValue cell = lowCell(m_node->child1());
2887         speculateFunction(m_node->child1(), cell);
2888         setJSValue(m_out.loadPtr(cell, m_heaps.JSFunction_executable));
2889     }
2890     
2891     void compileArrayify()
2892     {
2893         LValue cell = lowCell(m_node->child1());
2894         LValue property = !!m_node->child2() ? lowInt32(m_node->child2()) : 0;
2895         
2896         LBasicBlock unexpectedStructure = m_out.newBlock();
2897         LBasicBlock continuation = m_out.newBlock();
2898         
2899         auto isUnexpectedArray = [&] (LValue cell) {
2900             if (m_node->op() == Arrayify)
2901                 return m_out.logicalNot(isArrayTypeForArrayify(cell, m_node->arrayMode()));
2902
2903             ASSERT(m_node->op() == ArrayifyToStructure);
2904             return m_out.notEqual(m_out.load32(cell, m_heaps.JSCell_structureID), weakStructureID(m_node->structure()));
2905         };
2906
2907         m_out.branch(isUnexpectedArray(cell), rarely(unexpectedStructure), usually(continuation));
2908
2909         LBasicBlock lastNext = m_out.appendTo(unexpectedStructure, continuation);
2910         
2911         if (property) {
2912             switch (m_node->arrayMode().type()) {
2913             case Array::Int32:
2914             case Array::Double:
2915             case Array::Contiguous:
2916                 speculate(
2917                     Uncountable, noValue(), 0,
2918                     m_out.aboveOrEqual(property, m_out.constInt32(MIN_SPARSE_ARRAY_INDEX)));
2919                 break;
2920             default:
2921                 break;
2922             }
2923         }
2924         
2925         switch (m_node->arrayMode().type()) {
2926         case Array::Int32:
2927             vmCall(Void, m_out.operation(operationEnsureInt32), m_callFrame, cell);
2928             break;
2929         case Array::Double:
2930             vmCall(Void, m_out.operation(operationEnsureDouble), m_callFrame, cell);
2931             break;
2932         case Array::Contiguous:
2933             vmCall(Void, m_out.operation(operationEnsureContiguous), m_callFrame, cell);
2934             break;
2935         case Array::ArrayStorage:
2936         case Array::SlowPutArrayStorage:
2937             vmCall(Void, m_out.operation(operationEnsureArrayStorage), m_callFrame, cell);
2938             break;
2939         default:
2940             DFG_CRASH(m_graph, m_node, "Bad array type");
2941             break;
2942         }
2943         
2944         speculate(BadIndexingType, jsValueValue(cell), 0, isUnexpectedArray(cell));
2945         m_out.jump(continuation);
2946         
2947         m_out.appendTo(continuation, lastNext);
2948     }
2949     
2950     void compilePutStructure()
2951     {
2952         m_ftlState.jitCode->common.notifyCompilingStructureTransition(m_graph.m_plan, codeBlock(), m_node);
2953         
2954         RegisteredStructure oldStructure = m_node->transition()->previous;
2955         RegisteredStructure newStructure = m_node->transition()->next;
2956         ASSERT_UNUSED(oldStructure, oldStructure->indexingType() == newStructure->indexingType());
2957         ASSERT(oldStructure->typeInfo().inlineTypeFlags() == newStructure->typeInfo().inlineTypeFlags());
2958         ASSERT(oldStructure->typeInfo().type() == newStructure->typeInfo().type());
2959
2960         LValue cell = lowCell(m_node->child1()); 
2961         m_out.store32(
2962             weakStructureID(newStructure),
2963             cell, m_heaps.JSCell_structureID);
2964     }
2965     
2966     void compileGetById(AccessType type)
2967     {
2968         ASSERT(type == AccessType::Get || type == AccessType::TryGet);
2969         switch (m_node->child1().useKind()) {
2970         case CellUse: {
2971             setJSValue(getById(lowCell(m_node->child1()), type));
2972             return;
2973         }
2974             
2975         case UntypedUse: {
2976             // This is pretty weird, since we duplicate the slow path both here and in the
2977             // code generated by the IC. We should investigate making this less bad.
2978             // https://bugs.webkit.org/show_bug.cgi?id=127830
2979             LValue value = lowJSValue(m_node->child1());
2980             
2981             LBasicBlock cellCase = m_out.newBlock();
2982             LBasicBlock notCellCase = m_out.newBlock();
2983             LBasicBlock continuation = m_out.newBlock();
2984             
2985             m_out.branch(
2986                 isCell(value, provenType(m_node->child1())), unsure(cellCase), unsure(notCellCase));
2987             
2988             LBasicBlock lastNext = m_out.appendTo(cellCase, notCellCase);
2989             ValueFromBlock cellResult = m_out.anchor(getById(value, type));
2990             m_out.jump(continuation);
2991
2992             J_JITOperation_EJI getByIdFunction;
2993             if (type == AccessType::Get)
2994                 getByIdFunction = operationGetByIdGeneric;
2995             else
2996                 getByIdFunction = operationTryGetByIdGeneric;
2997
2998             m_out.appendTo(notCellCase, continuation);
2999             ValueFromBlock notCellResult = m_out.anchor(vmCall(
3000                 Int64, m_out.operation(getByIdFunction),
3001                 m_callFrame, value,
3002                 m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()])));
3003             m_out.jump(continuation);
3004             
3005             m_out.appendTo(continuation, lastNext);
3006             setJSValue(m_out.phi(Int64, cellResult, notCellResult));
3007             return;
3008         }
3009             
3010         default:
3011             DFG_CRASH(m_graph, m_node, "Bad use kind");
3012             return;
3013         }
3014     }
3015
3016     void compileGetByIdWithThis()
3017     {
3018         if (m_node->child1().useKind() == CellUse && m_node->child2().useKind() == CellUse)
3019             setJSValue(getByIdWithThis(lowCell(m_node->child1()), lowCell(m_node->child2())));
3020         else {
3021             LValue base = lowJSValue(m_node->child1());
3022             LValue thisValue = lowJSValue(m_node->child2());
3023             
3024             LBasicBlock baseCellCase = m_out.newBlock();
3025             LBasicBlock notCellCase = m_out.newBlock();
3026             LBasicBlock thisValueCellCase = m_out.newBlock();
3027             LBasicBlock continuation = m_out.newBlock();
3028             
3029             m_out.branch(
3030                 isCell(base, provenType(m_node->child1())), unsure(baseCellCase), unsure(notCellCase));
3031             
3032             LBasicBlock lastNext = m_out.appendTo(baseCellCase, thisValueCellCase);
3033             
3034             m_out.branch(
3035                 isCell(thisValue, provenType(m_node->child2())), unsure(thisValueCellCase), unsure(notCellCase));
3036             
3037             m_out.appendTo(thisValueCellCase, notCellCase);
3038             ValueFromBlock cellResult = m_out.anchor(getByIdWithThis(base, thisValue));
3039             m_out.jump(continuation);
3040
3041             m_out.appendTo(notCellCase, continuation);
3042             ValueFromBlock notCellResult = m_out.anchor(vmCall(
3043                 Int64, m_out.operation(operationGetByIdWithThis),
3044                 m_callFrame, base, thisValue,
3045                 m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()])));
3046             m_out.jump(continuation);
3047             
3048             m_out.appendTo(continuation, lastNext);
3049             setJSValue(m_out.phi(Int64, cellResult, notCellResult));
3050         }
3051         
3052     }
3053
3054     void compileGetByValWithThis()
3055     {
3056         LValue base = lowJSValue(m_node->child1());
3057         LValue thisValue = lowJSValue(m_node->child2());
3058         LValue subscript = lowJSValue(m_node->child3());
3059
3060         LValue result = vmCall(Int64, m_out.operation(operationGetByValWithThis), m_callFrame, base, thisValue, subscript);
3061         setJSValue(result);
3062     }
3063
3064     void compilePutByIdWithThis()
3065     {
3066         LValue base = lowJSValue(m_node->child1());
3067         LValue thisValue = lowJSValue(m_node->child2());
3068         LValue value = lowJSValue(m_node->child3());
3069
3070         vmCall(Void, m_out.operation(m_graph.isStrictModeFor(m_node->origin.semantic) ? operationPutByIdWithThisStrict : operationPutByIdWithThis),
3071             m_callFrame, base, thisValue, value, m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()]));
3072     }
3073
3074     void compilePutByValWithThis()
3075     {
3076         LValue base = lowJSValue(m_graph.varArgChild(m_node, 0));
3077         LValue thisValue = lowJSValue(m_graph.varArgChild(m_node, 1));
3078         LValue property = lowJSValue(m_graph.varArgChild(m_node, 2));
3079         LValue value = lowJSValue(m_graph.varArgChild(m_node, 3));
3080
3081         vmCall(Void, m_out.operation(m_graph.isStrictModeFor(m_node->origin.semantic) ? operationPutByValWithThisStrict : operationPutByValWithThis),
3082             m_callFrame, base, thisValue, property, value);
3083     }
3084     
3085     void compileAtomicsReadModifyWrite()
3086     {
3087         TypedArrayType type = m_node->arrayMode().typedArrayType();
3088         unsigned numExtraArgs = numExtraAtomicsArgs(m_node->op());
3089         Edge baseEdge = m_graph.child(m_node, 0);
3090         Edge indexEdge = m_graph.child(m_node, 1);
3091         Edge argEdges[maxNumExtraAtomicsArgs];
3092         for (unsigned i = numExtraArgs; i--;)
3093             argEdges[i] = m_graph.child(m_node, 2 + i);
3094         Edge storageEdge = m_graph.child(m_node, 2 + numExtraArgs);
3095         
3096         auto operation = [&] () -> LValue {
3097             switch (m_node->op()) {
3098             case AtomicsAdd:
3099                 return m_out.operation(operationAtomicsAdd);
3100             case AtomicsAnd:
3101                 return m_out.operation(operationAtomicsAnd);
3102             case AtomicsCompareExchange:
3103                 return m_out.operation(operationAtomicsCompareExchange);
3104             case AtomicsExchange:
3105                 return m_out.operation(operationAtomicsExchange);
3106             case AtomicsLoad:
3107                 return m_out.operation(operationAtomicsLoad);
3108             case AtomicsOr:
3109                 return m_out.operation(operationAtomicsOr);
3110             case AtomicsStore:
3111                 return m_out.operation(operationAtomicsStore);
3112             case AtomicsSub:
3113                 return m_out.operation(operationAtomicsSub);
3114             case AtomicsXor:
3115                 return m_out.operation(operationAtomicsXor);
3116             default:
3117                 RELEASE_ASSERT_NOT_REACHED();
3118                 break;
3119             }
3120         };
3121         
3122         if (!storageEdge) {
3123             Vector<LValue> args;
3124             args.append(m_callFrame);
3125             args.append(lowJSValue(baseEdge));
3126             args.append(lowJSValue(indexEdge));
3127             for (unsigned i = 0; i < numExtraArgs; ++i)
3128                 args.append(lowJSValue(argEdges[i]));
3129             LValue result = vmCall(Int64, operation(), args);
3130             setJSValue(result);
3131             return;
3132         }
3133         
3134         LValue index = lowInt32(indexEdge);
3135         LValue args[2];
3136         for (unsigned i = numExtraArgs; i--;)
3137             args[i] = getIntTypedArrayStoreOperand(argEdges[i]);
3138         LValue storage = lowStorage(storageEdge);
3139         
3140         TypedPointer pointer = pointerIntoTypedArray(storage, index, type);
3141         Width width = widthForBytes(elementSize(type));
3142         
3143         LValue atomicValue;
3144         LValue result;
3145         
3146         auto sanitizeResult = [&] (LValue value) -> LValue {
3147             if (isSigned(type)) {
3148                 switch (elementSize(type)) {
3149                 case 1:
3150                     value = m_out.bitAnd(value, m_out.constInt32(0xff));
3151                     break;
3152                 case 2:
3153                     value = m_out.bitAnd(value, m_out.constInt32(0xffff));
3154                     break;
3155                 case 4:
3156                     break;
3157                 default:
3158                     RELEASE_ASSERT_NOT_REACHED();
3159                     break;
3160                 }
3161             }
3162             return value;
3163         };
3164         
3165         switch (m_node->op()) {
3166         case AtomicsAdd:
3167             atomicValue = m_out.atomicXchgAdd(args[0], pointer, width);
3168             result = sanitizeResult(atomicValue);
3169             break;
3170         case AtomicsAnd:
3171             atomicValue = m_out.atomicXchgAnd(args[0], pointer, width);
3172             result = sanitizeResult(atomicValue);
3173             break;
3174         case AtomicsCompareExchange:
3175             atomicValue = m_out.atomicStrongCAS(args[0], args[1], pointer, width);
3176             result = sanitizeResult(atomicValue);
3177             break;
3178         case AtomicsExchange:
3179             atomicValue = m_out.atomicXchg(args[0], pointer, width);
3180             result = sanitizeResult(atomicValue);
3181             break;
3182         case AtomicsLoad:
3183             atomicValue = m_out.atomicXchgAdd(m_out.int32Zero, pointer, width);
3184             result = sanitizeResult(atomicValue);
3185             break;
3186         case AtomicsOr:
3187             atomicValue = m_out.atomicXchgOr(args[0], pointer, width);
3188             result = sanitizeResult(atomicValue);
3189             break;
3190         case AtomicsStore:
3191             atomicValue = m_out.atomicXchg(args[0], pointer, width);
3192             result = args[0];
3193             break;
3194         case AtomicsSub:
3195             atomicValue = m_out.atomicXchgSub(args[0], pointer, width);
3196             result = sanitizeResult(atomicValue);
3197             break;
3198         case AtomicsXor:
3199             atomicValue = m_out.atomicXchgXor(args[0], pointer, width);
3200             result = sanitizeResult(atomicValue);
3201             break;
3202         default:
3203             RELEASE_ASSERT_NOT_REACHED();
3204             break;
3205         }
3206         // Signify that the state against which the atomic operations are serialized is confined to just
3207         // the typed array storage, since that's as precise of an abstraction as we can have of shared
3208         // array buffer storage.
3209         m_heaps.decorateFencedAccess(&m_heaps.typedArrayProperties, atomicValue);
3210         
3211         setIntTypedArrayLoadResult(result, type);
3212     }
3213     
3214     void compileAtomicsIsLockFree()
3215     {
3216         if (m_node->child1().useKind() != Int32Use) {
3217             setJSValue(vmCall(Int64, m_out.operation(operationAtomicsIsLockFree), m_callFrame, lowJSValue(m_node->child1())));
3218             return;
3219         }
3220         
3221         LValue bytes = lowInt32(m_node->child1());
3222         
3223         LBasicBlock trueCase = m_out.newBlock();
3224         LBasicBlock falseCase = m_out.newBlock();
3225         LBasicBlock continuation = m_out.newBlock();
3226         
3227         LBasicBlock lastNext = m_out.insertNewBlocksBefore(trueCase);
3228         
3229         Vector<SwitchCase> cases;
3230         cases.append(SwitchCase(m_out.constInt32(1), trueCase, Weight()));
3231         cases.append(SwitchCase(m_out.constInt32(2), trueCase, Weight()));
3232         cases.append(SwitchCase(m_out.constInt32(4), trueCase, Weight()));
3233         m_out.switchInstruction(bytes, cases, falseCase, Weight());
3234         
3235         m_out.appendTo(trueCase, falseCase);
3236         ValueFromBlock trueValue = m_out.anchor(m_out.booleanTrue);
3237         m_out.jump(continuation);
3238         m_out.appendTo(falseCase, continuation);
3239         ValueFromBlock falseValue = m_out.anchor(m_out.booleanFalse);
3240         m_out.jump(continuation);
3241         
3242         m_out.appendTo(continuation, lastNext);
3243         setBoolean(m_out.phi(Int32, trueValue, falseValue));
3244     }
3245
3246     void compileDefineDataProperty()
3247     {
3248         LValue base = lowCell(m_graph.varArgChild(m_node, 0));
3249         LValue value  = lowJSValue(m_graph.varArgChild(m_node, 2));
3250         LValue attributes = lowInt32(m_graph.varArgChild(m_node, 3));
3251         Edge& propertyEdge = m_graph.varArgChild(m_node, 1);
3252         switch (propertyEdge.useKind()) {
3253         case StringUse: {
3254             LValue property = lowString(propertyEdge);
3255             vmCall(Void, m_out.operation(operationDefineDataPropertyString), m_callFrame, base, property, value, attributes);
3256             break;
3257         }
3258         case StringIdentUse: {
3259             LValue property = lowStringIdent(propertyEdge);
3260             vmCall(Void, m_out.operation(operationDefineDataPropertyStringIdent), m_callFrame, base, property, value, attributes);
3261             break;
3262         }
3263         case SymbolUse: {
3264             LValue property = lowSymbol(propertyEdge);
3265             vmCall(Void, m_out.operation(operationDefineDataPropertySymbol), m_callFrame, base, property, value, attributes);
3266             break;
3267         }
3268         case UntypedUse: {
3269             LValue property = lowJSValue(propertyEdge);
3270             vmCall(Void, m_out.operation(operationDefineDataProperty), m_callFrame, base, property, value, attributes);
3271             break;
3272         }
3273         default:
3274             RELEASE_ASSERT_NOT_REACHED();
3275         }
3276     }
3277
3278     void compileDefineAccessorProperty()
3279     {
3280         LValue base = lowCell(m_graph.varArgChild(m_node, 0));
3281         LValue getter = lowCell(m_graph.varArgChild(m_node, 2));
3282         LValue setter = lowCell(m_graph.varArgChild(m_node, 3));
3283         LValue attributes = lowInt32(m_graph.varArgChild(m_node, 4));
3284         Edge& propertyEdge = m_graph.varArgChild(m_node, 1);
3285         switch (propertyEdge.useKind()) {
3286         case StringUse: {
3287             LValue property = lowString(propertyEdge);
3288             vmCall(Void, m_out.operation(operationDefineAccessorPropertyString), m_callFrame, base, property, getter, setter, attributes);
3289             break;
3290         }
3291         case StringIdentUse: {
3292             LValue property = lowStringIdent(propertyEdge);
3293             vmCall(Void, m_out.operation(operationDefineAccessorPropertyStringIdent), m_callFrame, base, property, getter, setter, attributes);
3294             break;
3295         }
3296         case SymbolUse: {
3297             LValue property = lowSymbol(propertyEdge);
3298             vmCall(Void, m_out.operation(operationDefineAccessorPropertySymbol), m_callFrame, base, property, getter, setter, attributes);
3299             break;
3300         }
3301         case UntypedUse: {
3302             LValue property = lowJSValue(propertyEdge);
3303             vmCall(Void, m_out.operation(operationDefineAccessorProperty), m_callFrame, base, property, getter, setter, attributes);
3304             break;
3305         }
3306         default:
3307             RELEASE_ASSERT_NOT_REACHED();
3308         }
3309     }
3310     
3311     void compilePutById()
3312     {
3313         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == CellUse);
3314
3315         Node* node = m_node;
3316         LValue base = lowCell(node->child1());
3317         LValue value = lowJSValue(node->child2());
3318         auto uid = m_graph.identifiers()[node->identifierNumber()];
3319
3320         B3::PatchpointValue* patchpoint = m_out.patchpoint(Void);
3321         patchpoint->appendSomeRegister(base);
3322         patchpoint->appendSomeRegister(value);
3323         patchpoint->append(m_tagMask, ValueRep::reg(GPRInfo::tagMaskRegister));
3324         patchpoint->append(m_tagTypeNumber, ValueRep::reg(GPRInfo::tagTypeNumberRegister));
3325         patchpoint->clobber(RegisterSet::macroScratchRegisters());
3326
3327         // FIXME: If this is a PutByIdFlush, we might want to late-clobber volatile registers.
3328         // https://bugs.webkit.org/show_bug.cgi?id=152848
3329
3330         RefPtr<PatchpointExceptionHandle> exceptionHandle =
3331             preparePatchpointForExceptions(patchpoint);
3332
3333         State* state = &m_ftlState;
3334         ECMAMode ecmaMode = m_graph.executableFor(node->origin.semantic)->ecmaMode();
3335         
3336         patchpoint->setGenerator(
3337             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
3338                 AllowMacroScratchRegisterUsage allowScratch(jit);
3339
3340                 CallSiteIndex callSiteIndex =
3341                     state->jitCode->common.addUniqueCallSiteIndex(node->origin.semantic);
3342
3343                 Box<CCallHelpers::JumpList> exceptions =
3344                     exceptionHandle->scheduleExitCreation(params)->jumps(jit);
3345
3346                 // JS setter call ICs generated by the PutById IC will need this.
3347                 exceptionHandle->scheduleExitCreationForUnwind(params, callSiteIndex);
3348
3349                 auto generator = Box<JITPutByIdGenerator>::create(
3350                     jit.codeBlock(), node->origin.semantic, callSiteIndex,
3351                     params.unavailableRegisters(), JSValueRegs(params[0].gpr()),
3352                     JSValueRegs(params[1].gpr()), GPRInfo::patchpointScratchRegister, ecmaMode,
3353                     node->op() == PutByIdDirect ? Direct : NotDirect);
3354
3355                 generator->generateFastPath(jit);
3356                 CCallHelpers::Label done = jit.label();
3357
3358                 params.addLatePath(
3359                     [=] (CCallHelpers& jit) {
3360                         AllowMacroScratchRegisterUsage allowScratch(jit);
3361
3362                         generator->slowPathJump().link(&jit);
3363                         CCallHelpers::Label slowPathBegin = jit.label();
3364                         CCallHelpers::Call slowPathCall = callOperation(
3365                             *state, params.unavailableRegisters(), jit, node->origin.semantic,
3366                             exceptions.get(), generator->slowPathFunction(), InvalidGPRReg,
3367                             CCallHelpers::TrustedImmPtr(generator->stubInfo()), params[1].gpr(),
3368                             params[0].gpr(), CCallHelpers::TrustedImmPtr(uid)).call();
3369                         jit.jump().linkTo(done, &jit);
3370
3371                         generator->reportSlowPathCall(slowPathBegin, slowPathCall);
3372
3373                         jit.addLinkTask(
3374                             [=] (LinkBuffer& linkBuffer) {
3375                                 generator->finalize(linkBuffer);
3376                             });
3377                     });
3378             });
3379     }
3380     
3381     void compileGetButterfly()
3382     {
3383         LValue butterfly = m_out.loadPtr(lowCell(m_node->child1()), m_heaps.JSObject_butterfly);
3384         setStorage(butterfly);
3385     }
3386
3387     void compileConstantStoragePointer()
3388     {
3389         setStorage(m_out.constIntPtr(m_node->storagePointer()));
3390     }
3391     
3392     void compileGetIndexedPropertyStorage()
3393     {
3394         LValue cell = lowCell(m_node->child1());
3395         
3396         if (m_node->arrayMode().type() == Array::String) {
3397             LBasicBlock slowPath = m_out.newBlock();
3398             LBasicBlock continuation = m_out.newBlock();
3399
3400             LValue fastResultValue = m_out.loadPtr(cell, m_heaps.JSString_value);
3401             ValueFromBlock fastResult = m_out.anchor(fastResultValue);
3402             
3403             m_out.branch(
3404                 m_out.notNull(fastResultValue), usually(continuation), rarely(slowPath));
3405             
3406             LBasicBlock lastNext = m_out.appendTo(slowPath, continuation);
3407             
3408             ValueFromBlock slowResult = m_out.anchor(
3409                 vmCall(pointerType(), m_out.operation(operationResolveRope), m_callFrame, cell));
3410             
3411             m_out.jump(continuation);
3412             
3413             m_out.appendTo(continuation, lastNext);
3414             
3415             setStorage(m_out.loadPtr(m_out.phi(pointerType(), fastResult, slowResult), m_heaps.StringImpl_data));
3416             return;
3417         }
3418
3419         DFG_ASSERT(m_graph, m_node, isTypedView(m_node->arrayMode().typedArrayType()));
3420         setStorage(caged(Gigacage::Primitive, m_out.loadPtr(cell, m_heaps.JSArrayBufferView_vector)));
3421     }
3422     
3423     void compileCheckArray()
3424     {
3425         Edge edge = m_node->child1();
3426         LValue cell = lowCell(edge);
3427         
3428         if (m_node->arrayMode().alreadyChecked(m_graph, m_node, abstractValue(edge)))
3429             return;
3430         
3431         speculate(
3432             BadIndexingType, jsValueValue(cell), 0,
3433             m_out.logicalNot(isArrayTypeForCheckArray(cell, m_node->arrayMode())));
3434     }
3435
3436     void compileGetTypedArrayByteOffset()
3437     {
3438         LValue basePtr = lowCell(m_node->child1());    
3439
3440         LBasicBlock simpleCase = m_out.newBlock();
3441         LBasicBlock wastefulCase = m_out.newBlock();
3442         LBasicBlock continuation = m_out.newBlock();
3443         
3444         LValue mode = m_out.load32(basePtr, m_heaps.JSArrayBufferView_mode);
3445         m_out.branch(
3446             m_out.notEqual(mode, m_out.constInt32(WastefulTypedArray)),
3447             unsure(simpleCase), unsure(wastefulCase));
3448
3449         LBasicBlock lastNext = m_out.appendTo(simpleCase, wastefulCase);
3450
3451         ValueFromBlock simpleOut = m_out.anchor(m_out.constIntPtr(0));
3452
3453         m_out.jump(continuation);
3454
3455         m_out.appendTo(wastefulCase, continuation);
3456
3457         LValue vectorPtr = cagedMayBeNull(
3458             Gigacage::Primitive,
3459             m_out.loadPtr(basePtr, m_heaps.JSArrayBufferView_vector));
3460         LValue butterflyPtr = caged(Gigacage::JSValue, m_out.loadPtr(basePtr, m_heaps.JSObject_butterfly));
3461         LValue arrayBufferPtr = m_out.loadPtr(butterflyPtr, m_heaps.Butterfly_arrayBuffer);
3462         // FIXME: This needs caging.
3463         // https://bugs.webkit.org/show_bug.cgi?id=175515
3464         LValue dataPtr = m_out.loadPtr(arrayBufferPtr, m_heaps.ArrayBuffer_data);
3465
3466         ValueFromBlock wastefulOut = m_out.anchor(m_out.sub(vectorPtr, dataPtr));
3467
3468         m_out.jump(continuation);
3469         m_out.appendTo(continuation, lastNext);
3470
3471         setInt32(m_out.castToInt32(m_out.phi(pointerType(), simpleOut, wastefulOut)));
3472     }
3473
3474     void compileGetPrototypeOf()
3475     {
3476         switch (m_node->child1().useKind()) {
3477         case ArrayUse:
3478         case FunctionUse:
3479         case FinalObjectUse: {
3480             LValue object = lowCell(m_node->child1());
3481             switch (m_node->child1().useKind()) {
3482             case ArrayUse:
3483                 speculateArray(m_node->child1(), object);
3484                 break;
3485             case FunctionUse:
3486                 speculateFunction(m_node->child1(), object);
3487                 break;
3488             case FinalObjectUse:
3489                 speculateFinalObject(m_node->child1(), object);
3490                 break;
3491             default:
3492                 RELEASE_ASSERT_NOT_REACHED();
3493                 break;
3494             }
3495
3496             LValue structure = loadStructure(object);
3497
3498             AbstractValue& value = m_state.forNode(m_node->child1());
3499             if ((value.m_type && !(value.m_type & ~SpecObject)) && value.m_structure.isFinite()) {
3500                 bool hasPolyProto = false;
3501                 bool hasMonoProto = false;
3502                 value.m_structure.forEach([&] (RegisteredStructure structure) {
3503                     if (structure->hasPolyProto())
3504                         hasPolyProto = true;
3505                     else
3506                         hasMonoProto = true;
3507                 });
3508
3509                 if (hasMonoProto && !hasPolyProto) {
3510                     setJSValue(m_out.load64(structure, m_heaps.Structure_prototype));
3511                     return;
3512                 }
3513
3514                 if (hasPolyProto && !hasMonoProto) {
3515                     setJSValue(m_out.load64(m_out.baseIndex(m_heaps.properties.atAnyNumber(), object, m_out.constInt64(knownPolyProtoOffset), ScaleEight, JSObject::offsetOfInlineStorage())));
3516                     return;
3517                 }
3518             }
3519
3520             LBasicBlock continuation = m_out.newBlock();
3521             LBasicBlock loadPolyProto = m_out.newBlock();
3522
3523             LValue prototypeBits = m_out.load64(structure, m_heaps.Structure_prototype);
3524             ValueFromBlock directPrototype = m_out.anchor(prototypeBits);
3525             m_out.branch(m_out.isZero64(prototypeBits), unsure(loadPolyProto), unsure(continuation));
3526
3527             LBasicBlock lastNext = m_out.appendTo(loadPolyProto, continuation);
3528             ValueFromBlock polyProto = m_out.anchor(
3529                 m_out.load64(m_out.baseIndex(m_heaps.properties.atAnyNumber(), object, m_out.constInt64(knownPolyProtoOffset), ScaleEight, JSObject::offsetOfInlineStorage())));
3530             m_out.jump(continuation);
3531
3532             m_out.appendTo(continuation, lastNext);
3533             setJSValue(m_out.phi(Int64, directPrototype, polyProto));
3534             return;
3535         }
3536         case ObjectUse: {
3537             setJSValue(vmCall(Int64, m_out.operation(operationGetPrototypeOfObject), m_callFrame, lowObject(m_node->child1())));
3538             return;
3539         }
3540         default: {
3541             setJSValue(vmCall(Int64, m_out.operation(operationGetPrototypeOf), m_callFrame, lowJSValue(m_node->child1())));
3542             return;
3543         }
3544         }
3545     }
3546     
3547     void compileGetArrayLength()
3548     {
3549         switch (m_node->arrayMode().type()) {
3550         case Array::Undecided:
3551         case Array::Int32:
3552         case Array::Double:
3553         case Array::Contiguous: {
3554             setInt32(m_out.load32NonNegative(lowStorage(m_node->child2()), m_heaps.Butterfly_publicLength));
3555             return;
3556         }
3557             
3558         case Array::String: {
3559             LValue string = lowCell(m_node->child1());
3560             setInt32(m_out.load32NonNegative(string, m_heaps.JSString_length));
3561             return;
3562         }
3563             
3564         case Array::DirectArguments: {
3565             LValue arguments = lowCell(m_node->child1());
3566             speculate(
3567                 ExoticObjectMode, noValue(), nullptr,
3568                 m_out.notNull(m_out.loadPtr(arguments, m_heaps.DirectArguments_mappedArguments)));
3569             setInt32(m_out.load32NonNegative(arguments, m_heaps.DirectArguments_length));
3570             return;
3571         }
3572             
3573         case Array::ScopedArguments: {
3574             LValue arguments = lowCell(m_node->child1());
3575             speculate(
3576                 ExoticObjectMode, noValue(), nullptr,
3577                 m_out.notZero32(m_out.load8ZeroExt32(arguments, m_heaps.ScopedArguments_overrodeThings)));
3578             setInt32(m_out.load32NonNegative(arguments, m_heaps.ScopedArguments_totalLength));
3579             return;
3580         }
3581             
3582         default:
3583             if (m_node->arrayMode().isSomeTypedArrayView()) {
3584                 setInt32(
3585                     m_out.load32NonNegative(lowCell(m_node->child1()), m_heaps.JSArrayBufferView_length));
3586                 return;
3587             }
3588             
3589             DFG_CRASH(m_graph, m_node, "Bad array type");
3590             return;
3591         }
3592     }
3593
3594     void compileGetVectorLength()
3595     {
3596         switch (m_node->arrayMode().type()) {
3597         case Array::ArrayStorage:
3598         case Array::SlowPutArrayStorage:
3599             setInt32(m_out.load32NonNegative(lowStorage(m_node->child2()), m_heaps.Butterfly_vectorLength));
3600             return;
3601         default:
3602             return;
3603         }
3604     }
3605     
3606     void compileCheckInBounds()
3607     {
3608         speculate(
3609             OutOfBounds, noValue(), 0,
3610             m_out.aboveOrEqual(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
3611     }
3612     
3613     void compileGetByVal()
3614     {
3615         switch (m_node->arrayMode().type()) {
3616         case Array::Int32:
3617         case Array::Contiguous: {
3618             LValue index = lowInt32(m_node->child2());
3619             LValue storage = lowStorage(m_node->child3());
3620             
3621             IndexedAbstractHeap& heap = m_node->arrayMode().type() == Array::Int32 ?
3622                 m_heaps.indexedInt32Properties : m_heaps.indexedContiguousProperties;
3623             
3624             if (m_node->arrayMode().isInBounds()) {
3625                 LValue result = m_out.load64(baseIndex(heap, storage, index, m_node->child2()));