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