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