PutStackSinkingPhase should know that KillStack means ConflictingFlush
[WebKit-https.git] / Source / JavaScriptCore / ftl / FTLLowerDFGToB3.cpp
1 /*
2  * Copyright (C) 2013-2018 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27 #include "FTLLowerDFGToB3.h"
28
29 #if ENABLE(FTL_JIT)
30
31 #include "AirCode.h"
32 #include "AirGenerationContext.h"
33 #include "AllowMacroScratchRegisterUsage.h"
34 #include "AllowMacroScratchRegisterUsageIf.h"
35 #include "AtomicsObject.h"
36 #include "B3CheckValue.h"
37 #include "B3FenceValue.h"
38 #include "B3PatchpointValue.h"
39 #include "B3SlotBaseValue.h"
40 #include "B3StackmapGenerationParams.h"
41 #include "B3ValueInlines.h"
42 #include "CallFrameShuffler.h"
43 #include "CodeBlockWithJITType.h"
44 #include "DFGAbstractInterpreterInlines.h"
45 #include "DFGCapabilities.h"
46 #include "DFGDominators.h"
47 #include "DFGInPlaceAbstractState.h"
48 #include "DFGOSRAvailabilityAnalysisPhase.h"
49 #include "DFGOSRExitFuzz.h"
50 #include "DirectArguments.h"
51 #include "FTLAbstractHeapRepository.h"
52 #include "FTLAvailableRecovery.h"
53 #include "FTLExceptionTarget.h"
54 #include "FTLForOSREntryJITCode.h"
55 #include "FTLFormattedValue.h"
56 #include "FTLLazySlowPathCall.h"
57 #include "FTLLoweredNodeValue.h"
58 #include "FTLOperations.h"
59 #include "FTLOutput.h"
60 #include "FTLPatchpointExceptionHandle.h"
61 #include "FTLSnippetParams.h"
62 #include "FTLThunks.h"
63 #include "FTLWeightedTarget.h"
64 #include "JITAddGenerator.h"
65 #include "JITBitAndGenerator.h"
66 #include "JITBitOrGenerator.h"
67 #include "JITBitXorGenerator.h"
68 #include "JITDivGenerator.h"
69 #include "JITInlineCacheGenerator.h"
70 #include "JITLeftShiftGenerator.h"
71 #include "JITMathIC.h"
72 #include "JITMulGenerator.h"
73 #include "JITRightShiftGenerator.h"
74 #include "JITSubGenerator.h"
75 #include "JSAsyncFunction.h"
76 #include "JSAsyncGeneratorFunction.h"
77 #include "JSCInlines.h"
78 #include "JSGeneratorFunction.h"
79 #include "JSLexicalEnvironment.h"
80 #include "JSMap.h"
81 #include "OperandsInlines.h"
82 #include "RegExpObject.h"
83 #include "ScopedArguments.h"
84 #include "ScopedArgumentsTable.h"
85 #include "ScratchRegisterAllocator.h"
86 #include "SetupVarargsFrame.h"
87 #include "ShadowChicken.h"
88 #include "StructureStubInfo.h"
89 #include "SuperSampler.h"
90 #include "ThunkGenerators.h"
91 #include "VirtualRegister.h"
92 #include "Watchdog.h"
93 #include <atomic>
94 #include <wtf/Box.h>
95 #include <wtf/Gigacage.h>
96 #include <wtf/RecursableLambda.h>
97 #include <wtf/StdUnorderedSet.h>
98
99 #undef RELEASE_ASSERT
100 #define RELEASE_ASSERT(assertion) do { \
101     if (!(assertion)) { \
102         WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion); \
103         CRASH(); \
104     } \
105 } while (0)
106
107 namespace JSC { namespace FTL {
108
109 using namespace B3;
110 using namespace DFG;
111
112 namespace {
113
114 std::atomic<int> compileCounter;
115
116 #if !ASSERT_DISABLED
117 NO_RETURN_DUE_TO_CRASH static void ftlUnreachable(
118     CodeBlock* codeBlock, BlockIndex blockIndex, unsigned nodeIndex)
119 {
120     dataLog("Crashing in thought-to-be-unreachable FTL-generated code for ", pointerDump(codeBlock), " at basic block #", blockIndex);
121     if (nodeIndex != UINT_MAX)
122         dataLog(", node @", nodeIndex);
123     dataLog(".\n");
124     CRASH();
125 }
126 #endif
127
128 // Using this instead of typeCheck() helps to reduce the load on B3, by creating
129 // significantly less dead code.
130 #define FTL_TYPE_CHECK_WITH_EXIT_KIND(exitKind, lowValue, highValue, typesPassedThrough, failCondition) do { \
131         FormattedValue _ftc_lowValue = (lowValue);                      \
132         Edge _ftc_highValue = (highValue);                              \
133         SpeculatedType _ftc_typesPassedThrough = (typesPassedThrough);  \
134         if (!m_interpreter.needsTypeCheck(_ftc_highValue, _ftc_typesPassedThrough)) \
135             break;                                                      \
136         typeCheck(_ftc_lowValue, _ftc_highValue, _ftc_typesPassedThrough, (failCondition), exitKind); \
137     } while (false)
138
139 #define FTL_TYPE_CHECK(lowValue, highValue, typesPassedThrough, failCondition) \
140     FTL_TYPE_CHECK_WITH_EXIT_KIND(BadType, lowValue, highValue, typesPassedThrough, failCondition)
141
142 class LowerDFGToB3 {
143     WTF_MAKE_NONCOPYABLE(LowerDFGToB3);
144 public:
145     LowerDFGToB3(State& state)
146         : m_graph(state.graph)
147         , m_ftlState(state)
148         , m_out(state)
149         , m_proc(*state.proc)
150         , m_availabilityCalculator(m_graph)
151         , m_state(state.graph)
152         , m_interpreter(state.graph, m_state)
153         , m_indexMaskingMode(Options::enableSpectreMitigations() ?  IndexMaskingEnabled : IndexMaskingDisabled)
154     {
155     }
156     
157     void lower()
158     {
159         State* state = &m_ftlState;
160         
161         CString name;
162         if (verboseCompilationEnabled()) {
163             name = toCString(
164                 "jsBody_", ++compileCounter, "_", codeBlock()->inferredName(),
165                 "_", codeBlock()->hash());
166         } else
167             name = "jsBody";
168
169         {
170             m_proc.setNumEntrypoints(m_graph.m_numberOfEntrypoints);
171             CodeBlock* codeBlock = m_graph.m_codeBlock;
172
173             Ref<B3::Air::PrologueGenerator> catchPrologueGenerator = createSharedTask<B3::Air::PrologueGeneratorFunction>(
174                 [codeBlock] (CCallHelpers& jit, B3::Air::Code& code) {
175                     AllowMacroScratchRegisterUsage allowScratch(jit);
176                     jit.addPtr(CCallHelpers::TrustedImm32(-code.frameSize()), GPRInfo::callFrameRegister, CCallHelpers::stackPointerRegister);
177                     if (Options::zeroStackFrame())
178                         jit.clearStackFrame(GPRInfo::callFrameRegister, CCallHelpers::stackPointerRegister, GPRInfo::regT0, code.frameSize());
179
180                     jit.emitSave(code.calleeSaveRegisterAtOffsetList());
181                     jit.emitPutToCallFrameHeader(codeBlock, CallFrameSlot::codeBlock);
182                 });
183
184             for (unsigned catchEntrypointIndex : m_graph.m_entrypointIndexToCatchBytecodeOffset.keys()) {
185                 RELEASE_ASSERT(catchEntrypointIndex != 0);
186                 m_proc.code().setPrologueForEntrypoint(catchEntrypointIndex, catchPrologueGenerator.copyRef());
187             }
188
189             if (m_graph.m_maxLocalsForCatchOSREntry) {
190                 uint32_t numberOfLiveLocals = std::max(*m_graph.m_maxLocalsForCatchOSREntry, 1u); // Make sure we always allocate a non-null catchOSREntryBuffer.
191                 m_ftlState.jitCode->common.catchOSREntryBuffer = m_graph.m_vm.scratchBufferForSize(sizeof(JSValue) * numberOfLiveLocals);
192             }
193         }
194         
195         m_graph.ensureSSADominators();
196
197         if (verboseCompilationEnabled())
198             dataLog("Function ready, beginning lowering.\n");
199
200         m_out.initialize(m_heaps);
201
202         // We use prologue frequency for all of the initialization code.
203         m_out.setFrequency(1);
204         
205         bool hasMultipleEntrypoints = m_graph.m_numberOfEntrypoints > 1;
206     
207         LBasicBlock prologue = m_out.newBlock();
208         LBasicBlock callEntrypointArgumentSpeculations = hasMultipleEntrypoints ? m_out.newBlock() : nullptr;
209         m_handleExceptions = m_out.newBlock();
210
211         for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
212             m_highBlock = m_graph.block(blockIndex);
213             if (!m_highBlock)
214                 continue;
215             m_out.setFrequency(m_highBlock->executionCount);
216             m_blocks.add(m_highBlock, m_out.newBlock());
217         }
218
219         // Back to prologue frequency for any bocks that get sneakily created in the initialization code.
220         m_out.setFrequency(1);
221         
222         m_out.appendTo(prologue, hasMultipleEntrypoints ? callEntrypointArgumentSpeculations : m_handleExceptions);
223         m_out.initializeConstants(m_proc, prologue);
224         createPhiVariables();
225
226         size_t sizeOfCaptured = sizeof(JSValue) * m_graph.m_nextMachineLocal;
227         B3::SlotBaseValue* capturedBase = m_out.lockedStackSlot(sizeOfCaptured);
228         m_captured = m_out.add(capturedBase, m_out.constIntPtr(sizeOfCaptured));
229         state->capturedValue = capturedBase->slot();
230
231         auto preOrder = m_graph.blocksInPreOrder();
232
233         m_callFrame = m_out.framePointer();
234         m_tagTypeNumber = m_out.constInt64(TagTypeNumber);
235         m_tagMask = m_out.constInt64(TagMask);
236
237         // Make sure that B3 knows that we really care about the mask registers. This forces the
238         // constants to be materialized in registers.
239         m_proc.addFastConstant(m_tagTypeNumber->key());
240         m_proc.addFastConstant(m_tagMask->key());
241         
242         // We don't want the CodeBlock to have a weak pointer to itself because
243         // that would cause it to always get collected.
244         m_out.storePtr(m_out.constIntPtr(bitwise_cast<intptr_t>(codeBlock())), addressFor(CallFrameSlot::codeBlock));
245
246         VM* vm = &this->vm();
247
248         // Stack Overflow Check.
249         unsigned exitFrameSize = m_graph.requiredRegisterCountForExit() * sizeof(Register);
250         MacroAssembler::AbsoluteAddress addressOfStackLimit(vm->addressOfSoftStackLimit());
251         PatchpointValue* stackOverflowHandler = m_out.patchpoint(Void);
252         CallSiteIndex callSiteIndex = callSiteIndexForCodeOrigin(m_ftlState, CodeOrigin(0));
253         stackOverflowHandler->appendSomeRegister(m_callFrame);
254         stackOverflowHandler->clobber(RegisterSet::macroScratchRegisters());
255         stackOverflowHandler->numGPScratchRegisters = 1;
256         stackOverflowHandler->setGenerator(
257             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
258                 AllowMacroScratchRegisterUsage allowScratch(jit);
259                 GPRReg fp = params[0].gpr();
260                 GPRReg scratch = params.gpScratch(0);
261
262                 unsigned ftlFrameSize = params.proc().frameSize();
263                 unsigned maxFrameSize = std::max(exitFrameSize, ftlFrameSize);
264
265                 jit.addPtr(MacroAssembler::TrustedImm32(-maxFrameSize), fp, scratch);
266                 MacroAssembler::JumpList stackOverflow;
267                 if (UNLIKELY(maxFrameSize > Options::reservedZoneSize()))
268                     stackOverflow.append(jit.branchPtr(MacroAssembler::Above, scratch, fp));
269                 stackOverflow.append(jit.branchPtr(MacroAssembler::Above, addressOfStackLimit, scratch));
270
271                 params.addLatePath([=] (CCallHelpers& jit) {
272                     AllowMacroScratchRegisterUsage allowScratch(jit);
273
274                     stackOverflow.link(&jit);
275                     
276                     // FIXME: We would not have to do this if the stack check was part of the Air
277                     // prologue. Then, we would know that there is no way for the callee-saves to
278                     // get clobbered.
279                     // https://bugs.webkit.org/show_bug.cgi?id=172456
280                     jit.emitRestore(params.proc().calleeSaveRegisterAtOffsetList());
281                     
282                     jit.store32(
283                         MacroAssembler::TrustedImm32(callSiteIndex.bits()),
284                         CCallHelpers::tagFor(VirtualRegister(CallFrameSlot::argumentCount)));
285                     jit.copyCalleeSavesToEntryFrameCalleeSavesBuffer(vm->topEntryFrame);
286
287                     jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
288                     jit.move(CCallHelpers::TrustedImmPtr(jit.codeBlock()), GPRInfo::argumentGPR1);
289                     PtrTag throwTag = ptrTag(FTLOperationPtrTag, nextPtrTagID());
290                     CCallHelpers::Call throwCall = jit.call(throwTag);
291
292                     jit.move(CCallHelpers::TrustedImmPtr(vm), GPRInfo::argumentGPR0);
293                     jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
294                     PtrTag lookupTag = ptrTag(FTLOperationPtrTag, nextPtrTagID());
295                     CCallHelpers::Call lookupExceptionHandlerCall = jit.call(lookupTag);
296                     jit.jumpToExceptionHandler(*vm);
297
298                     jit.addLinkTask(
299                         [=] (LinkBuffer& linkBuffer) {
300                             linkBuffer.link(throwCall, FunctionPtr(operationThrowStackOverflowError, throwTag));
301                             linkBuffer.link(lookupExceptionHandlerCall, FunctionPtr(lookupExceptionHandlerFromCallerFrame, lookupTag));
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(*exceptionHandler, ExceptionHandlerPtrTag));
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 GetStack:
572             compileGetStack();
573             break;
574         case PutStack:
575             compilePutStack();
576             break;
577         case DFG::Check:
578         case CheckVarargs:
579             compileNoOp();
580             break;
581         case ToObject:
582         case CallObjectConstructor:
583             compileToObjectOrCallObjectConstructor();
584             break;
585         case ToThis:
586             compileToThis();
587             break;
588         case ValueAdd:
589             compileValueAdd();
590             break;
591         case StrCat:
592             compileStrCat();
593             break;
594         case ArithAdd:
595         case ArithSub:
596             compileArithAddOrSub();
597             break;
598         case ArithClz32:
599             compileArithClz32();
600             break;
601         case ArithMul:
602             compileArithMul();
603             break;
604         case ArithDiv:
605             compileArithDiv();
606             break;
607         case ArithMod:
608             compileArithMod();
609             break;
610         case ArithMin:
611         case ArithMax:
612             compileArithMinOrMax();
613             break;
614         case ArithAbs:
615             compileArithAbs();
616             break;
617         case ArithPow:
618             compileArithPow();
619             break;
620         case ArithRandom:
621             compileArithRandom();
622             break;
623         case ArithRound:
624             compileArithRound();
625             break;
626         case ArithFloor:
627             compileArithFloor();
628             break;
629         case ArithCeil:
630             compileArithCeil();
631             break;
632         case ArithTrunc:
633             compileArithTrunc();
634             break;
635         case ArithSqrt:
636             compileArithSqrt();
637             break;
638         case ArithFRound:
639             compileArithFRound();
640             break;
641         case ArithNegate:
642             compileArithNegate();
643             break;
644         case ArithUnary:
645             compileArithUnary();
646             break;
647         case DFG::BitAnd:
648             compileBitAnd();
649             break;
650         case DFG::BitOr:
651             compileBitOr();
652             break;
653         case DFG::BitXor:
654             compileBitXor();
655             break;
656         case BitRShift:
657             compileBitRShift();
658             break;
659         case BitLShift:
660             compileBitLShift();
661             break;
662         case BitURShift:
663             compileBitURShift();
664             break;
665         case UInt32ToNumber:
666             compileUInt32ToNumber();
667             break;
668         case CheckStructure:
669             compileCheckStructure();
670             break;
671         case CheckStructureOrEmpty:
672             compileCheckStructureOrEmpty();
673             break;
674         case CheckCell:
675             compileCheckCell();
676             break;
677         case CheckNotEmpty:
678             compileCheckNotEmpty();
679             break;
680         case AssertNotEmpty:
681             compileAssertNotEmpty();
682             break;
683         case CheckBadCell:
684             compileCheckBadCell();
685             break;
686         case CheckStringIdent:
687             compileCheckStringIdent();
688             break;
689         case GetExecutable:
690             compileGetExecutable();
691             break;
692         case Arrayify:
693         case ArrayifyToStructure:
694             compileArrayify();
695             break;
696         case PutStructure:
697             compilePutStructure();
698             break;
699         case TryGetById:
700             compileGetById(AccessType::TryGet);
701             break;
702         case GetById:
703         case GetByIdFlush:
704             compileGetById(AccessType::Get);
705             break;
706         case GetByIdWithThis:
707             compileGetByIdWithThis();
708             break;
709         case GetByIdDirect:
710         case GetByIdDirectFlush:
711             compileGetById(AccessType::GetDirect);
712             break;
713         case In:
714             compileIn();
715             break;
716         case HasOwnProperty:
717             compileHasOwnProperty();
718             break;
719         case PutById:
720         case PutByIdDirect:
721         case PutByIdFlush:
722             compilePutById();
723             break;
724         case PutByIdWithThis:
725             compilePutByIdWithThis();
726             break;
727         case PutGetterById:
728         case PutSetterById:
729             compilePutAccessorById();
730             break;
731         case PutGetterSetterById:
732             compilePutGetterSetterById();
733             break;
734         case PutGetterByVal:
735         case PutSetterByVal:
736             compilePutAccessorByVal();
737             break;
738         case DeleteById:
739             compileDeleteById();
740             break;
741         case DeleteByVal:
742             compileDeleteByVal();
743             break;
744         case GetButterfly:
745             compileGetButterfly();
746             break;
747         case ConstantStoragePointer:
748             compileConstantStoragePointer();
749             break;
750         case GetIndexedPropertyStorage:
751             compileGetIndexedPropertyStorage();
752             break;
753         case CheckArray:
754             compileCheckArray();
755             break;
756         case GetArrayLength:
757             compileGetArrayLength();
758             break;
759         case GetVectorLength:
760             compileGetVectorLength();
761             break;
762         case CheckInBounds:
763             compileCheckInBounds();
764             break;
765         case GetByVal:
766             compileGetByVal();
767             break;
768         case GetMyArgumentByVal:
769         case GetMyArgumentByValOutOfBounds:
770             compileGetMyArgumentByVal();
771             break;
772         case GetByValWithThis:
773             compileGetByValWithThis();
774             break;
775         case PutByVal:
776         case PutByValAlias:
777         case PutByValDirect:
778             compilePutByVal();
779             break;
780         case PutByValWithThis:
781             compilePutByValWithThis();
782             break;
783         case AtomicsAdd:
784         case AtomicsAnd:
785         case AtomicsCompareExchange:
786         case AtomicsExchange:
787         case AtomicsLoad:
788         case AtomicsOr:
789         case AtomicsStore:
790         case AtomicsSub:
791         case AtomicsXor:
792             compileAtomicsReadModifyWrite();
793             break;
794         case AtomicsIsLockFree:
795             compileAtomicsIsLockFree();
796             break;
797         case DefineDataProperty:
798             compileDefineDataProperty();
799             break;
800         case DefineAccessorProperty:
801             compileDefineAccessorProperty();
802             break;
803         case ArrayPush:
804             compileArrayPush();
805             break;
806         case ArrayPop:
807             compileArrayPop();
808             break;
809         case ArraySlice:
810             compileArraySlice();
811             break;
812         case ArrayIndexOf:
813             compileArrayIndexOf();
814             break;
815         case CreateActivation:
816             compileCreateActivation();
817             break;
818         case PushWithScope:
819             compilePushWithScope();
820             break;
821         case NewFunction:
822         case NewGeneratorFunction:
823         case NewAsyncGeneratorFunction:
824         case NewAsyncFunction:
825             compileNewFunction();
826             break;
827         case CreateDirectArguments:
828             compileCreateDirectArguments();
829             break;
830         case CreateScopedArguments:
831             compileCreateScopedArguments();
832             break;
833         case CreateClonedArguments:
834             compileCreateClonedArguments();
835             break;
836         case NewObject:
837             compileNewObject();
838             break;
839         case NewStringObject:
840             compileNewStringObject();
841             break;
842         case NewArray:
843             compileNewArray();
844             break;
845         case NewArrayWithSpread:
846             compileNewArrayWithSpread();
847             break;
848         case Spread:
849             compileSpread();
850             break;
851         case NewArrayBuffer:
852             compileNewArrayBuffer();
853             break;
854         case NewArrayWithSize:
855             compileNewArrayWithSize();
856             break;
857         case NewTypedArray:
858             compileNewTypedArray();
859             break;
860         case GetTypedArrayByteOffset:
861             compileGetTypedArrayByteOffset();
862             break;
863         case GetPrototypeOf:
864             compileGetPrototypeOf();
865             break;
866         case AllocatePropertyStorage:
867             compileAllocatePropertyStorage();
868             break;
869         case ReallocatePropertyStorage:
870             compileReallocatePropertyStorage();
871             break;
872         case NukeStructureAndSetButterfly:
873             compileNukeStructureAndSetButterfly();
874             break;
875         case ToNumber:
876             compileToNumber();
877             break;
878         case ToString:
879         case CallStringConstructor:
880             compileToStringOrCallStringConstructor();
881             break;
882         case ToPrimitive:
883             compileToPrimitive();
884             break;
885         case MakeRope:
886             compileMakeRope();
887             break;
888         case StringCharAt:
889             compileStringCharAt();
890             break;
891         case StringCharCodeAt:
892             compileStringCharCodeAt();
893             break;
894         case StringFromCharCode:
895             compileStringFromCharCode();
896             break;
897         case GetByOffset:
898         case GetGetterSetterByOffset:
899             compileGetByOffset();
900             break;
901         case GetGetter:
902             compileGetGetter();
903             break;
904         case GetSetter:
905             compileGetSetter();
906             break;
907         case MultiGetByOffset:
908             compileMultiGetByOffset();
909             break;
910         case PutByOffset:
911             compilePutByOffset();
912             break;
913         case MultiPutByOffset:
914             compileMultiPutByOffset();
915             break;
916         case GetGlobalVar:
917         case GetGlobalLexicalVariable:
918             compileGetGlobalVariable();
919             break;
920         case PutGlobalVariable:
921             compilePutGlobalVariable();
922             break;
923         case NotifyWrite:
924             compileNotifyWrite();
925             break;
926         case GetCallee:
927             compileGetCallee();
928             break;
929         case GetArgumentCountIncludingThis:
930             compileGetArgumentCountIncludingThis();
931             break;
932         case SetArgumentCountIncludingThis:
933             compileSetArgumentCountIncludingThis();
934             break;
935         case GetScope:
936             compileGetScope();
937             break;
938         case SkipScope:
939             compileSkipScope();
940             break;
941         case GetGlobalObject:
942             compileGetGlobalObject();
943             break;
944         case GetGlobalThis:
945             compileGetGlobalThis();
946             break;
947         case GetClosureVar:
948             compileGetClosureVar();
949             break;
950         case PutClosureVar:
951             compilePutClosureVar();
952             break;
953         case GetFromArguments:
954             compileGetFromArguments();
955             break;
956         case PutToArguments:
957             compilePutToArguments();
958             break;
959         case GetArgument:
960             compileGetArgument();
961             break;
962         case CompareEq:
963             compileCompareEq();
964             break;
965         case CompareStrictEq:
966             compileCompareStrictEq();
967             break;
968         case CompareLess:
969             compileCompareLess();
970             break;
971         case CompareLessEq:
972             compileCompareLessEq();
973             break;
974         case CompareGreater:
975             compileCompareGreater();
976             break;
977         case CompareGreaterEq:
978             compileCompareGreaterEq();
979             break;
980         case CompareBelow:
981             compileCompareBelow();
982             break;
983         case CompareBelowEq:
984             compileCompareBelowEq();
985             break;
986         case CompareEqPtr:
987             compileCompareEqPtr();
988             break;
989         case LogicalNot:
990             compileLogicalNot();
991             break;
992         case Call:
993         case TailCallInlinedCaller:
994         case Construct:
995             compileCallOrConstruct();
996             break;
997         case DirectCall:
998         case DirectTailCallInlinedCaller:
999         case DirectConstruct:
1000         case DirectTailCall:
1001             compileDirectCallOrConstruct();
1002             break;
1003         case TailCall:
1004             compileTailCall();
1005             break;
1006         case CallVarargs:
1007         case CallForwardVarargs:
1008         case TailCallVarargs:
1009         case TailCallVarargsInlinedCaller:
1010         case TailCallForwardVarargs:
1011         case TailCallForwardVarargsInlinedCaller:
1012         case ConstructVarargs:
1013         case ConstructForwardVarargs:
1014             compileCallOrConstructVarargs();
1015             break;
1016         case CallEval:
1017             compileCallEval();
1018             break;
1019         case LoadVarargs:
1020             compileLoadVarargs();
1021             break;
1022         case ForwardVarargs:
1023             compileForwardVarargs();
1024             break;
1025         case DFG::Jump:
1026             compileJump();
1027             break;
1028         case DFG::Branch:
1029             compileBranch();
1030             break;
1031         case DFG::Switch:
1032             compileSwitch();
1033             break;
1034         case DFG::EntrySwitch:
1035             compileEntrySwitch();
1036             break;
1037         case DFG::Return:
1038             compileReturn();
1039             break;
1040         case ForceOSRExit:
1041             compileForceOSRExit();
1042             break;
1043         case CPUIntrinsic:
1044 #if CPU(X86_64)
1045             compileCPUIntrinsic();
1046 #else
1047             RELEASE_ASSERT_NOT_REACHED();
1048 #endif
1049             break;
1050         case Throw:
1051             compileThrow();
1052             break;
1053         case ThrowStaticError:
1054             compileThrowStaticError();
1055             break;
1056         case InvalidationPoint:
1057             compileInvalidationPoint();
1058             break;
1059         case IsEmpty:
1060             compileIsEmpty();
1061             break;
1062         case IsUndefined:
1063             compileIsUndefined();
1064             break;
1065         case IsBoolean:
1066             compileIsBoolean();
1067             break;
1068         case IsNumber:
1069             compileIsNumber();
1070             break;
1071         case NumberIsInteger:
1072             compileNumberIsInteger();
1073             break;
1074         case IsCellWithType:
1075             compileIsCellWithType();
1076             break;
1077         case MapHash:
1078             compileMapHash();
1079             break;
1080         case NormalizeMapKey:
1081             compileNormalizeMapKey();
1082             break;
1083         case GetMapBucket:
1084             compileGetMapBucket();
1085             break;
1086         case GetMapBucketHead:
1087             compileGetMapBucketHead();
1088             break;
1089         case GetMapBucketNext:
1090             compileGetMapBucketNext();
1091             break;
1092         case LoadKeyFromMapBucket:
1093             compileLoadKeyFromMapBucket();
1094             break;
1095         case LoadValueFromMapBucket:
1096             compileLoadValueFromMapBucket();
1097             break;
1098         case ExtractValueFromWeakMapGet:
1099             compileExtractValueFromWeakMapGet();
1100             break;
1101         case SetAdd:
1102             compileSetAdd();
1103             break;
1104         case MapSet:
1105             compileMapSet();
1106             break;
1107         case WeakMapGet:
1108             compileWeakMapGet();
1109             break;
1110         case WeakSetAdd:
1111             compileWeakSetAdd();
1112             break;
1113         case WeakMapSet:
1114             compileWeakMapSet();
1115             break;
1116         case IsObject:
1117             compileIsObject();
1118             break;
1119         case IsObjectOrNull:
1120             compileIsObjectOrNull();
1121             break;
1122         case IsFunction:
1123             compileIsFunction();
1124             break;
1125         case IsTypedArrayView:
1126             compileIsTypedArrayView();
1127             break;
1128         case ParseInt:
1129             compileParseInt();
1130             break;
1131         case TypeOf:
1132             compileTypeOf();
1133             break;
1134         case CheckTypeInfoFlags:
1135             compileCheckTypeInfoFlags();
1136             break;
1137         case OverridesHasInstance:
1138             compileOverridesHasInstance();
1139             break;
1140         case InstanceOf:
1141             compileInstanceOf();
1142             break;
1143         case InstanceOfCustom:
1144             compileInstanceOfCustom();
1145             break;
1146         case CountExecution:
1147             compileCountExecution();
1148             break;
1149         case SuperSamplerBegin:
1150             compileSuperSamplerBegin();
1151             break;
1152         case SuperSamplerEnd:
1153             compileSuperSamplerEnd();
1154             break;
1155         case StoreBarrier:
1156         case FencedStoreBarrier:
1157             compileStoreBarrier();
1158             break;
1159         case HasIndexedProperty:
1160             compileHasIndexedProperty();
1161             break;
1162         case HasGenericProperty:
1163             compileHasGenericProperty();
1164             break;
1165         case HasStructureProperty:
1166             compileHasStructureProperty();
1167             break;
1168         case GetDirectPname:
1169             compileGetDirectPname();
1170             break;
1171         case GetEnumerableLength:
1172             compileGetEnumerableLength();
1173             break;
1174         case GetPropertyEnumerator:
1175             compileGetPropertyEnumerator();
1176             break;
1177         case GetEnumeratorStructurePname:
1178             compileGetEnumeratorStructurePname();
1179             break;
1180         case GetEnumeratorGenericPname:
1181             compileGetEnumeratorGenericPname();
1182             break;
1183         case ToIndexString:
1184             compileToIndexString();
1185             break;
1186         case CheckStructureImmediate:
1187             compileCheckStructureImmediate();
1188             break;
1189         case MaterializeNewObject:
1190             compileMaterializeNewObject();
1191             break;
1192         case MaterializeCreateActivation:
1193             compileMaterializeCreateActivation();
1194             break;
1195         case CheckTraps:
1196             if (Options::usePollingTraps())
1197                 compileCheckTraps();
1198             break;
1199         case CreateRest:
1200             compileCreateRest();
1201             break;
1202         case GetRestLength:
1203             compileGetRestLength();
1204             break;
1205         case RegExpExec:
1206             compileRegExpExec();
1207             break;
1208         case RegExpExecNonGlobalOrSticky:
1209             compileRegExpExecNonGlobalOrSticky();
1210             break;
1211         case RegExpTest:
1212             compileRegExpTest();
1213             break;
1214         case RegExpMatchFast:
1215             compileRegExpMatchFast();
1216             break;
1217         case RegExpMatchFastGlobal:
1218             compileRegExpMatchFastGlobal();
1219             break;
1220         case NewRegexp:
1221             compileNewRegexp();
1222             break;
1223         case SetFunctionName:
1224             compileSetFunctionName();
1225             break;
1226         case StringReplace:
1227         case StringReplaceRegExp:
1228             compileStringReplace();
1229             break;
1230         case GetRegExpObjectLastIndex:
1231             compileGetRegExpObjectLastIndex();
1232             break;
1233         case SetRegExpObjectLastIndex:
1234             compileSetRegExpObjectLastIndex();
1235             break;
1236         case LogShadowChickenPrologue:
1237             compileLogShadowChickenPrologue();
1238             break;
1239         case LogShadowChickenTail:
1240             compileLogShadowChickenTail();
1241             break;
1242         case RecordRegExpCachedResult:
1243             compileRecordRegExpCachedResult();
1244             break;
1245         case ResolveScopeForHoistingFuncDeclInEval:
1246             compileResolveScopeForHoistingFuncDeclInEval();
1247             break;
1248         case ResolveScope:
1249             compileResolveScope();
1250             break;
1251         case GetDynamicVar:
1252             compileGetDynamicVar();
1253             break;
1254         case PutDynamicVar:
1255             compilePutDynamicVar();
1256             break;
1257         case Unreachable:
1258             compileUnreachable();
1259             break;
1260         case StringSlice:
1261             compileStringSlice();
1262             break;
1263         case ToLowerCase:
1264             compileToLowerCase();
1265             break;
1266         case NumberToStringWithRadix:
1267             compileNumberToStringWithRadix();
1268             break;
1269         case NumberToStringWithValidRadixConstant:
1270             compileNumberToStringWithValidRadixConstant();
1271             break;
1272         case CheckSubClass:
1273             compileCheckSubClass();
1274             break;
1275         case CallDOM:
1276             compileCallDOM();
1277             break;
1278         case CallDOMGetter:
1279             compileCallDOMGetter();
1280             break;
1281
1282         case PhantomLocal:
1283         case LoopHint:
1284         case MovHint:
1285         case ZombieHint:
1286         case ExitOK:
1287         case PhantomNewObject:
1288         case PhantomNewFunction:
1289         case PhantomNewGeneratorFunction:
1290         case PhantomNewAsyncGeneratorFunction:
1291         case PhantomNewAsyncFunction:
1292         case PhantomCreateActivation:
1293         case PhantomDirectArguments:
1294         case PhantomCreateRest:
1295         case PhantomSpread:
1296         case PhantomNewArrayWithSpread:
1297         case PhantomNewArrayBuffer:
1298         case PhantomClonedArguments:
1299         case PhantomNewRegexp:
1300         case PutHint:
1301         case BottomValue:
1302         case KillStack:
1303         case InitializeEntrypointArguments:
1304             break;
1305         default:
1306             DFG_CRASH(m_graph, m_node, "Unrecognized node in FTL backend");
1307             break;
1308         }
1309         
1310         if (m_node->isTerminal())
1311             return false;
1312         
1313         if (!m_state.isValid()) {
1314             safelyInvalidateAfterTermination();
1315             return false;
1316         }
1317
1318         m_availabilityCalculator.executeNode(m_node);
1319         m_interpreter.executeEffects(nodeIndex);
1320         
1321         return true;
1322     }
1323
1324     void compileUpsilon()
1325     {
1326         LValue upsilonValue = nullptr;
1327         switch (m_node->child1().useKind()) {
1328         case DoubleRepUse:
1329             upsilonValue = lowDouble(m_node->child1());
1330             break;
1331         case Int32Use:
1332         case KnownInt32Use:
1333             upsilonValue = lowInt32(m_node->child1());
1334             break;
1335         case Int52RepUse:
1336             upsilonValue = lowInt52(m_node->child1());
1337             break;
1338         case BooleanUse:
1339         case KnownBooleanUse:
1340             upsilonValue = lowBoolean(m_node->child1());
1341             break;
1342         case CellUse:
1343         case KnownCellUse:
1344             upsilonValue = lowCell(m_node->child1());
1345             break;
1346         case UntypedUse:
1347             upsilonValue = lowJSValue(m_node->child1());
1348             break;
1349         default:
1350             DFG_CRASH(m_graph, m_node, "Bad use kind");
1351             break;
1352         }
1353         ValueFromBlock upsilon = m_out.anchor(upsilonValue);
1354         LValue phiNode = m_phis.get(m_node->phi());
1355         m_out.addIncomingToPhi(phiNode, upsilon);
1356     }
1357     
1358     void compilePhi()
1359     {
1360         LValue phi = m_phis.get(m_node);
1361         m_out.m_block->append(phi);
1362
1363         switch (m_node->flags() & NodeResultMask) {
1364         case NodeResultDouble:
1365             setDouble(phi);
1366             break;
1367         case NodeResultInt32:
1368             setInt32(phi);
1369             break;
1370         case NodeResultInt52:
1371             setInt52(phi);
1372             break;
1373         case NodeResultBoolean:
1374             setBoolean(phi);
1375             break;
1376         case NodeResultJS:
1377             setJSValue(phi);
1378             break;
1379         default:
1380             DFG_CRASH(m_graph, m_node, "Bad use kind");
1381             break;
1382         }
1383     }
1384     
1385     void compileDoubleConstant()
1386     {
1387         setDouble(m_out.constDouble(m_node->asNumber()));
1388     }
1389     
1390     void compileInt52Constant()
1391     {
1392         int64_t value = m_node->asAnyInt();
1393         
1394         setInt52(m_out.constInt64(value << JSValue::int52ShiftAmount));
1395         setStrictInt52(m_out.constInt64(value));
1396     }
1397
1398     void compileLazyJSConstant()
1399     {
1400         PatchpointValue* patchpoint = m_out.patchpoint(Int64);
1401         LazyJSValue value = m_node->lazyJSValue();
1402         patchpoint->setGenerator(
1403             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
1404                 value.emit(jit, JSValueRegs(params[0].gpr()));
1405             });
1406         patchpoint->effects = Effects::none();
1407         setJSValue(patchpoint);
1408     }
1409
1410     void compileDoubleRep()
1411     {
1412         switch (m_node->child1().useKind()) {
1413         case RealNumberUse: {
1414             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
1415             
1416             LValue doubleValue = unboxDouble(value);
1417             
1418             LBasicBlock intCase = m_out.newBlock();
1419             LBasicBlock continuation = m_out.newBlock();
1420             
1421             ValueFromBlock fastResult = m_out.anchor(doubleValue);
1422             m_out.branch(
1423                 m_out.doubleEqual(doubleValue, doubleValue),
1424                 usually(continuation), rarely(intCase));
1425             
1426             LBasicBlock lastNext = m_out.appendTo(intCase, continuation);
1427
1428             FTL_TYPE_CHECK(
1429                 jsValueValue(value), m_node->child1(), SpecBytecodeRealNumber,
1430                 isNotInt32(value, provenType(m_node->child1()) & ~SpecDoubleReal));
1431             ValueFromBlock slowResult = m_out.anchor(m_out.intToDouble(unboxInt32(value)));
1432             m_out.jump(continuation);
1433             
1434             m_out.appendTo(continuation, lastNext);
1435             
1436             setDouble(m_out.phi(Double, fastResult, slowResult));
1437             return;
1438         }
1439             
1440         case NotCellUse:
1441         case NumberUse: {
1442             bool shouldConvertNonNumber = m_node->child1().useKind() == NotCellUse;
1443             
1444             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
1445
1446             LBasicBlock intCase = m_out.newBlock();
1447             LBasicBlock doubleTesting = m_out.newBlock();
1448             LBasicBlock doubleCase = m_out.newBlock();
1449             LBasicBlock nonDoubleCase = m_out.newBlock();
1450             LBasicBlock continuation = m_out.newBlock();
1451             
1452             m_out.branch(
1453                 isNotInt32(value, provenType(m_node->child1())),
1454                 unsure(doubleTesting), unsure(intCase));
1455             
1456             LBasicBlock lastNext = m_out.appendTo(intCase, doubleTesting);
1457             
1458             ValueFromBlock intToDouble = m_out.anchor(
1459                 m_out.intToDouble(unboxInt32(value)));
1460             m_out.jump(continuation);
1461             
1462             m_out.appendTo(doubleTesting, doubleCase);
1463             LValue valueIsNumber = isNumber(value, provenType(m_node->child1()));
1464             m_out.branch(valueIsNumber, usually(doubleCase), rarely(nonDoubleCase));
1465
1466             m_out.appendTo(doubleCase, nonDoubleCase);
1467             ValueFromBlock unboxedDouble = m_out.anchor(unboxDouble(value));
1468             m_out.jump(continuation);
1469
1470             if (shouldConvertNonNumber) {
1471                 LBasicBlock undefinedCase = m_out.newBlock();
1472                 LBasicBlock testNullCase = m_out.newBlock();
1473                 LBasicBlock nullCase = m_out.newBlock();
1474                 LBasicBlock testBooleanTrueCase = m_out.newBlock();
1475                 LBasicBlock convertBooleanTrueCase = m_out.newBlock();
1476                 LBasicBlock convertBooleanFalseCase = m_out.newBlock();
1477
1478                 m_out.appendTo(nonDoubleCase, undefinedCase);
1479                 LValue valueIsUndefined = m_out.equal(value, m_out.constInt64(ValueUndefined));
1480                 m_out.branch(valueIsUndefined, unsure(undefinedCase), unsure(testNullCase));
1481
1482                 m_out.appendTo(undefinedCase, testNullCase);
1483                 ValueFromBlock convertedUndefined = m_out.anchor(m_out.constDouble(PNaN));
1484                 m_out.jump(continuation);
1485
1486                 m_out.appendTo(testNullCase, nullCase);
1487                 LValue valueIsNull = m_out.equal(value, m_out.constInt64(ValueNull));
1488                 m_out.branch(valueIsNull, unsure(nullCase), unsure(testBooleanTrueCase));
1489
1490                 m_out.appendTo(nullCase, testBooleanTrueCase);
1491                 ValueFromBlock convertedNull = m_out.anchor(m_out.constDouble(0));
1492                 m_out.jump(continuation);
1493
1494                 m_out.appendTo(testBooleanTrueCase, convertBooleanTrueCase);
1495                 LValue valueIsBooleanTrue = m_out.equal(value, m_out.constInt64(ValueTrue));
1496                 m_out.branch(valueIsBooleanTrue, unsure(convertBooleanTrueCase), unsure(convertBooleanFalseCase));
1497
1498                 m_out.appendTo(convertBooleanTrueCase, convertBooleanFalseCase);
1499                 ValueFromBlock convertedTrue = m_out.anchor(m_out.constDouble(1));
1500                 m_out.jump(continuation);
1501
1502                 m_out.appendTo(convertBooleanFalseCase, continuation);
1503
1504                 LValue valueIsNotBooleanFalse = m_out.notEqual(value, m_out.constInt64(ValueFalse));
1505                 FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), ~SpecCellCheck, valueIsNotBooleanFalse);
1506                 ValueFromBlock convertedFalse = m_out.anchor(m_out.constDouble(0));
1507                 m_out.jump(continuation);
1508
1509                 m_out.appendTo(continuation, lastNext);
1510                 setDouble(m_out.phi(Double, intToDouble, unboxedDouble, convertedUndefined, convertedNull, convertedTrue, convertedFalse));
1511                 return;
1512             }
1513             m_out.appendTo(nonDoubleCase, continuation);
1514             FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), SpecBytecodeNumber, m_out.booleanTrue);
1515             m_out.unreachable();
1516
1517             m_out.appendTo(continuation, lastNext);
1518
1519             setDouble(m_out.phi(Double, intToDouble, unboxedDouble));
1520             return;
1521         }
1522             
1523         case Int52RepUse: {
1524             setDouble(strictInt52ToDouble(lowStrictInt52(m_node->child1())));
1525             return;
1526         }
1527             
1528         default:
1529             DFG_CRASH(m_graph, m_node, "Bad use kind");
1530         }
1531     }
1532
1533     void compileDoubleAsInt32()
1534     {
1535         LValue integerValue = convertDoubleToInt32(lowDouble(m_node->child1()), shouldCheckNegativeZero(m_node->arithMode()));
1536         setInt32(integerValue);
1537     }
1538
1539     void compileValueRep()
1540     {
1541         switch (m_node->child1().useKind()) {
1542         case DoubleRepUse: {
1543             LValue value = lowDouble(m_node->child1());
1544             
1545             if (m_interpreter.needsTypeCheck(m_node->child1(), ~SpecDoubleImpureNaN)) {
1546                 value = m_out.select(
1547                     m_out.doubleEqual(value, value), value, m_out.constDouble(PNaN));
1548             }
1549             
1550             setJSValue(boxDouble(value));
1551             return;
1552         }
1553             
1554         case Int52RepUse: {
1555             setJSValue(strictInt52ToJSValue(lowStrictInt52(m_node->child1())));
1556             return;
1557         }
1558             
1559         default:
1560             DFG_CRASH(m_graph, m_node, "Bad use kind");
1561         }
1562     }
1563     
1564     void compileInt52Rep()
1565     {
1566         switch (m_node->child1().useKind()) {
1567         case Int32Use:
1568             setStrictInt52(m_out.signExt32To64(lowInt32(m_node->child1())));
1569             return;
1570             
1571         case AnyIntUse:
1572             setStrictInt52(
1573                 jsValueToStrictInt52(
1574                     m_node->child1(), lowJSValue(m_node->child1(), ManualOperandSpeculation)));
1575             return;
1576             
1577         case DoubleRepAnyIntUse:
1578             setStrictInt52(
1579                 doubleToStrictInt52(
1580                     m_node->child1(), lowDouble(m_node->child1())));
1581             return;
1582             
1583         default:
1584             RELEASE_ASSERT_NOT_REACHED();
1585         }
1586     }
1587     
1588     void compileValueToInt32()
1589     {
1590         switch (m_node->child1().useKind()) {
1591         case Int52RepUse:
1592             setInt32(m_out.castToInt32(lowStrictInt52(m_node->child1())));
1593             break;
1594             
1595         case DoubleRepUse:
1596             setInt32(doubleToInt32(lowDouble(m_node->child1())));
1597             break;
1598             
1599         case NumberUse:
1600         case NotCellUse: {
1601             LoweredNodeValue value = m_int32Values.get(m_node->child1().node());
1602             if (isValid(value)) {
1603                 setInt32(value.value());
1604                 break;
1605             }
1606             
1607             value = m_jsValueValues.get(m_node->child1().node());
1608             if (isValid(value)) {
1609                 setInt32(numberOrNotCellToInt32(m_node->child1(), value.value()));
1610                 break;
1611             }
1612             
1613             // We'll basically just get here for constants. But it's good to have this
1614             // catch-all since we often add new representations into the mix.
1615             setInt32(
1616                 numberOrNotCellToInt32(
1617                     m_node->child1(),
1618                     lowJSValue(m_node->child1(), ManualOperandSpeculation)));
1619             break;
1620         }
1621             
1622         default:
1623             DFG_CRASH(m_graph, m_node, "Bad use kind");
1624             break;
1625         }
1626     }
1627     
1628     void compileBooleanToNumber()
1629     {
1630         switch (m_node->child1().useKind()) {
1631         case BooleanUse: {
1632             setInt32(m_out.zeroExt(lowBoolean(m_node->child1()), Int32));
1633             return;
1634         }
1635             
1636         case UntypedUse: {
1637             LValue value = lowJSValue(m_node->child1());
1638             
1639             if (!m_interpreter.needsTypeCheck(m_node->child1(), SpecBoolInt32 | SpecBoolean)) {
1640                 setInt32(m_out.bitAnd(m_out.castToInt32(value), m_out.int32One));
1641                 return;
1642             }
1643             
1644             LBasicBlock booleanCase = m_out.newBlock();
1645             LBasicBlock continuation = m_out.newBlock();
1646             
1647             ValueFromBlock notBooleanResult = m_out.anchor(value);
1648             m_out.branch(
1649                 isBoolean(value, provenType(m_node->child1())),
1650                 unsure(booleanCase), unsure(continuation));
1651             
1652             LBasicBlock lastNext = m_out.appendTo(booleanCase, continuation);
1653             ValueFromBlock booleanResult = m_out.anchor(m_out.bitOr(
1654                 m_out.zeroExt(unboxBoolean(value), Int64), m_tagTypeNumber));
1655             m_out.jump(continuation);
1656             
1657             m_out.appendTo(continuation, lastNext);
1658             setJSValue(m_out.phi(Int64, booleanResult, notBooleanResult));
1659             return;
1660         }
1661             
1662         default:
1663             RELEASE_ASSERT_NOT_REACHED();
1664             return;
1665         }
1666     }
1667
1668     void compileExtractOSREntryLocal()
1669     {
1670         EncodedJSValue* buffer = static_cast<EncodedJSValue*>(
1671             m_ftlState.jitCode->ftlForOSREntry()->entryBuffer()->dataBuffer());
1672         setJSValue(m_out.load64(m_out.absolute(buffer + m_node->unlinkedLocal().toLocal())));
1673     }
1674
1675     void compileExtractCatchLocal()
1676     {
1677         EncodedJSValue* buffer = static_cast<EncodedJSValue*>(m_ftlState.jitCode->common.catchOSREntryBuffer->dataBuffer());
1678         setJSValue(m_out.load64(m_out.absolute(buffer + m_node->catchOSREntryIndex())));
1679     }
1680     
1681     void compileGetStack()
1682     {
1683         StackAccessData* data = m_node->stackAccessData();
1684         AbstractValue& value = m_state.variables().operand(data->local);
1685         
1686         DFG_ASSERT(m_graph, m_node, isConcrete(data->format), data->format);
1687         DFG_ASSERT(m_graph, m_node, data->format != FlushedDouble, data->format); // This just happens to not arise for GetStacks, right now. It would be trivial to support.
1688         
1689         if (isInt32Speculation(value.m_type))
1690             setInt32(m_out.load32(payloadFor(data->machineLocal)));
1691         else
1692             setJSValue(m_out.load64(addressFor(data->machineLocal)));
1693     }
1694     
1695     void compilePutStack()
1696     {
1697         StackAccessData* data = m_node->stackAccessData();
1698         switch (data->format) {
1699         case FlushedJSValue: {
1700             LValue value = lowJSValue(m_node->child1());
1701             m_out.store64(value, addressFor(data->machineLocal));
1702             break;
1703         }
1704             
1705         case FlushedDouble: {
1706             LValue value = lowDouble(m_node->child1());
1707             m_out.storeDouble(value, addressFor(data->machineLocal));
1708             break;
1709         }
1710             
1711         case FlushedInt32: {
1712             LValue value = lowInt32(m_node->child1());
1713             m_out.store32(value, payloadFor(data->machineLocal));
1714             break;
1715         }
1716             
1717         case FlushedInt52: {
1718             LValue value = lowInt52(m_node->child1());
1719             m_out.store64(value, addressFor(data->machineLocal));
1720             break;
1721         }
1722             
1723         case FlushedCell: {
1724             LValue value = lowCell(m_node->child1());
1725             m_out.store64(value, addressFor(data->machineLocal));
1726             break;
1727         }
1728             
1729         case FlushedBoolean: {
1730             speculateBoolean(m_node->child1());
1731             m_out.store64(
1732                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
1733                 addressFor(data->machineLocal));
1734             break;
1735         }
1736             
1737         default:
1738             DFG_CRASH(m_graph, m_node, "Bad flush format");
1739             break;
1740         }
1741     }
1742     
1743     void compileNoOp()
1744     {
1745         DFG_NODE_DO_TO_CHILDREN(m_graph, m_node, speculate);
1746     }
1747
1748     void compileToObjectOrCallObjectConstructor()
1749     {
1750         LValue value = lowJSValue(m_node->child1());
1751
1752         LBasicBlock isCellCase = m_out.newBlock();
1753         LBasicBlock slowCase = m_out.newBlock();
1754         LBasicBlock continuation = m_out.newBlock();
1755
1756         m_out.branch(isCell(value, provenType(m_node->child1())), usually(isCellCase), rarely(slowCase));
1757
1758         LBasicBlock lastNext = m_out.appendTo(isCellCase, slowCase);
1759         ValueFromBlock fastResult = m_out.anchor(value);
1760         m_out.branch(isObject(value), usually(continuation), rarely(slowCase));
1761
1762         m_out.appendTo(slowCase, continuation);
1763
1764         ValueFromBlock slowResult;
1765         if (m_node->op() == ToObject) {
1766             auto* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
1767             slowResult = m_out.anchor(vmCall(Int64, m_out.operation(operationToObject), m_callFrame, weakPointer(globalObject), value, m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()])));
1768         } else
1769             slowResult = m_out.anchor(vmCall(Int64, m_out.operation(operationCallObjectConstructor), m_callFrame, frozenPointer(m_node->cellOperand()), value));
1770         m_out.jump(continuation);
1771
1772         m_out.appendTo(continuation, lastNext);
1773         setJSValue(m_out.phi(Int64, fastResult, slowResult));
1774     }
1775     
1776     void compileToThis()
1777     {
1778         LValue value = lowJSValue(m_node->child1());
1779         
1780         LBasicBlock isCellCase = m_out.newBlock();
1781         LBasicBlock slowCase = m_out.newBlock();
1782         LBasicBlock continuation = m_out.newBlock();
1783         
1784         m_out.branch(
1785             isCell(value, provenType(m_node->child1())), usually(isCellCase), rarely(slowCase));
1786         
1787         LBasicBlock lastNext = m_out.appendTo(isCellCase, slowCase);
1788         ValueFromBlock fastResult = m_out.anchor(value);
1789         m_out.branch(
1790             m_out.testIsZero32(
1791                 m_out.load8ZeroExt32(value, m_heaps.JSCell_typeInfoFlags),
1792                 m_out.constInt32(OverridesToThis)),
1793             usually(continuation), rarely(slowCase));
1794         
1795         m_out.appendTo(slowCase, continuation);
1796         J_JITOperation_EJ function;
1797         if (m_graph.isStrictModeFor(m_node->origin.semantic))
1798             function = operationToThisStrict;
1799         else
1800             function = operationToThis;
1801         ValueFromBlock slowResult = m_out.anchor(
1802             vmCall(Int64, m_out.operation(function), m_callFrame, value));
1803         m_out.jump(continuation);
1804         
1805         m_out.appendTo(continuation, lastNext);
1806         setJSValue(m_out.phi(Int64, fastResult, slowResult));
1807     }
1808
1809     void compileValueAdd()
1810     {
1811         CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic);
1812         ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(m_node->origin.semantic.bytecodeIndex);
1813         Instruction* instruction = &baselineCodeBlock->instructions()[m_node->origin.semantic.bytecodeIndex];
1814         auto repatchingFunction = operationValueAddOptimize;
1815         auto nonRepatchingFunction = operationValueAdd;
1816         compileBinaryMathIC<JITAddGenerator>(arithProfile, instruction, repatchingFunction, nonRepatchingFunction);
1817     }
1818
1819     template <typename Generator, typename Func1, typename Func2,
1820         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>>
1821     void compileUnaryMathIC(ArithProfile* arithProfile, Instruction* instruction, Func1 repatchingFunction, Func2 nonRepatchingFunction)
1822     {
1823         Node* node = m_node;
1824
1825         LValue operand = lowJSValue(node->child1());
1826
1827         PatchpointValue* patchpoint = m_out.patchpoint(Int64);
1828         patchpoint->appendSomeRegister(operand);
1829         patchpoint->append(m_tagMask, ValueRep::lateReg(GPRInfo::tagMaskRegister));
1830         patchpoint->append(m_tagTypeNumber, ValueRep::lateReg(GPRInfo::tagTypeNumberRegister));
1831         RefPtr<PatchpointExceptionHandle> exceptionHandle = preparePatchpointForExceptions(patchpoint);
1832         patchpoint->numGPScratchRegisters = 1;
1833         patchpoint->clobber(RegisterSet::macroScratchRegisters());
1834         State* state = &m_ftlState;
1835         patchpoint->setGenerator(
1836             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
1837                 AllowMacroScratchRegisterUsage allowScratch(jit);
1838
1839                 Box<CCallHelpers::JumpList> exceptions =
1840                     exceptionHandle->scheduleExitCreation(params)->jumps(jit);
1841
1842 #if ENABLE(MATH_IC_STATS)
1843                 auto inlineStart = jit.label();
1844 #endif
1845
1846                 Box<MathICGenerationState> mathICGenerationState = Box<MathICGenerationState>::create();
1847                 JITUnaryMathIC<Generator>* mathIC = jit.codeBlock()->addMathIC<Generator>(arithProfile, instruction);
1848                 mathIC->m_generator = Generator(JSValueRegs(params[0].gpr()), JSValueRegs(params[1].gpr()), params.gpScratch(0));
1849
1850                 bool shouldEmitProfiling = false;
1851                 bool generatedInline = mathIC->generateInline(jit, *mathICGenerationState, shouldEmitProfiling);
1852
1853                 if (generatedInline) {
1854                     ASSERT(!mathICGenerationState->slowPathJumps.empty());
1855                     auto done = jit.label();
1856                     params.addLatePath([=] (CCallHelpers& jit) {
1857                         AllowMacroScratchRegisterUsage allowScratch(jit);
1858                         mathICGenerationState->slowPathJumps.link(&jit);
1859                         mathICGenerationState->slowPathStart = jit.label();
1860 #if ENABLE(MATH_IC_STATS)
1861                         auto slowPathStart = jit.label();
1862 #endif
1863
1864                         if (mathICGenerationState->shouldSlowPathRepatch) {
1865                             SlowPathCall call = callOperation(*state, params.unavailableRegisters(), jit, node->origin.semantic, exceptions.get(),
1866                                 repatchingFunction, params[0].gpr(), params[1].gpr(), CCallHelpers::TrustedImmPtr(mathIC));
1867                             mathICGenerationState->slowPathCall = call.call();
1868                         } else {
1869                             SlowPathCall call = callOperation(*state, params.unavailableRegisters(), jit, node->origin.semantic,
1870                                 exceptions.get(), nonRepatchingFunction, params[0].gpr(), params[1].gpr());
1871                             mathICGenerationState->slowPathCall = call.call();
1872                         }
1873                         jit.jump().linkTo(done, &jit);
1874
1875                         jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1876                             mathIC->finalizeInlineCode(*mathICGenerationState, linkBuffer);
1877                         });
1878
1879 #if ENABLE(MATH_IC_STATS)
1880                         auto slowPathEnd = jit.label();
1881                         jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1882                             size_t size = linkBuffer.locationOf(slowPathEnd).executableAddress<char*>() - linkBuffer.locationOf(slowPathStart).executableAddress<char*>();
1883                             mathIC->m_generatedCodeSize += size;
1884                         });
1885 #endif
1886                     });
1887                 } else {
1888                     callOperation(
1889                         *state, params.unavailableRegisters(), jit, node->origin.semantic, exceptions.get(),
1890                         nonRepatchingFunction, params[0].gpr(), params[1].gpr());
1891                 }
1892
1893 #if ENABLE(MATH_IC_STATS)
1894                 auto inlineEnd = jit.label();
1895                 jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1896                     size_t size = linkBuffer.locationOf(inlineEnd).executableAddress<char*>() - linkBuffer.locationOf(inlineStart).executableAddress<char*>();
1897                     mathIC->m_generatedCodeSize += size;
1898                 });
1899 #endif
1900             });
1901
1902         setJSValue(patchpoint);
1903     }
1904
1905     template <typename Generator, typename Func1, typename Func2,
1906         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>>
1907     void compileBinaryMathIC(ArithProfile* arithProfile, Instruction* instruction, Func1 repatchingFunction, Func2 nonRepatchingFunction)
1908     {
1909         Node* node = m_node;
1910         
1911         LValue left = lowJSValue(node->child1());
1912         LValue right = lowJSValue(node->child2());
1913
1914         SnippetOperand leftOperand(m_state.forNode(node->child1()).resultType());
1915         SnippetOperand rightOperand(m_state.forNode(node->child2()).resultType());
1916             
1917         PatchpointValue* patchpoint = m_out.patchpoint(Int64);
1918         patchpoint->appendSomeRegister(left);
1919         patchpoint->appendSomeRegister(right);
1920         patchpoint->append(m_tagMask, ValueRep::lateReg(GPRInfo::tagMaskRegister));
1921         patchpoint->append(m_tagTypeNumber, ValueRep::lateReg(GPRInfo::tagTypeNumberRegister));
1922         RefPtr<PatchpointExceptionHandle> exceptionHandle =
1923             preparePatchpointForExceptions(patchpoint);
1924         patchpoint->numGPScratchRegisters = 1;
1925         patchpoint->numFPScratchRegisters = 2;
1926         patchpoint->clobber(RegisterSet::macroScratchRegisters());
1927         State* state = &m_ftlState;
1928         patchpoint->setGenerator(
1929             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
1930                 AllowMacroScratchRegisterUsage allowScratch(jit);
1931
1932
1933                 Box<CCallHelpers::JumpList> exceptions =
1934                     exceptionHandle->scheduleExitCreation(params)->jumps(jit);
1935
1936 #if ENABLE(MATH_IC_STATS)
1937                 auto inlineStart = jit.label();
1938 #endif
1939
1940                 Box<MathICGenerationState> mathICGenerationState = Box<MathICGenerationState>::create();
1941                 JITBinaryMathIC<Generator>* mathIC = jit.codeBlock()->addMathIC<Generator>(arithProfile, instruction);
1942                 mathIC->m_generator = Generator(leftOperand, rightOperand, JSValueRegs(params[0].gpr()),
1943                     JSValueRegs(params[1].gpr()), JSValueRegs(params[2].gpr()), params.fpScratch(0),
1944                     params.fpScratch(1), params.gpScratch(0), InvalidFPRReg);
1945
1946                 bool shouldEmitProfiling = false;
1947                 bool generatedInline = mathIC->generateInline(jit, *mathICGenerationState, shouldEmitProfiling);
1948
1949                 if (generatedInline) {
1950                     ASSERT(!mathICGenerationState->slowPathJumps.empty());
1951                     auto done = jit.label();
1952                     params.addLatePath([=] (CCallHelpers& jit) {
1953                         AllowMacroScratchRegisterUsage allowScratch(jit);
1954                         mathICGenerationState->slowPathJumps.link(&jit);
1955                         mathICGenerationState->slowPathStart = jit.label();
1956 #if ENABLE(MATH_IC_STATS)
1957                         auto slowPathStart = jit.label();
1958 #endif
1959
1960                         if (mathICGenerationState->shouldSlowPathRepatch) {
1961                             SlowPathCall call = callOperation(*state, params.unavailableRegisters(), jit, node->origin.semantic, exceptions.get(),
1962                                 repatchingFunction, params[0].gpr(), params[1].gpr(), params[2].gpr(), CCallHelpers::TrustedImmPtr(mathIC));
1963                             mathICGenerationState->slowPathCall = call.call();
1964                         } else {
1965                             SlowPathCall call = callOperation(*state, params.unavailableRegisters(), jit, node->origin.semantic,
1966                                 exceptions.get(), nonRepatchingFunction, params[0].gpr(), params[1].gpr(), params[2].gpr());
1967                             mathICGenerationState->slowPathCall = call.call();
1968                         }
1969                         jit.jump().linkTo(done, &jit);
1970
1971                         jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1972                             mathIC->finalizeInlineCode(*mathICGenerationState, linkBuffer);
1973                         });
1974
1975 #if ENABLE(MATH_IC_STATS)
1976                         auto slowPathEnd = jit.label();
1977                         jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1978                             size_t size = linkBuffer.locationOf(slowPathEnd).executableAddress<char*>() - linkBuffer.locationOf(slowPathStart).executableAddress<char*>();
1979                             mathIC->m_generatedCodeSize += size;
1980                         });
1981 #endif
1982                     });
1983                 } else {
1984                     callOperation(
1985                         *state, params.unavailableRegisters(), jit, node->origin.semantic, exceptions.get(),
1986                         nonRepatchingFunction, params[0].gpr(), params[1].gpr(), params[2].gpr());
1987                 }
1988
1989 #if ENABLE(MATH_IC_STATS)
1990                 auto inlineEnd = jit.label();
1991                 jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1992                     size_t size = linkBuffer.locationOf(inlineEnd).executableAddress<char*>() - linkBuffer.locationOf(inlineStart).executableAddress<char*>();
1993                     mathIC->m_generatedCodeSize += size;
1994                 });
1995 #endif
1996             });
1997
1998         setJSValue(patchpoint);
1999     }
2000     
2001     void compileStrCat()
2002     {
2003         LValue result;
2004         if (m_node->child3()) {
2005             result = vmCall(
2006                 Int64, m_out.operation(operationStrCat3), m_callFrame,
2007                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
2008                 lowJSValue(m_node->child2(), ManualOperandSpeculation),
2009                 lowJSValue(m_node->child3(), ManualOperandSpeculation));
2010         } else {
2011             result = vmCall(
2012                 Int64, m_out.operation(operationStrCat2), m_callFrame,
2013                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
2014                 lowJSValue(m_node->child2(), ManualOperandSpeculation));
2015         }
2016         setJSValue(result);
2017     }
2018     
2019     void compileArithAddOrSub()
2020     {
2021         bool isSub =  m_node->op() == ArithSub;
2022         switch (m_node->binaryUseKind()) {
2023         case Int32Use: {
2024             LValue left = lowInt32(m_node->child1());
2025             LValue right = lowInt32(m_node->child2());
2026
2027             if (!shouldCheckOverflow(m_node->arithMode())) {
2028                 setInt32(isSub ? m_out.sub(left, right) : m_out.add(left, right));
2029                 break;
2030             }
2031
2032             CheckValue* result =
2033                 isSub ? m_out.speculateSub(left, right) : m_out.speculateAdd(left, right);
2034             blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);
2035             setInt32(result);
2036             break;
2037         }
2038             
2039         case Int52RepUse: {
2040             if (!abstractValue(m_node->child1()).couldBeType(SpecInt52Only)
2041                 && !abstractValue(m_node->child2()).couldBeType(SpecInt52Only)) {
2042                 Int52Kind kind;
2043                 LValue left = lowWhicheverInt52(m_node->child1(), kind);
2044                 LValue right = lowInt52(m_node->child2(), kind);
2045                 setInt52(isSub ? m_out.sub(left, right) : m_out.add(left, right), kind);
2046                 break;
2047             }
2048
2049             LValue left = lowInt52(m_node->child1());
2050             LValue right = lowInt52(m_node->child2());
2051             CheckValue* result =
2052                 isSub ? m_out.speculateSub(left, right) : m_out.speculateAdd(left, right);
2053             blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);
2054             setInt52(result);
2055             break;
2056         }
2057             
2058         case DoubleRepUse: {
2059             LValue C1 = lowDouble(m_node->child1());
2060             LValue C2 = lowDouble(m_node->child2());
2061
2062             setDouble(isSub ? m_out.doubleSub(C1, C2) : m_out.doubleAdd(C1, C2));
2063             break;
2064         }
2065
2066         case UntypedUse: {
2067             if (!isSub) {
2068                 DFG_CRASH(m_graph, m_node, "Bad use kind");
2069                 break;
2070             }
2071
2072             CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic);
2073             ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(m_node->origin.semantic.bytecodeIndex);
2074             Instruction* instruction = &baselineCodeBlock->instructions()[m_node->origin.semantic.bytecodeIndex];
2075             auto repatchingFunction = operationValueSubOptimize;
2076             auto nonRepatchingFunction = operationValueSub;
2077             compileBinaryMathIC<JITSubGenerator>(arithProfile, instruction, repatchingFunction, nonRepatchingFunction);
2078             break;
2079         }
2080
2081         default:
2082             DFG_CRASH(m_graph, m_node, "Bad use kind");
2083             break;
2084         }
2085     }
2086
2087     void compileArithClz32()
2088     {
2089         if (m_node->child1().useKind() == Int32Use || m_node->child1().useKind() == KnownInt32Use) {
2090             LValue operand = lowInt32(m_node->child1());
2091             setInt32(m_out.ctlz32(operand));
2092             return;
2093         }
2094         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse, m_node->child1().useKind());
2095         LValue argument = lowJSValue(m_node->child1());
2096         LValue result = vmCall(Int32, m_out.operation(operationArithClz32), m_callFrame, argument);
2097         setInt32(result);
2098     }
2099     
2100     void compileArithMul()
2101     {
2102         switch (m_node->binaryUseKind()) {
2103         case Int32Use: {
2104             LValue left = lowInt32(m_node->child1());
2105             LValue right = lowInt32(m_node->child2());
2106             
2107             LValue result;
2108
2109             if (!shouldCheckOverflow(m_node->arithMode()))
2110                 result = m_out.mul(left, right);
2111             else {
2112                 CheckValue* speculation = m_out.speculateMul(left, right);
2113                 blessSpeculation(speculation, Overflow, noValue(), nullptr, m_origin);
2114                 result = speculation;
2115             }
2116             
2117             if (shouldCheckNegativeZero(m_node->arithMode())) {
2118                 LBasicBlock slowCase = m_out.newBlock();
2119                 LBasicBlock continuation = m_out.newBlock();
2120                 
2121                 m_out.branch(
2122                     m_out.notZero32(result), usually(continuation), rarely(slowCase));
2123                 
2124                 LBasicBlock lastNext = m_out.appendTo(slowCase, continuation);
2125                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(left, m_out.int32Zero));
2126                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(right, m_out.int32Zero));
2127                 m_out.jump(continuation);
2128                 m_out.appendTo(continuation, lastNext);
2129             }
2130             
2131             setInt32(result);
2132             break;
2133         }
2134             
2135         case Int52RepUse: {
2136             Int52Kind kind;
2137             LValue left = lowWhicheverInt52(m_node->child1(), kind);
2138             LValue right = lowInt52(m_node->child2(), opposite(kind));
2139
2140             CheckValue* result = m_out.speculateMul(left, right);
2141             blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);
2142
2143             if (shouldCheckNegativeZero(m_node->arithMode())) {
2144                 LBasicBlock slowCase = m_out.newBlock();
2145                 LBasicBlock continuation = m_out.newBlock();
2146                 
2147                 m_out.branch(
2148                     m_out.notZero64(result), usually(continuation), rarely(slowCase));
2149                 
2150                 LBasicBlock lastNext = m_out.appendTo(slowCase, continuation);
2151                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(left, m_out.int64Zero));
2152                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(right, m_out.int64Zero));
2153                 m_out.jump(continuation);
2154                 m_out.appendTo(continuation, lastNext);
2155             }
2156             
2157             setInt52(result);
2158             break;
2159         }
2160             
2161         case DoubleRepUse: {
2162             setDouble(
2163                 m_out.doubleMul(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
2164             break;
2165         }
2166
2167         case UntypedUse: {
2168             CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic);
2169             ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(m_node->origin.semantic.bytecodeIndex);
2170             Instruction* instruction = &baselineCodeBlock->instructions()[m_node->origin.semantic.bytecodeIndex];
2171             auto repatchingFunction = operationValueMulOptimize;
2172             auto nonRepatchingFunction = operationValueMul;
2173             compileBinaryMathIC<JITMulGenerator>(arithProfile, instruction, repatchingFunction, nonRepatchingFunction);
2174             break;
2175         }
2176
2177         default:
2178             DFG_CRASH(m_graph, m_node, "Bad use kind");
2179             break;
2180         }
2181     }
2182
2183     void compileArithDiv()
2184     {
2185         switch (m_node->binaryUseKind()) {
2186         case Int32Use: {
2187             LValue numerator = lowInt32(m_node->child1());
2188             LValue denominator = lowInt32(m_node->child2());
2189
2190             if (shouldCheckNegativeZero(m_node->arithMode())) {
2191                 LBasicBlock zeroNumerator = m_out.newBlock();
2192                 LBasicBlock numeratorContinuation = m_out.newBlock();
2193
2194                 m_out.branch(
2195                     m_out.isZero32(numerator),
2196                     rarely(zeroNumerator), usually(numeratorContinuation));
2197
2198                 LBasicBlock innerLastNext = m_out.appendTo(zeroNumerator, numeratorContinuation);
2199
2200                 speculate(
2201                     NegativeZero, noValue(), 0, m_out.lessThan(denominator, m_out.int32Zero));
2202
2203                 m_out.jump(numeratorContinuation);
2204
2205                 m_out.appendTo(numeratorContinuation, innerLastNext);
2206             }
2207             
2208             if (shouldCheckOverflow(m_node->arithMode())) {
2209                 LBasicBlock unsafeDenominator = m_out.newBlock();
2210                 LBasicBlock continuation = m_out.newBlock();
2211
2212                 LValue adjustedDenominator = m_out.add(denominator, m_out.int32One);
2213                 m_out.branch(
2214                     m_out.above(adjustedDenominator, m_out.int32One),
2215                     usually(continuation), rarely(unsafeDenominator));
2216
2217                 LBasicBlock lastNext = m_out.appendTo(unsafeDenominator, continuation);
2218                 LValue neg2ToThe31 = m_out.constInt32(-2147483647-1);
2219                 speculate(Overflow, noValue(), nullptr, m_out.isZero32(denominator));
2220                 speculate(Overflow, noValue(), nullptr, m_out.equal(numerator, neg2ToThe31));
2221                 m_out.jump(continuation);
2222
2223                 m_out.appendTo(continuation, lastNext);
2224                 LValue result = m_out.div(numerator, denominator);
2225                 speculate(
2226                     Overflow, noValue(), 0,
2227                     m_out.notEqual(m_out.mul(result, denominator), numerator));
2228                 setInt32(result);
2229             } else
2230                 setInt32(m_out.chillDiv(numerator, denominator));
2231
2232             break;
2233         }
2234             
2235         case DoubleRepUse: {
2236             setDouble(m_out.doubleDiv(
2237                 lowDouble(m_node->child1()), lowDouble(m_node->child2())));
2238             break;
2239         }
2240
2241         case UntypedUse: {
2242             emitBinarySnippet<JITDivGenerator, NeedScratchFPR>(operationValueDiv);
2243             break;
2244         }
2245
2246         default:
2247             DFG_CRASH(m_graph, m_node, "Bad use kind");
2248             break;
2249         }
2250     }
2251     
2252     void compileArithMod()
2253     {
2254         switch (m_node->binaryUseKind()) {
2255         case Int32Use: {
2256             LValue numerator = lowInt32(m_node->child1());
2257             LValue denominator = lowInt32(m_node->child2());
2258
2259             LValue remainder;
2260             if (shouldCheckOverflow(m_node->arithMode())) {
2261                 LBasicBlock unsafeDenominator = m_out.newBlock();
2262                 LBasicBlock continuation = m_out.newBlock();
2263
2264                 LValue adjustedDenominator = m_out.add(denominator, m_out.int32One);
2265                 m_out.branch(
2266                     m_out.above(adjustedDenominator, m_out.int32One),
2267                     usually(continuation), rarely(unsafeDenominator));
2268
2269                 LBasicBlock lastNext = m_out.appendTo(unsafeDenominator, continuation);
2270                 LValue neg2ToThe31 = m_out.constInt32(-2147483647-1);
2271                 speculate(Overflow, noValue(), nullptr, m_out.isZero32(denominator));
2272                 speculate(Overflow, noValue(), nullptr, m_out.equal(numerator, neg2ToThe31));
2273                 m_out.jump(continuation);
2274
2275                 m_out.appendTo(continuation, lastNext);
2276                 LValue result = m_out.mod(numerator, denominator);
2277                 remainder = result;
2278             } else
2279                 remainder = m_out.chillMod(numerator, denominator);
2280
2281             if (shouldCheckNegativeZero(m_node->arithMode())) {
2282                 LBasicBlock negativeNumerator = m_out.newBlock();
2283                 LBasicBlock numeratorContinuation = m_out.newBlock();
2284
2285                 m_out.branch(
2286                     m_out.lessThan(numerator, m_out.int32Zero),
2287                     unsure(negativeNumerator), unsure(numeratorContinuation));
2288
2289                 LBasicBlock innerLastNext = m_out.appendTo(negativeNumerator, numeratorContinuation);
2290
2291                 speculate(NegativeZero, noValue(), 0, m_out.isZero32(remainder));
2292
2293                 m_out.jump(numeratorContinuation);
2294
2295                 m_out.appendTo(numeratorContinuation, innerLastNext);
2296             }
2297
2298             setInt32(remainder);
2299             break;
2300         }
2301             
2302         case DoubleRepUse: {
2303             setDouble(
2304                 m_out.doubleMod(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
2305             break;
2306         }
2307             
2308         default:
2309             DFG_CRASH(m_graph, m_node, "Bad use kind");
2310             break;
2311         }
2312     }
2313
2314     void compileArithMinOrMax()
2315     {
2316         switch (m_node->binaryUseKind()) {
2317         case Int32Use: {
2318             LValue left = lowInt32(m_node->child1());
2319             LValue right = lowInt32(m_node->child2());
2320             
2321             setInt32(
2322                 m_out.select(
2323                     m_node->op() == ArithMin
2324                         ? m_out.lessThan(left, right)
2325                         : m_out.lessThan(right, left),
2326                     left, right));
2327             break;
2328         }
2329             
2330         case DoubleRepUse: {
2331             LValue left = lowDouble(m_node->child1());
2332             LValue right = lowDouble(m_node->child2());
2333             
2334             LBasicBlock notLessThan = m_out.newBlock();
2335             LBasicBlock continuation = m_out.newBlock();
2336             
2337             Vector<ValueFromBlock, 2> results;
2338             
2339             results.append(m_out.anchor(left));
2340             m_out.branch(
2341                 m_node->op() == ArithMin
2342                     ? m_out.doubleLessThan(left, right)
2343                     : m_out.doubleGreaterThan(left, right),
2344                 unsure(continuation), unsure(notLessThan));
2345             
2346             LBasicBlock lastNext = m_out.appendTo(notLessThan, continuation);
2347             results.append(m_out.anchor(m_out.select(
2348                 m_node->op() == ArithMin
2349                     ? m_out.doubleGreaterThanOrEqual(left, right)
2350                     : m_out.doubleLessThanOrEqual(left, right),
2351                 right, m_out.constDouble(PNaN))));
2352             m_out.jump(continuation);
2353             
2354             m_out.appendTo(continuation, lastNext);
2355             setDouble(m_out.phi(Double, results));
2356             break;
2357         }
2358             
2359         default:
2360             DFG_CRASH(m_graph, m_node, "Bad use kind");
2361             break;
2362         }
2363     }
2364     
2365     void compileArithAbs()
2366     {
2367         switch (m_node->child1().useKind()) {
2368         case Int32Use: {
2369             LValue value = lowInt32(m_node->child1());
2370
2371             LValue mask = m_out.aShr(value, m_out.constInt32(31));
2372             LValue result = m_out.bitXor(mask, m_out.add(mask, value));
2373
2374             if (shouldCheckOverflow(m_node->arithMode()))
2375                 speculate(Overflow, noValue(), 0, m_out.lessThan(result, m_out.int32Zero));
2376
2377             setInt32(result);
2378             break;
2379         }
2380             
2381         case DoubleRepUse: {
2382             setDouble(m_out.doubleAbs(lowDouble(m_node->child1())));
2383             break;
2384         }
2385             
2386         default: {
2387             DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse, m_node->child1().useKind());
2388             LValue argument = lowJSValue(m_node->child1());
2389             LValue result = vmCall(Double, m_out.operation(operationArithAbs), m_callFrame, argument);
2390             setDouble(result);
2391             break;
2392         }
2393         }
2394     }
2395
2396     void compileArithUnary()
2397     {
2398         if (m_node->child1().useKind() == DoubleRepUse) {
2399             setDouble(m_out.doubleUnary(m_node->arithUnaryType(), lowDouble(m_node->child1())));
2400             return;
2401         }
2402         LValue argument = lowJSValue(m_node->child1());
2403         LValue result = vmCall(Double, m_out.operation(DFG::arithUnaryOperation(m_node->arithUnaryType())), m_callFrame, argument);
2404         setDouble(result);
2405     }
2406
2407     void compileArithPow()
2408     {
2409         if (m_node->child2().useKind() == Int32Use)
2410             setDouble(m_out.doublePowi(lowDouble(m_node->child1()), lowInt32(m_node->child2())));
2411         else {
2412             LValue base = lowDouble(m_node->child1());
2413             LValue exponent = lowDouble(m_node->child2());
2414
2415             LBasicBlock integerExponentIsSmallBlock = m_out.newBlock();
2416             LBasicBlock integerExponentPowBlock = m_out.newBlock();
2417             LBasicBlock doubleExponentPowBlockEntry = m_out.newBlock();
2418             LBasicBlock nanExceptionBaseIsOne = m_out.newBlock();
2419             LBasicBlock nanExceptionExponentIsInfinity = m_out.newBlock();
2420             LBasicBlock testExponentIsOneHalf = m_out.newBlock();
2421             LBasicBlock handleBaseZeroExponentIsOneHalf = m_out.newBlock();
2422             LBasicBlock handleInfinityForExponentIsOneHalf = m_out.newBlock();
2423             LBasicBlock exponentIsOneHalfNormal = m_out.newBlock();
2424             LBasicBlock exponentIsOneHalfInfinity = m_out.newBlock();
2425             LBasicBlock testExponentIsNegativeOneHalf = m_out.newBlock();
2426             LBasicBlock testBaseZeroExponentIsNegativeOneHalf = m_out.newBlock();
2427             LBasicBlock handleBaseZeroExponentIsNegativeOneHalf = m_out.newBlock();
2428             LBasicBlock handleInfinityForExponentIsNegativeOneHalf = m_out.newBlock();
2429             LBasicBlock exponentIsNegativeOneHalfNormal = m_out.newBlock();
2430             LBasicBlock exponentIsNegativeOneHalfInfinity = m_out.newBlock();
2431             LBasicBlock powBlock = m_out.newBlock();
2432             LBasicBlock nanExceptionResultIsNaN = m_out.newBlock();
2433             LBasicBlock continuation = m_out.newBlock();
2434
2435             LValue integerExponent = m_out.doubleToInt(exponent);
2436             LValue integerExponentConvertedToDouble = m_out.intToDouble(integerExponent);
2437             LValue exponentIsInteger = m_out.doubleEqual(exponent, integerExponentConvertedToDouble);
2438             m_out.branch(exponentIsInteger, unsure(integerExponentIsSmallBlock), unsure(doubleExponentPowBlockEntry));
2439
2440             LBasicBlock lastNext = m_out.appendTo(integerExponentIsSmallBlock, integerExponentPowBlock);
2441             LValue integerExponentBelowMax = m_out.belowOrEqual(integerExponent, m_out.constInt32(maxExponentForIntegerMathPow));
2442             m_out.branch(integerExponentBelowMax, usually(integerExponentPowBlock), rarely(doubleExponentPowBlockEntry));
2443
2444             m_out.appendTo(integerExponentPowBlock, doubleExponentPowBlockEntry);
2445             ValueFromBlock powDoubleIntResult = m_out.anchor(m_out.doublePowi(base, integerExponent));
2446             m_out.jump(continuation);
2447
2448             // If y is NaN, the result is NaN.
2449             m_out.appendTo(doubleExponentPowBlockEntry, nanExceptionBaseIsOne);
2450             LValue exponentIsNaN;
2451             if (provenType(m_node->child2()) & SpecDoubleNaN)
2452                 exponentIsNaN = m_out.doubleNotEqualOrUnordered(exponent, exponent);
2453             else
2454                 exponentIsNaN = m_out.booleanFalse;
2455             m_out.branch(exponentIsNaN, rarely(nanExceptionResultIsNaN), usually(nanExceptionBaseIsOne));
2456
2457             // If abs(x) is 1 and y is +infinity, the result is NaN.
2458             // If abs(x) is 1 and y is -infinity, the result is NaN.
2459
2460             //     Test if base == 1.
2461             m_out.appendTo(nanExceptionBaseIsOne, nanExceptionExponentIsInfinity);
2462             LValue absoluteBase = m_out.doubleAbs(base);
2463             LValue absoluteBaseIsOne = m_out.doubleEqual(absoluteBase, m_out.constDouble(1));
2464             m_out.branch(absoluteBaseIsOne, rarely(nanExceptionExponentIsInfinity), usually(testExponentIsOneHalf));
2465
2466             //     Test if abs(y) == Infinity.
2467             m_out.appendTo(nanExceptionExponentIsInfinity, testExponentIsOneHalf);
2468             LValue absoluteExponent = m_out.doubleAbs(exponent);
2469             LValue absoluteExponentIsInfinity = m_out.doubleEqual(absoluteExponent, m_out.constDouble(std::numeric_limits<double>::infinity()));
2470             m_out.branch(absoluteExponentIsInfinity, rarely(nanExceptionResultIsNaN), usually(testExponentIsOneHalf));
2471
2472             // If y == 0.5 or y == -0.5, handle it through SQRT.
2473             // We have be carefuly with -0 and -Infinity.
2474
2475             //     Test if y == 0.5
2476             m_out.appendTo(testExponentIsOneHalf, handleBaseZeroExponentIsOneHalf);
2477             LValue exponentIsOneHalf = m_out.doubleEqual(exponent, m_out.constDouble(0.5));
2478             m_out.branch(exponentIsOneHalf, rarely(handleBaseZeroExponentIsOneHalf), usually(testExponentIsNegativeOneHalf));
2479
2480             //     Handle x == -0.
2481             m_out.appendTo(handleBaseZeroExponentIsOneHalf, handleInfinityForExponentIsOneHalf);
2482             LValue baseIsZeroExponentIsOneHalf = m_out.doubleEqual(base, m_out.doubleZero);
2483             ValueFromBlock zeroResultExponentIsOneHalf = m_out.anchor(m_out.doubleZero);
2484             m_out.branch(baseIsZeroExponentIsOneHalf, rarely(continuation), usually(handleInfinityForExponentIsOneHalf));
2485
2486             //     Test if abs(x) == Infinity.
2487             m_out.appendTo(handleInfinityForExponentIsOneHalf, exponentIsOneHalfNormal);
2488             LValue absoluteBaseIsInfinityOneHalf = m_out.doubleEqual(absoluteBase, m_out.constDouble(std::numeric_limits<double>::infinity()));
2489             m_out.branch(absoluteBaseIsInfinityOneHalf, rarely(exponentIsOneHalfInfinity), usually(exponentIsOneHalfNormal));
2490
2491             //     The exponent is 0.5, the base is finite or NaN, we can use SQRT.
2492             m_out.appendTo(exponentIsOneHalfNormal, exponentIsOneHalfInfinity);
2493             ValueFromBlock sqrtResult = m_out.anchor(m_out.doubleSqrt(base));
2494             m_out.jump(continuation);
2495
2496             //     The exponent is 0.5, the base is infinite, the result is always infinite.
2497             m_out.appendTo(exponentIsOneHalfInfinity, testExponentIsNegativeOneHalf);
2498             ValueFromBlock sqrtInfinityResult = m_out.anchor(m_out.constDouble(std::numeric_limits<double>::infinity()));
2499             m_out.jump(continuation);
2500
2501             //     Test if y == -0.5
2502             m_out.appendTo(testExponentIsNegativeOneHalf, testBaseZeroExponentIsNegativeOneHalf);
2503             LValue exponentIsNegativeOneHalf = m_out.doubleEqual(exponent, m_out.constDouble(-0.5));
2504             m_out.branch(exponentIsNegativeOneHalf, rarely(testBaseZeroExponentIsNegativeOneHalf), usually(powBlock));
2505
2506             //     Handle x == -0.
2507             m_out.appendTo(testBaseZeroExponentIsNegativeOneHalf, handleBaseZeroExponentIsNegativeOneHalf);
2508             LValue baseIsZeroExponentIsNegativeOneHalf = m_out.doubleEqual(base, m_out.doubleZero);
2509             m_out.branch(baseIsZeroExponentIsNegativeOneHalf, rarely(handleBaseZeroExponentIsNegativeOneHalf), usually(handleInfinityForExponentIsNegativeOneHalf));
2510
2511             m_out.appendTo(handleBaseZeroExponentIsNegativeOneHalf, handleInfinityForExponentIsNegativeOneHalf);
2512             ValueFromBlock oneOverSqrtZeroResult = m_out.anchor(m_out.constDouble(std::numeric_limits<double>::infinity()));
2513             m_out.jump(continuation);
2514
2515             //     Test if abs(x) == Infinity.
2516             m_out.appendTo(handleInfinityForExponentIsNegativeOneHalf, exponentIsNegativeOneHalfNormal);
2517             LValue absoluteBaseIsInfinityNegativeOneHalf = m_out.doubleEqual(absoluteBase, m_out.constDouble(std::numeric_limits<double>::infinity()));
2518             m_out.branch(absoluteBaseIsInfinityNegativeOneHalf, rarely(exponentIsNegativeOneHalfInfinity), usually(exponentIsNegativeOneHalfNormal));
2519
2520             //     The exponent is -0.5, the base is finite or NaN, we can use 1/SQRT.
2521             m_out.appendTo(exponentIsNegativeOneHalfNormal, exponentIsNegativeOneHalfInfinity);
2522             LValue sqrtBase = m_out.doubleSqrt(base);
2523             ValueFromBlock oneOverSqrtResult = m_out.anchor(m_out.div(m_out.constDouble(1.), sqrtBase));
2524             m_out.jump(continuation);
2525
2526             //     The exponent is -0.5, the base is infinite, the result is always zero.
2527             m_out.appendTo(exponentIsNegativeOneHalfInfinity, powBlock);
2528             ValueFromBlock oneOverSqrtInfinityResult = m_out.anchor(m_out.doubleZero);
2529             m_out.jump(continuation);
2530
2531             m_out.appendTo(powBlock, nanExceptionResultIsNaN);
2532             ValueFromBlock powResult = m_out.anchor(m_out.doublePow(base, exponent));
2533             m_out.jump(continuation);
2534
2535             m_out.appendTo(nanExceptionResultIsNaN, continuation);
2536             ValueFromBlock pureNan = m_out.anchor(m_out.constDouble(PNaN));
2537             m_out.jump(continuation);
2538
2539             m_out.appendTo(continuation, lastNext);
2540             setDouble(m_out.phi(Double, powDoubleIntResult, zeroResultExponentIsOneHalf, sqrtResult, sqrtInfinityResult, oneOverSqrtZeroResult, oneOverSqrtResult, oneOverSqrtInfinityResult, powResult, pureNan));
2541         }
2542     }
2543
2544     void compileArithRandom()
2545     {
2546         JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
2547
2548         // Inlined WeakRandom::advance().
2549         // uint64_t x = m_low;
2550         void* lowAddress = reinterpret_cast<uint8_t*>(globalObject) + JSGlobalObject::weakRandomOffset() + WeakRandom::lowOffset();
2551         LValue low = m_out.load64(m_out.absolute(lowAddress));
2552         // uint64_t y = m_high;
2553         void* highAddress = reinterpret_cast<uint8_t*>(globalObject) + JSGlobalObject::weakRandomOffset() + WeakRandom::highOffset();
2554         LValue high = m_out.load64(m_out.absolute(highAddress));
2555         // m_low = y;
2556         m_out.store64(high, m_out.absolute(lowAddress));
2557
2558         // x ^= x << 23;
2559         LValue phase1 = m_out.bitXor(m_out.shl(low, m_out.constInt64(23)), low);
2560
2561         // x ^= x >> 17;
2562         LValue phase2 = m_out.bitXor(m_out.lShr(phase1, m_out.constInt64(17)), phase1);
2563
2564         // x ^= y ^ (y >> 26);
2565         LValue phase3 = m_out.bitXor(m_out.bitXor(high, m_out.lShr(high, m_out.constInt64(26))), phase2);
2566
2567         // m_high = x;
2568         m_out.store64(phase3, m_out.absolute(highAddress));
2569
2570         // return x + y;
2571         LValue random64 = m_out.add(phase3, high);
2572
2573         // Extract random 53bit. [0, 53] bit is safe integer number ranges in double representation.
2574         LValue random53 = m_out.bitAnd(random64, m_out.constInt64((1ULL << 53) - 1));
2575
2576         LValue double53Integer = m_out.intToDouble(random53);
2577
2578         // Convert `(53bit double integer value) / (1 << 53)` to `(53bit double integer value) * (1.0 / (1 << 53))`.
2579         // In latter case, `1.0 / (1 << 53)` will become a double value represented as (mantissa = 0 & exp = 970, it means 1e-(2**54)).
2580         static const double scale = 1.0 / (1ULL << 53);
2581
2582         // Multiplying 1e-(2**54) with the double integer does not change anything of the mantissa part of the double integer.
2583         // It just reduces the exp part of the given 53bit double integer.
2584         // (Except for 0.0. This is specially handled and in this case, exp just becomes 0.)
2585         // Now we get 53bit precision random double value in [0, 1).
2586         LValue result = m_out.doubleMul(double53Integer, m_out.constDouble(scale));
2587
2588         setDouble(result);
2589     }
2590
2591     void compileArithRound()
2592     {
2593         if (m_node->child1().useKind() == DoubleRepUse) {
2594             LValue result = nullptr;
2595             if (producesInteger(m_node->arithRoundingMode()) && !shouldCheckNegativeZero(m_node->arithRoundingMode())) {
2596                 LValue value = lowDouble(m_node->child1());
2597                 result = m_out.doubleFloor(m_out.doubleAdd(value, m_out.constDouble(0.5)));
2598             } else {
2599                 LBasicBlock realPartIsMoreThanHalf = m_out.newBlock();
2600                 LBasicBlock continuation = m_out.newBlock();
2601
2602                 LValue value = lowDouble(m_node->child1());
2603                 LValue integerValue = m_out.doubleCeil(value);
2604                 ValueFromBlock integerValueResult = m_out.anchor(integerValue);
2605
2606                 LValue realPart = m_out.doubleSub(integerValue, value);
2607
2608                 m_out.branch(m_out.doubleGreaterThanOrUnordered(realPart, m_out.constDouble(0.5)), unsure(realPartIsMoreThanHalf), unsure(continuation));
2609
2610                 LBasicBlock lastNext = m_out.appendTo(realPartIsMoreThanHalf, continuation);
2611                 LValue integerValueRoundedDown = m_out.doubleSub(integerValue, m_out.constDouble(1));
2612                 ValueFromBlock integerValueRoundedDownResult = m_out.anchor(integerValueRoundedDown);
2613                 m_out.jump(continuation);
2614                 m_out.appendTo(continuation, lastNext);
2615
2616                 result = m_out.phi(Double, integerValueResult, integerValueRoundedDownResult);
2617             }
2618
2619             if (producesInteger(m_node->arithRoundingMode())) {
2620                 LValue integerValue = convertDoubleToInt32(result, shouldCheckNegativeZero(m_node->arithRoundingMode()));
2621                 setInt32(integerValue);
2622             } else
2623                 setDouble(result);
2624             return;
2625         }
2626
2627         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse, m_node->child1().useKind());
2628         LValue argument = lowJSValue(m_node->child1());
2629         setJSValue(vmCall(Int64, m_out.operation(operationArithRound), m_callFrame, argument));
2630     }
2631
2632     void compileArithFloor()
2633     {
2634         if (m_node->child1().useKind() == DoubleRepUse) {
2635             LValue value = lowDouble(m_node->child1());
2636             LValue integerValue = m_out.doubleFloor(value);
2637             if (producesInteger(m_node->arithRoundingMode()))
2638                 setInt32(convertDoubleToInt32(integerValue, shouldCheckNegativeZero(m_node->arithRoundingMode())));
2639             else
2640                 setDouble(integerValue);
2641             return;
2642         }
2643         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse, m_node->child1().useKind());
2644         LValue argument = lowJSValue(m_node->child1());
2645         setJSValue(vmCall(Int64, m_out.operation(operationArithFloor), m_callFrame, argument));
2646     }
2647
2648     void compileArithCeil()
2649     {
2650         if (m_node->child1().useKind() == DoubleRepUse) {
2651             LValue value = lowDouble(m_node->child1());
2652             LValue integerValue = m_out.doubleCeil(value);
2653             if (producesInteger(m_node->arithRoundingMode()))
2654                 setInt32(convertDoubleToInt32(integerValue, shouldCheckNegativeZero(m_node->arithRoundingMode())));
2655             else
2656                 setDouble(integerValue);
2657             return;
2658         }
2659         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse, m_node->child1().useKind());
2660         LValue argument = lowJSValue(m_node->child1());
2661         setJSValue(vmCall(Int64, m_out.operation(operationArithCeil), m_callFrame, argument));
2662     }
2663
2664     void compileArithTrunc()
2665     {
2666         if (m_node->child1().useKind() == DoubleRepUse) {
2667             LValue value = lowDouble(m_node->child1());
2668             LValue result = m_out.doubleTrunc(value);
2669             if (producesInteger(m_node->arithRoundingMode()))
2670                 setInt32(convertDoubleToInt32(result, shouldCheckNegativeZero(m_node->arithRoundingMode())));
2671             else
2672                 setDouble(result);
2673             return;
2674         }
2675         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse, m_node->child1().useKind());
2676         LValue argument = lowJSValue(m_node->child1());
2677         setJSValue(vmCall(Int64, m_out.operation(operationArithTrunc), m_callFrame, argument));
2678     }
2679
2680     void compileArithSqrt()
2681     {
2682         if (m_node->child1().useKind() == DoubleRepUse) {
2683             setDouble(m_out.doubleSqrt(lowDouble(m_node->child1())));
2684             return;
2685         }
2686         LValue argument = lowJSValue(m_node->child1());
2687         LValue result = vmCall(Double, m_out.operation(operationArithSqrt), m_callFrame, argument);
2688         setDouble(result);
2689     }
2690
2691     void compileArithFRound()
2692     {
2693         if (m_node->child1().useKind() == DoubleRepUse) {
2694             setDouble(m_out.fround(lowDouble(m_node->child1())));
2695             return;
2696         }
2697         LValue argument = lowJSValue(m_node->child1());
2698         LValue result = vmCall(Double, m_out.operation(operationArithFRound), m_callFrame, argument);
2699         setDouble(result);
2700     }
2701     
2702     void compileArithNegate()
2703     {
2704         switch (m_node->child1().useKind()) {
2705         case Int32Use: {
2706             LValue value = lowInt32(m_node->child1());
2707             
2708             LValue result;
2709             if (!shouldCheckOverflow(m_node->arithMode()))
2710                 result = m_out.neg(value);
2711             else if (!shouldCheckNegativeZero(m_node->arithMode())) {
2712                 CheckValue* check = m_out.speculateSub(m_out.int32Zero, value);
2713                 blessSpeculation(check, Overflow, noValue(), nullptr, m_origin);
2714                 result = check;
2715             } else {
2716                 speculate(Overflow, noValue(), 0, m_out.testIsZero32(value, m_out.constInt32(0x7fffffff)));
2717                 result = m_out.neg(value);
2718             }
2719
2720             setInt32(result);
2721             break;
2722         }
2723             
2724         case Int52RepUse: {
2725             if (!abstractValue(m_node->child1()).couldBeType(SpecInt52Only)) {
2726                 Int52Kind kind;
2727                 LValue value = lowWhicheverInt52(m_node->child1(), kind);
2728                 LValue result = m_out.neg(value);
2729                 if (shouldCheckNegativeZero(m_node->arithMode()))
2730                     speculate(NegativeZero, noValue(), 0, m_out.isZero64(result));
2731                 setInt52(result, kind);
2732                 break;
2733             }
2734             
2735             LValue value = lowInt52(m_node->child1());
2736             CheckValue* result = m_out.speculateSub(m_out.int64Zero, value);
2737             blessSpeculation(result, Int52Overflow, noValue(), nullptr, m_origin);
2738             if (shouldCheckNegativeZero(m_node->arithMode()))
2739                 speculate(NegativeZero, noValue(), 0, m_out.isZero64(result));
2740             setInt52(result);
2741             break;
2742         }
2743             
2744         case DoubleRepUse: {
2745             setDouble(m_out.doubleNeg(lowDouble(m_node->child1())));
2746             break;
2747         }
2748             
2749         default:
2750             DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse, m_node->child1().useKind());
2751             CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic);
2752             ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(m_node->origin.semantic.bytecodeIndex);
2753             Instruction* instruction = &baselineCodeBlock->instructions()[m_node->origin.semantic.bytecodeIndex];
2754             auto repatchingFunction = operationArithNegateOptimize;
2755             auto nonRepatchingFunction = operationArithNegate;
2756             compileUnaryMathIC<JITNegGenerator>(arithProfile, instruction, repatchingFunction, nonRepatchingFunction);
2757             break;
2758         }
2759     }
2760     
2761     void compileBitAnd()
2762     {
2763         if (m_node->isBinaryUseKind(UntypedUse)) {
2764             emitBinaryBitOpSnippet<JITBitAndGenerator>(operationValueBitAnd);
2765             return;
2766         }
2767         setInt32(m_out.bitAnd(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2768     }
2769     
2770     void compileBitOr()
2771     {
2772         if (m_node->isBinaryUseKind(UntypedUse)) {
2773             emitBinaryBitOpSnippet<JITBitOrGenerator>(operationValueBitOr);
2774             return;
2775         }
2776         setInt32(m_out.bitOr(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2777     }
2778     
2779     void compileBitXor()
2780     {
2781         if (m_node->isBinaryUseKind(UntypedUse)) {
2782             emitBinaryBitOpSnippet<JITBitXorGenerator>(operationValueBitXor);
2783             return;
2784         }
2785         setInt32(m_out.bitXor(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2786     }
2787     
2788     void compileBitRShift()
2789     {
2790         if (m_node->isBinaryUseKind(UntypedUse)) {
2791             emitRightShiftSnippet(JITRightShiftGenerator::SignedShift);
2792             return;
2793         }
2794         setInt32(m_out.aShr(
2795             lowInt32(m_node->child1()),
2796             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2797     }
2798     
2799     void compileBitLShift()
2800     {
2801         if (m_node->isBinaryUseKind(UntypedUse)) {
2802             emitBinaryBitOpSnippet<JITLeftShiftGenerator>(operationValueBitLShift);
2803             return;
2804         }
2805         setInt32(m_out.shl(
2806             lowInt32(m_node->child1()),
2807             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2808     }
2809     
2810     void compileBitURShift()
2811     {
2812         if (m_node->isBinaryUseKind(UntypedUse)) {
2813             emitRightShiftSnippet(JITRightShiftGenerator::UnsignedShift);
2814             return;
2815         }
2816         setInt32(m_out.lShr(
2817             lowInt32(m_node->child1()),
2818             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2819     }
2820     
2821     void compileUInt32ToNumber()
2822     {
2823         LValue value = lowInt32(m_node->child1());
2824
2825         if (doesOverflow(m_node->arithMode())) {
2826             setStrictInt52(m_out.zeroExtPtr(value));
2827             return;
2828         }
2829
2830         speculate(Overflow, noValue(), 0, m_out.lessThan(value, m_out.int32Zero));
2831         setInt32(value);
2832     }
2833     
2834     void compileCheckStructure()
2835     {
2836         ExitKind exitKind;
2837         if (m_node->child1()->hasConstant())
2838             exitKind = BadConstantCache;
2839         else
2840             exitKind = BadCache;
2841
2842         switch (m_node->child1().useKind()) {
2843         case CellUse:
2844         case KnownCellUse: {
2845             LValue cell = lowCell(m_node->child1());
2846             
2847             checkStructure(
2848                 m_out.load32(cell, m_heaps.JSCell_structureID), jsValueValue(cell),
2849                 exitKind, m_node->structureSet(),
2850                 [&] (RegisteredStructure structure) {
2851                     return weakStructureID(structure);
2852                 });
2853             return;
2854         }
2855
2856         case CellOrOtherUse: {
2857             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
2858
2859             LBasicBlock cellCase = m_out.newBlock();
2860             LBasicBlock notCellCase = m_out.newBlock();
2861             LBasicBlock continuation = m_out.newBlock();
2862
2863             m_out.branch(
2864                 isCell(value, provenType(m_node->child1())), unsure(cellCase), unsure(notCellCase));
2865
2866             LBasicBlock lastNext = m_out.appendTo(cellCase, notCellCase);
2867             checkStructure(
2868                 m_out.load32(value, m_heaps.JSCell_structureID), jsValueValue(value),
2869                 exitKind, m_node->structureSet(),
2870                 [&] (RegisteredStructure structure) {
2871                     return weakStructureID(structure);
2872                 });
2873             m_out.jump(continuation);
2874
2875             m_out.appendTo(notCellCase, continuation);
2876             FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), SpecCell | SpecOther, isNotOther(value));
2877             m_out.jump(continuation);
2878
2879             m_out.appendTo(continuation, lastNext);
2880             return;
2881         }
2882
2883         default:
2884             DFG_CRASH(m_graph, m_node, "Bad use kind");
2885             return;
2886         }
2887     }
2888
2889     void compileCheckStructureOrEmpty()
2890     {
2891         ExitKind exitKind;
2892         if (m_node->child1()->hasConstant())
2893             exitKind = BadConstantCache;
2894         else
2895             exitKind = BadCache;
2896
2897         LValue cell = lowCell(m_node->child1());
2898         bool maySeeEmptyValue = m_interpreter.forNode(m_node->child1()).m_type & SpecEmpty;
2899         LBasicBlock notEmpty;
2900         LBasicBlock continuation;
2901         LBasicBlock lastNext;
2902         if (maySeeEmptyValue) {
2903             notEmpty = m_out.newBlock();
2904             continuation = m_out.newBlock();
2905             m_out.branch(m_out.isZero64(cell), unsure(continuation), unsure(notEmpty));
2906             lastNext = m_out.appendTo(notEmpty, continuation);
2907         }
2908
2909         checkStructure(
2910             m_out.load32(cell, m_heaps.JSCell_structureID), jsValueValue(cell),
2911             exitKind, m_node->structureSet(),
2912             [&] (RegisteredStructure structure) {
2913                 return weakStructureID(structure);
2914             });
2915
2916         if (maySeeEmptyValue) {
2917             m_out.jump(continuation);
2918             m_out.appendTo(continuation, lastNext);
2919         }
2920     }
2921     
2922     void compileCheckCell()
2923     {
2924         LValue cell = lowCell(m_node->child1());
2925         
2926         speculate(
2927             BadCell, jsValueValue(cell), m_node->child1().node(),
2928             m_out.notEqual(cell, weakPointer(m_node->cellOperand()->cell())));
2929     }
2930     
2931     void compileCheckBadCell()
2932     {
2933         terminate(BadCell);
2934     }
2935
2936     void compileCheckNotEmpty()
2937     {
2938         speculate(TDZFailure, noValue(), nullptr, m_out.isZero64(lowJSValue(m_node->child1())));
2939     }
2940
2941     void compileAssertNotEmpty()
2942     {
2943         if (!validationEnabled())
2944             return;
2945
2946         B3::PatchpointValue* patchpoint = m_out.patchpoint(Void);
2947         patchpoint->appendSomeRegister(lowJSValue(m_node->child1()));
2948         patchpoint->setGenerator(
2949             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
2950                 AllowMacroScratchRegisterUsage allowScratch(jit);
2951                 GPRReg input =  params[0].gpr();
2952                 CCallHelpers::Jump done = jit.branchTest64(CCallHelpers::NonZero, input);
2953                 jit.breakpoint();
2954                 done.link(&jit);
2955             });
2956     }
2957
2958     void compileCheckStringIdent()
2959     {
2960         UniquedStringImpl* uid = m_node->uidOperand();
2961         LValue stringImpl = lowStringIdent(m_node->child1());
2962         speculate(BadIdent, noValue(), nullptr, m_out.notEqual(stringImpl, m_out.constIntPtr(uid)));
2963     }
2964
2965     void compileGetExecutable()
2966     {
2967         LValue cell = lowCell(m_node->child1());
2968         speculateFunction(m_node->child1(), cell);
2969         setJSValue(
2970             m_out.bitXor(
2971                 m_out.loadPtr(cell, m_heaps.JSFunction_executable),
2972                 m_out.constIntPtr(JSFunctionPoison::key())));
2973     }
2974     
2975     void compileArrayify()
2976     {
2977         LValue cell = lowCell(m_node->child1());
2978         LValue property = !!m_node->child2() ? lowInt32(m_node->child2()) : 0;
2979         
2980         LBasicBlock unexpectedStructure = m_out.newBlock();
2981         LBasicBlock continuation = m_out.newBlock();
2982         
2983         auto isUnexpectedArray = [&] (LValue cell) {
2984             if (m_node->op() == Arrayify)
2985                 return m_out.logicalNot(isArrayTypeForArrayify(cell, m_node->arrayMode()));
2986
2987             ASSERT(m_node->op() == ArrayifyToStructure);
2988             return m_out.notEqual(m_out.load32(cell, m_heaps.JSCell_structureID), weakStructureID(m_node->structure()));
2989         };
2990
2991         m_out.branch(isUnexpectedArray(cell), rarely(unexpectedStructure), usually(continuation));
2992
2993         LBasicBlock lastNext = m_out.appendTo(unexpectedStructure, continuation);
2994         
2995         if (property) {
2996             switch (m_node->arrayMode().type()) {
2997             case Array::Int32:
2998             case Array::Double:
2999             case Array::Contiguous:
3000                 speculate(
3001                     Uncountable, noValue(), 0,
3002                     m_out.aboveOrEqual(property, m_out.constInt32(MIN_SPARSE_ARRAY_INDEX)));
3003                 break;
3004             default:
3005                 break;
3006             }
3007         }
3008         
3009         switch (m_node->arrayMode().type()) {
3010         case Array::Int32:
3011             vmCall(Void, m_out.operation(operationEnsureInt32), m_callFrame, cell);
3012             break;
3013         case Array::Double:
3014             vmCall(Void, m_out.operation(operationEnsureDouble), m_callFrame, cell);
3015             break;
3016         case Array::Contiguous:
3017             vmCall(Void, m_out.operation(operationEnsureContiguous), m_callFrame, cell);
3018             break;
3019         case Array::ArrayStorage:
3020         case Array::SlowPutArrayStorage:
3021             vmCall(Void, m_out.operation(operationEnsureArrayStorage), m_callFrame, cell);
3022             break;
3023         default:
3024             DFG_CRASH(m_graph, m_node, "Bad array type");
3025             break;
3026         }
3027         
3028         speculate(BadIndexingType, jsValueValue(cell), 0, isUnexpectedArray(cell));
3029         m_out.jump(continuation);
3030         
3031         m_out.appendTo(continuation, lastNext);
3032     }
3033     
3034     void compilePutStructure()
3035     {
3036         m_ftlState.jitCode->common.notifyCompilingStructureTransition(m_graph.m_plan, codeBlock(), m_node);
3037         
3038         RegisteredStructure oldStructure = m_node->transition()->previous;
3039         RegisteredStructure newStructure = m_node->transition()->next;
3040         ASSERT_UNUSED(oldStructure, oldStructure->indexingType() == newStructure->indexingType());
3041         ASSERT(oldStructure->typeInfo().inlineTypeFlags() == newStructure->typeInfo().inlineTypeFlags());
3042         ASSERT(oldStructure->typeInfo().type() == newStructure->typeInfo().type());
3043
3044         LValue cell = lowCell(m_node->child1()); 
3045         m_out.store32(
3046             weakStructureID(newStructure),
3047             cell, m_heaps.JSCell_structureID);
3048     }
3049     
3050     void compileGetById(AccessType type)
3051     {
3052         ASSERT(type == AccessType::Get || type == AccessType::TryGet || type == AccessType::GetDirect);
3053         switch (m_node->child1().useKind()) {
3054         case CellUse: {
3055             setJSValue(getById(lowCell(m_node->child1()), type));
3056             return;
3057         }
3058             
3059         case UntypedUse: {
3060             // This is pretty weird, since we duplicate the slow path both here and in the
3061             // code generated by the IC. We should investigate making this less bad.
3062             // https://bugs.webkit.org/show_bug.cgi?id=127830
3063             LValue value = lowJSValue(m_node->child1());
3064             
3065             LBasicBlock cellCase = m_out.newBlock();
3066             LBasicBlock notCellCase = m_out.newBlock();
3067             LBasicBlock continuation = m_out.newBlock();
3068             
3069             m_out.branch(
3070                 isCell(value, provenType(m_node->child1())), unsure(cellCase), unsure(notCellCase));
3071             
3072             LBasicBlock lastNext = m_out.appendTo(cellCase, notCellCase);
3073             ValueFromBlock cellResult = m_out.anchor(getById(value, type));
3074             m_out.jump(continuation);
3075
3076             J_JITOperation_EJI getByIdFunction = appropriateGenericGetByIdFunction(type);
3077
3078             m_out.appendTo(notCellCase, continuation);
3079             ValueFromBlock notCellResult = m_out.anchor(vmCall(
3080                 Int64, m_out.operation(getByIdFunction),
3081                 m_callFrame, value,
3082                 m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()])));
3083             m_out.jump(continuation);
3084             
3085             m_out.appendTo(continuation, lastNext);
3086             setJSValue(m_out.phi(Int64, cellResult, notCellResult));
3087             return;
3088         }
3089             
3090         default:
3091             DFG_CRASH(m_graph, m_node, "Bad use kind");
3092             return;
3093         }
3094     }
3095
3096     void compileGetByIdWithThis()
3097     {
3098         if (m_node->child1().useKind() == CellUse && m_node->child2().useKind() == CellUse)
3099             setJSValue(getByIdWithThis(lowCell(m_node->child1()), lowCell(m_node->child2())));
3100         else {
3101             LValue base = lowJSValue(m_node->child1());
3102             LValue thisValue = lowJSValue(m_node->child2());
3103             
3104             LBasicBlock baseCellCase = m_out.newBlock();
3105             LBasicBlock notCellCase = m_out.newBlock();
3106             LBasicBlock thisValueCellCase = m_out.newBlock();
3107             LBasicBlock continuation = m_out.newBlock();
3108             
3109             m_out.branch(
3110                 isCell(base, provenType(m_node->child1())), unsure(baseCellCase), unsure(notCellCase));
3111             
3112             LBasicBlock lastNext = m_out.appendTo(baseCellCase, thisValueCellCase);
3113             
3114             m_out.branch(
3115                 isCell(thisValue, provenType(m_node->child2())), unsure(thisValueCellCase), unsure(notCellCase));
3116             
3117             m_out.appendTo(thisValueCellCase, notCellCase);
3118             ValueFromBlock cellResult = m_out.anchor(getByIdWithThis(base, thisValue));
3119             m_out.jump(continuation);
3120
3121             m_out.appendTo(notCellCase, continuation);
3122             ValueFromBlock notCellResult = m_out.anchor(vmCall(
3123                 Int64, m_out.operation(operationGetByIdWithThisGeneric),
3124                 m_callFrame, base, thisValue,
3125                 m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()])));
3126             m_out.jump(continuation);
3127             
3128             m_out.appendTo(continuation, lastNext);
3129             setJSValue(m_out.phi(Int64, cellResult, notCellResult));
3130         }
3131         
3132     }
3133
3134     void compileGetByValWithThis()
3135     {
3136         LValue base = lowJSValue(m_node->child1());
3137         LValue thisValue = lowJSValue(m_node->child2());
3138         LValue subscript = lowJSValue(m_node->child3());
3139
3140         LValue result = vmCall(Int64, m_out.operation(operationGetByValWithThis), m_callFrame, base, thisValue, subscript);
3141         setJSValue(result);
3142     }
3143