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