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