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