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