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