[JSC] Add SameValue DFG node
[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                     CCallHelpers::Call throwCall = jit.call(OperationPtrTag);
290
291                     jit.move(CCallHelpers::TrustedImmPtr(vm), GPRInfo::argumentGPR0);
292                     jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
293                     CCallHelpers::Call lookupExceptionHandlerCall = jit.call(OperationPtrTag);
294                     jit.jumpToExceptionHandler(*vm);
295
296                     jit.addLinkTask(
297                         [=] (LinkBuffer& linkBuffer) {
298                             linkBuffer.link(throwCall, FunctionPtr<OperationPtrTag>(operationThrowStackOverflowError));
299                             linkBuffer.link(lookupExceptionHandlerCall, FunctionPtr<OperationPtrTag>(lookupExceptionHandlerFromCallerFrame));
300                     });
301                 });
302             });
303
304         LBasicBlock firstDFGBasicBlock = lowBlock(m_graph.block(0));
305
306         {
307             if (hasMultipleEntrypoints) {
308                 Vector<LBasicBlock> successors(m_graph.m_numberOfEntrypoints);
309                 successors[0] = callEntrypointArgumentSpeculations;
310                 for (unsigned i = 1; i < m_graph.m_numberOfEntrypoints; ++i) {
311                     // Currently, the only other entrypoint is an op_catch entrypoint.
312                     // We do OSR entry at op_catch, and we prove argument formats before
313                     // jumping to FTL code, so we don't need to check argument types here
314                     // for these entrypoints.
315                     successors[i] = firstDFGBasicBlock;
316                 }
317                 
318                 m_out.entrySwitch(successors);
319                 m_out.appendTo(callEntrypointArgumentSpeculations, m_handleExceptions);
320             }
321
322             m_node = nullptr;
323             m_origin = NodeOrigin(CodeOrigin(0), CodeOrigin(0), true);
324
325             // Check Arguments.
326             availabilityMap().clear();
327             availabilityMap().m_locals = Operands<Availability>(codeBlock()->numParameters(), 0);
328             for (unsigned i = codeBlock()->numParameters(); i--;) {
329                 availabilityMap().m_locals.argument(i) =
330                     Availability(FlushedAt(FlushedJSValue, virtualRegisterForArgument(i)));
331             }
332
333             for (unsigned i = codeBlock()->numParameters(); i--;) {
334                 MethodOfGettingAValueProfile profile(&m_graph.m_profiledBlock->valueProfileForArgument(i));
335                 VirtualRegister operand = virtualRegisterForArgument(i);
336                 LValue jsValue = m_out.load64(addressFor(operand));
337                 
338                 switch (m_graph.m_argumentFormats[0][i]) {
339                 case FlushedInt32:
340                     speculate(BadType, jsValueValue(jsValue), profile, isNotInt32(jsValue));
341                     break;
342                 case FlushedBoolean:
343                     speculate(BadType, jsValueValue(jsValue), profile, isNotBoolean(jsValue));
344                     break;
345                 case FlushedCell:
346                     speculate(BadType, jsValueValue(jsValue), profile, isNotCell(jsValue));
347                     break;
348                 case FlushedJSValue:
349                     break;
350                 default:
351                     DFG_CRASH(m_graph, nullptr, "Bad flush format for argument");
352                     break;
353                 }
354             }
355             m_out.jump(firstDFGBasicBlock);
356         }
357
358
359         m_out.appendTo(m_handleExceptions, firstDFGBasicBlock);
360         Box<CCallHelpers::Label> exceptionHandler = state->exceptionHandler;
361         m_out.patchpoint(Void)->setGenerator(
362             [=] (CCallHelpers& jit, const StackmapGenerationParams&) {
363                 CCallHelpers::Jump jump = jit.jump();
364                 jit.addLinkTask(
365                     [=] (LinkBuffer& linkBuffer) {
366                         linkBuffer.link(jump, linkBuffer.locationOf<ExceptionHandlerPtrTag>(*exceptionHandler));
367                     });
368             });
369         m_out.unreachable();
370
371         for (DFG::BasicBlock* block : preOrder)
372             compileBlock(block);
373
374         // Make sure everything is decorated. This does a bunch of deferred decorating. This has
375         // to happen last because our abstract heaps are generated lazily. They have to be
376         // generated lazily because we have an infinite number of numbered, indexed, and
377         // absolute heaps. We only become aware of the ones we actually mention while lowering.
378         m_heaps.computeRangesAndDecorateInstructions();
379
380         // We create all Phi's up front, but we may then decide not to compile the basic block
381         // that would have contained one of them. So this creates orphans, which triggers B3
382         // validation failures. Calling this fixes the issue.
383         //
384         // Note that you should avoid the temptation to make this call conditional upon
385         // validation being enabled. B3 makes no guarantees of any kind of correctness when
386         // dealing with IR that would have failed validation. For example, it would be valid to
387         // write a B3 phase that so aggressively assumes the lack of orphans that it would crash
388         // if any orphans were around. We might even have such phases already.
389         m_proc.deleteOrphans();
390
391         // We put the blocks into the B3 procedure in a super weird order. Now we reorder them.
392         m_out.applyBlockOrder();
393     }
394
395 private:
396     
397     void createPhiVariables()
398     {
399         for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
400             DFG::BasicBlock* block = m_graph.block(blockIndex);
401             if (!block)
402                 continue;
403             for (unsigned nodeIndex = block->size(); nodeIndex--;) {
404                 Node* node = block->at(nodeIndex);
405                 if (node->op() != DFG::Phi)
406                     continue;
407                 LType type;
408                 switch (node->flags() & NodeResultMask) {
409                 case NodeResultDouble:
410                     type = Double;
411                     break;
412                 case NodeResultInt32:
413                     type = Int32;
414                     break;
415                 case NodeResultInt52:
416                     type = Int64;
417                     break;
418                 case NodeResultBoolean:
419                     type = Int32;
420                     break;
421                 case NodeResultJS:
422                     type = Int64;
423                     break;
424                 default:
425                     DFG_CRASH(m_graph, node, "Bad Phi node result type");
426                     break;
427                 }
428                 m_phis.add(node, m_proc.add<Value>(B3::Phi, type, Origin(node)));
429             }
430         }
431     }
432     
433     void compileBlock(DFG::BasicBlock* block)
434     {
435         if (!block)
436             return;
437         
438         if (verboseCompilationEnabled())
439             dataLog("Compiling block ", *block, "\n");
440         
441         m_highBlock = block;
442         
443         // Make sure that any blocks created while lowering code in the high block have the frequency of
444         // the high block. This is appropriate because B3 doesn't need precise frequencies. It just needs
445         // something roughly approximate for things like register allocation.
446         m_out.setFrequency(m_highBlock->executionCount);
447         
448         LBasicBlock lowBlock = m_blocks.get(m_highBlock);
449         
450         m_nextHighBlock = 0;
451         for (BlockIndex nextBlockIndex = m_highBlock->index + 1; nextBlockIndex < m_graph.numBlocks(); ++nextBlockIndex) {
452             m_nextHighBlock = m_graph.block(nextBlockIndex);
453             if (m_nextHighBlock)
454                 break;
455         }
456         m_nextLowBlock = m_nextHighBlock ? m_blocks.get(m_nextHighBlock) : 0;
457         
458         // All of this effort to find the next block gives us the ability to keep the
459         // generated IR in roughly program order. This ought not affect the performance
460         // of the generated code (since we expect B3 to reorder things) but it will
461         // make IR dumps easier to read.
462         m_out.appendTo(lowBlock, m_nextLowBlock);
463         
464         if (Options::ftlCrashes())
465             m_out.trap();
466         
467         if (!m_highBlock->cfaHasVisited) {
468             if (verboseCompilationEnabled())
469                 dataLog("Bailing because CFA didn't reach.\n");
470             crash(m_highBlock, nullptr);
471             return;
472         }
473         
474         m_availabilityCalculator.beginBlock(m_highBlock);
475         
476         m_state.reset();
477         m_state.beginBasicBlock(m_highBlock);
478         
479         for (m_nodeIndex = 0; m_nodeIndex < m_highBlock->size(); ++m_nodeIndex) {
480             if (!compileNode(m_nodeIndex))
481                 break;
482         }
483     }
484
485     void safelyInvalidateAfterTermination()
486     {
487         if (verboseCompilationEnabled())
488             dataLog("Bailing.\n");
489         crash();
490
491         // Invalidate dominated blocks. Under normal circumstances we would expect
492         // them to be invalidated already. But you can have the CFA become more
493         // precise over time because the structures of objects change on the main
494         // thread. Failing to do this would result in weird crashes due to a value
495         // being used but not defined. Race conditions FTW!
496         for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
497             DFG::BasicBlock* target = m_graph.block(blockIndex);
498             if (!target)
499                 continue;
500             if (m_graph.m_ssaDominators->dominates(m_highBlock, target)) {
501                 if (verboseCompilationEnabled())
502                     dataLog("Block ", *target, " will bail also.\n");
503                 target->cfaHasVisited = false;
504             }
505         }
506     }
507
508     bool compileNode(unsigned nodeIndex)
509     {
510         if (!m_state.isValid()) {
511             safelyInvalidateAfterTermination();
512             return false;
513         }
514         
515         m_node = m_highBlock->at(nodeIndex);
516         m_origin = m_node->origin;
517         m_out.setOrigin(m_node);
518         
519         if (verboseCompilationEnabled())
520             dataLog("Lowering ", m_node, "\n");
521         
522         m_availableRecoveries.shrink(0);
523         
524         m_interpreter.startExecuting();
525         m_interpreter.executeKnownEdgeTypes(m_node);
526         
527         switch (m_node->op()) {
528         case DFG::Upsilon:
529             compileUpsilon();
530             break;
531         case DFG::Phi:
532             compilePhi();
533             break;
534         case JSConstant:
535             break;
536         case DoubleConstant:
537             compileDoubleConstant();
538             break;
539         case Int52Constant:
540             compileInt52Constant();
541             break;
542         case LazyJSConstant:
543             compileLazyJSConstant();
544             break;
545         case DoubleRep:
546             compileDoubleRep();
547             break;
548         case DoubleAsInt32:
549             compileDoubleAsInt32();
550             break;
551         case DFG::ValueRep:
552             compileValueRep();
553             break;
554         case Int52Rep:
555             compileInt52Rep();
556             break;
557         case ValueToInt32:
558             compileValueToInt32();
559             break;
560         case BooleanToNumber:
561             compileBooleanToNumber();
562             break;
563         case ExtractOSREntryLocal:
564             compileExtractOSREntryLocal();
565             break;
566         case ExtractCatchLocal:
567             compileExtractCatchLocal();
568             break;
569         case GetStack:
570             compileGetStack();
571             break;
572         case PutStack:
573             compilePutStack();
574             break;
575         case DFG::Check:
576         case CheckVarargs:
577             compileNoOp();
578             break;
579         case ToObject:
580         case CallObjectConstructor:
581             compileToObjectOrCallObjectConstructor();
582             break;
583         case ToThis:
584             compileToThis();
585             break;
586         case ValueAdd:
587             compileValueAdd();
588             break;
589         case StrCat:
590             compileStrCat();
591             break;
592         case ArithAdd:
593         case ArithSub:
594             compileArithAddOrSub();
595             break;
596         case ArithClz32:
597             compileArithClz32();
598             break;
599         case ArithMul:
600             compileArithMul();
601             break;
602         case ArithDiv:
603             compileArithDiv();
604             break;
605         case ArithMod:
606             compileArithMod();
607             break;
608         case ArithMin:
609         case ArithMax:
610             compileArithMinOrMax();
611             break;
612         case ArithAbs:
613             compileArithAbs();
614             break;
615         case ArithPow:
616             compileArithPow();
617             break;
618         case ArithRandom:
619             compileArithRandom();
620             break;
621         case ArithRound:
622             compileArithRound();
623             break;
624         case ArithFloor:
625             compileArithFloor();
626             break;
627         case ArithCeil:
628             compileArithCeil();
629             break;
630         case ArithTrunc:
631             compileArithTrunc();
632             break;
633         case ArithSqrt:
634             compileArithSqrt();
635             break;
636         case ArithFRound:
637             compileArithFRound();
638             break;
639         case ArithNegate:
640             compileArithNegate();
641             break;
642         case ArithUnary:
643             compileArithUnary();
644             break;
645         case DFG::BitAnd:
646             compileBitAnd();
647             break;
648         case DFG::BitOr:
649             compileBitOr();
650             break;
651         case DFG::BitXor:
652             compileBitXor();
653             break;
654         case BitRShift:
655             compileBitRShift();
656             break;
657         case BitLShift:
658             compileBitLShift();
659             break;
660         case BitURShift:
661             compileBitURShift();
662             break;
663         case UInt32ToNumber:
664             compileUInt32ToNumber();
665             break;
666         case CheckStructure:
667             compileCheckStructure();
668             break;
669         case CheckStructureOrEmpty:
670             compileCheckStructureOrEmpty();
671             break;
672         case CheckCell:
673             compileCheckCell();
674             break;
675         case CheckNotEmpty:
676             compileCheckNotEmpty();
677             break;
678         case AssertNotEmpty:
679             compileAssertNotEmpty();
680             break;
681         case CheckBadCell:
682             compileCheckBadCell();
683             break;
684         case CheckStringIdent:
685             compileCheckStringIdent();
686             break;
687         case GetExecutable:
688             compileGetExecutable();
689             break;
690         case Arrayify:
691         case ArrayifyToStructure:
692             compileArrayify();
693             break;
694         case PutStructure:
695             compilePutStructure();
696             break;
697         case TryGetById:
698             compileGetById(AccessType::TryGet);
699             break;
700         case GetById:
701         case GetByIdFlush:
702             compileGetById(AccessType::Get);
703             break;
704         case GetByIdWithThis:
705             compileGetByIdWithThis();
706             break;
707         case GetByIdDirect:
708         case GetByIdDirectFlush:
709             compileGetById(AccessType::GetDirect);
710             break;
711         case In:
712             compileIn();
713             break;
714         case HasOwnProperty:
715             compileHasOwnProperty();
716             break;
717         case PutById:
718         case PutByIdDirect:
719         case PutByIdFlush:
720             compilePutById();
721             break;
722         case PutByIdWithThis:
723             compilePutByIdWithThis();
724             break;
725         case PutGetterById:
726         case PutSetterById:
727             compilePutAccessorById();
728             break;
729         case PutGetterSetterById:
730             compilePutGetterSetterById();
731             break;
732         case PutGetterByVal:
733         case PutSetterByVal:
734             compilePutAccessorByVal();
735             break;
736         case DeleteById:
737             compileDeleteById();
738             break;
739         case DeleteByVal:
740             compileDeleteByVal();
741             break;
742         case GetButterfly:
743             compileGetButterfly();
744             break;
745         case ConstantStoragePointer:
746             compileConstantStoragePointer();
747             break;
748         case GetIndexedPropertyStorage:
749             compileGetIndexedPropertyStorage();
750             break;
751         case CheckArray:
752             compileCheckArray();
753             break;
754         case GetArrayLength:
755             compileGetArrayLength();
756             break;
757         case GetVectorLength:
758             compileGetVectorLength();
759             break;
760         case CheckInBounds:
761             compileCheckInBounds();
762             break;
763         case GetByVal:
764             compileGetByVal();
765             break;
766         case GetMyArgumentByVal:
767         case GetMyArgumentByValOutOfBounds:
768             compileGetMyArgumentByVal();
769             break;
770         case GetByValWithThis:
771             compileGetByValWithThis();
772             break;
773         case PutByVal:
774         case PutByValAlias:
775         case PutByValDirect:
776             compilePutByVal();
777             break;
778         case PutByValWithThis:
779             compilePutByValWithThis();
780             break;
781         case AtomicsAdd:
782         case AtomicsAnd:
783         case AtomicsCompareExchange:
784         case AtomicsExchange:
785         case AtomicsLoad:
786         case AtomicsOr:
787         case AtomicsStore:
788         case AtomicsSub:
789         case AtomicsXor:
790             compileAtomicsReadModifyWrite();
791             break;
792         case AtomicsIsLockFree:
793             compileAtomicsIsLockFree();
794             break;
795         case DefineDataProperty:
796             compileDefineDataProperty();
797             break;
798         case DefineAccessorProperty:
799             compileDefineAccessorProperty();
800             break;
801         case ArrayPush:
802             compileArrayPush();
803             break;
804         case ArrayPop:
805             compileArrayPop();
806             break;
807         case ArraySlice:
808             compileArraySlice();
809             break;
810         case ArrayIndexOf:
811             compileArrayIndexOf();
812             break;
813         case CreateActivation:
814             compileCreateActivation();
815             break;
816         case PushWithScope:
817             compilePushWithScope();
818             break;
819         case NewFunction:
820         case NewGeneratorFunction:
821         case NewAsyncGeneratorFunction:
822         case NewAsyncFunction:
823             compileNewFunction();
824             break;
825         case CreateDirectArguments:
826             compileCreateDirectArguments();
827             break;
828         case CreateScopedArguments:
829             compileCreateScopedArguments();
830             break;
831         case CreateClonedArguments:
832             compileCreateClonedArguments();
833             break;
834         case NewObject:
835             compileNewObject();
836             break;
837         case NewStringObject:
838             compileNewStringObject();
839             break;
840         case NewArray:
841             compileNewArray();
842             break;
843         case NewArrayWithSpread:
844             compileNewArrayWithSpread();
845             break;
846         case Spread:
847             compileSpread();
848             break;
849         case NewArrayBuffer:
850             compileNewArrayBuffer();
851             break;
852         case NewArrayWithSize:
853             compileNewArrayWithSize();
854             break;
855         case NewTypedArray:
856             compileNewTypedArray();
857             break;
858         case GetTypedArrayByteOffset:
859             compileGetTypedArrayByteOffset();
860             break;
861         case GetPrototypeOf:
862             compileGetPrototypeOf();
863             break;
864         case AllocatePropertyStorage:
865             compileAllocatePropertyStorage();
866             break;
867         case ReallocatePropertyStorage:
868             compileReallocatePropertyStorage();
869             break;
870         case NukeStructureAndSetButterfly:
871             compileNukeStructureAndSetButterfly();
872             break;
873         case ToNumber:
874             compileToNumber();
875             break;
876         case ToString:
877         case CallStringConstructor:
878             compileToStringOrCallStringConstructor();
879             break;
880         case ToPrimitive:
881             compileToPrimitive();
882             break;
883         case MakeRope:
884             compileMakeRope();
885             break;
886         case StringCharAt:
887             compileStringCharAt();
888             break;
889         case StringCharCodeAt:
890             compileStringCharCodeAt();
891             break;
892         case StringFromCharCode:
893             compileStringFromCharCode();
894             break;
895         case GetByOffset:
896         case GetGetterSetterByOffset:
897             compileGetByOffset();
898             break;
899         case GetGetter:
900             compileGetGetter();
901             break;
902         case GetSetter:
903             compileGetSetter();
904             break;
905         case MultiGetByOffset:
906             compileMultiGetByOffset();
907             break;
908         case PutByOffset:
909             compilePutByOffset();
910             break;
911         case MultiPutByOffset:
912             compileMultiPutByOffset();
913             break;
914         case GetGlobalVar:
915         case GetGlobalLexicalVariable:
916             compileGetGlobalVariable();
917             break;
918         case PutGlobalVariable:
919             compilePutGlobalVariable();
920             break;
921         case NotifyWrite:
922             compileNotifyWrite();
923             break;
924         case GetCallee:
925             compileGetCallee();
926             break;
927         case SetCallee:
928             compileSetCallee();
929             break;
930         case GetArgumentCountIncludingThis:
931             compileGetArgumentCountIncludingThis();
932             break;
933         case SetArgumentCountIncludingThis:
934             compileSetArgumentCountIncludingThis();
935             break;
936         case GetScope:
937             compileGetScope();
938             break;
939         case SkipScope:
940             compileSkipScope();
941             break;
942         case GetGlobalObject:
943             compileGetGlobalObject();
944             break;
945         case GetGlobalThis:
946             compileGetGlobalThis();
947             break;
948         case GetClosureVar:
949             compileGetClosureVar();
950             break;
951         case PutClosureVar:
952             compilePutClosureVar();
953             break;
954         case GetFromArguments:
955             compileGetFromArguments();
956             break;
957         case PutToArguments:
958             compilePutToArguments();
959             break;
960         case GetArgument:
961             compileGetArgument();
962             break;
963         case CompareEq:
964             compileCompareEq();
965             break;
966         case CompareStrictEq:
967             compileCompareStrictEq();
968             break;
969         case CompareLess:
970             compileCompareLess();
971             break;
972         case CompareLessEq:
973             compileCompareLessEq();
974             break;
975         case CompareGreater:
976             compileCompareGreater();
977             break;
978         case CompareGreaterEq:
979             compileCompareGreaterEq();
980             break;
981         case CompareBelow:
982             compileCompareBelow();
983             break;
984         case CompareBelowEq:
985             compileCompareBelowEq();
986             break;
987         case CompareEqPtr:
988             compileCompareEqPtr();
989             break;
990         case SameValue:
991             compileSameValue();
992             break;
993         case LogicalNot:
994             compileLogicalNot();
995             break;
996         case Call:
997         case TailCallInlinedCaller:
998         case Construct:
999             compileCallOrConstruct();
1000             break;
1001         case DirectCall:
1002         case DirectTailCallInlinedCaller:
1003         case DirectConstruct:
1004         case DirectTailCall:
1005             compileDirectCallOrConstruct();
1006             break;
1007         case TailCall:
1008             compileTailCall();
1009             break;
1010         case CallVarargs:
1011         case CallForwardVarargs:
1012         case TailCallVarargs:
1013         case TailCallVarargsInlinedCaller:
1014         case TailCallForwardVarargs:
1015         case TailCallForwardVarargsInlinedCaller:
1016         case ConstructVarargs:
1017         case ConstructForwardVarargs:
1018             compileCallOrConstructVarargs();
1019             break;
1020         case CallEval:
1021             compileCallEval();
1022             break;
1023         case LoadVarargs:
1024             compileLoadVarargs();
1025             break;
1026         case ForwardVarargs:
1027             compileForwardVarargs();
1028             break;
1029         case DFG::Jump:
1030             compileJump();
1031             break;
1032         case DFG::Branch:
1033             compileBranch();
1034             break;
1035         case DFG::Switch:
1036             compileSwitch();
1037             break;
1038         case DFG::EntrySwitch:
1039             compileEntrySwitch();
1040             break;
1041         case DFG::Return:
1042             compileReturn();
1043             break;
1044         case ForceOSRExit:
1045             compileForceOSRExit();
1046             break;
1047         case CPUIntrinsic:
1048 #if CPU(X86_64)
1049             compileCPUIntrinsic();
1050 #else
1051             RELEASE_ASSERT_NOT_REACHED();
1052 #endif
1053             break;
1054         case Throw:
1055             compileThrow();
1056             break;
1057         case ThrowStaticError:
1058             compileThrowStaticError();
1059             break;
1060         case InvalidationPoint:
1061             compileInvalidationPoint();
1062             break;
1063         case IsEmpty:
1064             compileIsEmpty();
1065             break;
1066         case IsUndefined:
1067             compileIsUndefined();
1068             break;
1069         case IsBoolean:
1070             compileIsBoolean();
1071             break;
1072         case IsNumber:
1073             compileIsNumber();
1074             break;
1075         case NumberIsInteger:
1076             compileNumberIsInteger();
1077             break;
1078         case IsCellWithType:
1079             compileIsCellWithType();
1080             break;
1081         case MapHash:
1082             compileMapHash();
1083             break;
1084         case NormalizeMapKey:
1085             compileNormalizeMapKey();
1086             break;
1087         case GetMapBucket:
1088             compileGetMapBucket();
1089             break;
1090         case GetMapBucketHead:
1091             compileGetMapBucketHead();
1092             break;
1093         case GetMapBucketNext:
1094             compileGetMapBucketNext();
1095             break;
1096         case LoadKeyFromMapBucket:
1097             compileLoadKeyFromMapBucket();
1098             break;
1099         case LoadValueFromMapBucket:
1100             compileLoadValueFromMapBucket();
1101             break;
1102         case ExtractValueFromWeakMapGet:
1103             compileExtractValueFromWeakMapGet();
1104             break;
1105         case SetAdd:
1106             compileSetAdd();
1107             break;
1108         case MapSet:
1109             compileMapSet();
1110             break;
1111         case WeakMapGet:
1112             compileWeakMapGet();
1113             break;
1114         case WeakSetAdd:
1115             compileWeakSetAdd();
1116             break;
1117         case WeakMapSet:
1118             compileWeakMapSet();
1119             break;
1120         case IsObject:
1121             compileIsObject();
1122             break;
1123         case IsObjectOrNull:
1124             compileIsObjectOrNull();
1125             break;
1126         case IsFunction:
1127             compileIsFunction();
1128             break;
1129         case IsTypedArrayView:
1130             compileIsTypedArrayView();
1131             break;
1132         case ParseInt:
1133             compileParseInt();
1134             break;
1135         case TypeOf:
1136             compileTypeOf();
1137             break;
1138         case CheckTypeInfoFlags:
1139             compileCheckTypeInfoFlags();
1140             break;
1141         case OverridesHasInstance:
1142             compileOverridesHasInstance();
1143             break;
1144         case InstanceOf:
1145             compileInstanceOf();
1146             break;
1147         case InstanceOfCustom:
1148             compileInstanceOfCustom();
1149             break;
1150         case CountExecution:
1151             compileCountExecution();
1152             break;
1153         case SuperSamplerBegin:
1154             compileSuperSamplerBegin();
1155             break;
1156         case SuperSamplerEnd:
1157             compileSuperSamplerEnd();
1158             break;
1159         case StoreBarrier:
1160         case FencedStoreBarrier:
1161             compileStoreBarrier();
1162             break;
1163         case HasIndexedProperty:
1164             compileHasIndexedProperty();
1165             break;
1166         case HasGenericProperty:
1167             compileHasGenericProperty();
1168             break;
1169         case HasStructureProperty:
1170             compileHasStructureProperty();
1171             break;
1172         case GetDirectPname:
1173             compileGetDirectPname();
1174             break;
1175         case GetEnumerableLength:
1176             compileGetEnumerableLength();
1177             break;
1178         case GetPropertyEnumerator:
1179             compileGetPropertyEnumerator();
1180             break;
1181         case GetEnumeratorStructurePname:
1182             compileGetEnumeratorStructurePname();
1183             break;
1184         case GetEnumeratorGenericPname:
1185             compileGetEnumeratorGenericPname();
1186             break;
1187         case ToIndexString:
1188             compileToIndexString();
1189             break;
1190         case CheckStructureImmediate:
1191             compileCheckStructureImmediate();
1192             break;
1193         case MaterializeNewObject:
1194             compileMaterializeNewObject();
1195             break;
1196         case MaterializeCreateActivation:
1197             compileMaterializeCreateActivation();
1198             break;
1199         case CheckTraps:
1200             if (Options::usePollingTraps())
1201                 compileCheckTraps();
1202             break;
1203         case CreateRest:
1204             compileCreateRest();
1205             break;
1206         case GetRestLength:
1207             compileGetRestLength();
1208             break;
1209         case RegExpExec:
1210             compileRegExpExec();
1211             break;
1212         case RegExpExecNonGlobalOrSticky:
1213             compileRegExpExecNonGlobalOrSticky();
1214             break;
1215         case RegExpTest:
1216             compileRegExpTest();
1217             break;
1218         case RegExpMatchFast:
1219             compileRegExpMatchFast();
1220             break;
1221         case RegExpMatchFastGlobal:
1222             compileRegExpMatchFastGlobal();
1223             break;
1224         case NewRegexp:
1225             compileNewRegexp();
1226             break;
1227         case SetFunctionName:
1228             compileSetFunctionName();
1229             break;
1230         case StringReplace:
1231         case StringReplaceRegExp:
1232             compileStringReplace();
1233             break;
1234         case GetRegExpObjectLastIndex:
1235             compileGetRegExpObjectLastIndex();
1236             break;
1237         case SetRegExpObjectLastIndex:
1238             compileSetRegExpObjectLastIndex();
1239             break;
1240         case LogShadowChickenPrologue:
1241             compileLogShadowChickenPrologue();
1242             break;
1243         case LogShadowChickenTail:
1244             compileLogShadowChickenTail();
1245             break;
1246         case RecordRegExpCachedResult:
1247             compileRecordRegExpCachedResult();
1248             break;
1249         case ResolveScopeForHoistingFuncDeclInEval:
1250             compileResolveScopeForHoistingFuncDeclInEval();
1251             break;
1252         case ResolveScope:
1253             compileResolveScope();
1254             break;
1255         case GetDynamicVar:
1256             compileGetDynamicVar();
1257             break;
1258         case PutDynamicVar:
1259             compilePutDynamicVar();
1260             break;
1261         case Unreachable:
1262             compileUnreachable();
1263             break;
1264         case StringSlice:
1265             compileStringSlice();
1266             break;
1267         case ToLowerCase:
1268             compileToLowerCase();
1269             break;
1270         case NumberToStringWithRadix:
1271             compileNumberToStringWithRadix();
1272             break;
1273         case NumberToStringWithValidRadixConstant:
1274             compileNumberToStringWithValidRadixConstant();
1275             break;
1276         case CheckSubClass:
1277             compileCheckSubClass();
1278             break;
1279         case CallDOM:
1280             compileCallDOM();
1281             break;
1282         case CallDOMGetter:
1283             compileCallDOMGetter();
1284             break;
1285
1286         case PhantomLocal:
1287         case LoopHint:
1288         case MovHint:
1289         case ZombieHint:
1290         case ExitOK:
1291         case PhantomNewObject:
1292         case PhantomNewFunction:
1293         case PhantomNewGeneratorFunction:
1294         case PhantomNewAsyncGeneratorFunction:
1295         case PhantomNewAsyncFunction:
1296         case PhantomCreateActivation:
1297         case PhantomDirectArguments:
1298         case PhantomCreateRest:
1299         case PhantomSpread:
1300         case PhantomNewArrayWithSpread:
1301         case PhantomNewArrayBuffer:
1302         case PhantomClonedArguments:
1303         case PhantomNewRegexp:
1304         case PutHint:
1305         case BottomValue:
1306         case KillStack:
1307         case InitializeEntrypointArguments:
1308             break;
1309         default:
1310             DFG_CRASH(m_graph, m_node, "Unrecognized node in FTL backend");
1311             break;
1312         }
1313         
1314         if (m_node->isTerminal())
1315             return false;
1316         
1317         if (!m_state.isValid()) {
1318             safelyInvalidateAfterTermination();
1319             return false;
1320         }
1321
1322         m_availabilityCalculator.executeNode(m_node);
1323         m_interpreter.executeEffects(nodeIndex);
1324         
1325         return true;
1326     }
1327
1328     void compileUpsilon()
1329     {
1330         LValue upsilonValue = nullptr;
1331         switch (m_node->child1().useKind()) {
1332         case DoubleRepUse:
1333             upsilonValue = lowDouble(m_node->child1());
1334             break;
1335         case Int32Use:
1336         case KnownInt32Use:
1337             upsilonValue = lowInt32(m_node->child1());
1338             break;
1339         case Int52RepUse:
1340             upsilonValue = lowInt52(m_node->child1());
1341             break;
1342         case BooleanUse:
1343         case KnownBooleanUse:
1344             upsilonValue = lowBoolean(m_node->child1());
1345             break;
1346         case CellUse:
1347         case KnownCellUse:
1348             upsilonValue = lowCell(m_node->child1());
1349             break;
1350         case UntypedUse:
1351             upsilonValue = lowJSValue(m_node->child1());
1352             break;
1353         default:
1354             DFG_CRASH(m_graph, m_node, "Bad use kind");
1355             break;
1356         }
1357         ValueFromBlock upsilon = m_out.anchor(upsilonValue);
1358         LValue phiNode = m_phis.get(m_node->phi());
1359         m_out.addIncomingToPhi(phiNode, upsilon);
1360     }
1361     
1362     void compilePhi()
1363     {
1364         LValue phi = m_phis.get(m_node);
1365         m_out.m_block->append(phi);
1366
1367         switch (m_node->flags() & NodeResultMask) {
1368         case NodeResultDouble:
1369             setDouble(phi);
1370             break;
1371         case NodeResultInt32:
1372             setInt32(phi);
1373             break;
1374         case NodeResultInt52:
1375             setInt52(phi);
1376             break;
1377         case NodeResultBoolean:
1378             setBoolean(phi);
1379             break;
1380         case NodeResultJS:
1381             setJSValue(phi);
1382             break;
1383         default:
1384             DFG_CRASH(m_graph, m_node, "Bad use kind");
1385             break;
1386         }
1387     }
1388     
1389     void compileDoubleConstant()
1390     {
1391         setDouble(m_out.constDouble(m_node->asNumber()));
1392     }
1393     
1394     void compileInt52Constant()
1395     {
1396         int64_t value = m_node->asAnyInt();
1397         
1398         setInt52(m_out.constInt64(value << JSValue::int52ShiftAmount));
1399         setStrictInt52(m_out.constInt64(value));
1400     }
1401
1402     void compileLazyJSConstant()
1403     {
1404         PatchpointValue* patchpoint = m_out.patchpoint(Int64);
1405         LazyJSValue value = m_node->lazyJSValue();
1406         patchpoint->setGenerator(
1407             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
1408                 value.emit(jit, JSValueRegs(params[0].gpr()));
1409             });
1410         patchpoint->effects = Effects::none();
1411         setJSValue(patchpoint);
1412     }
1413
1414     void compileDoubleRep()
1415     {
1416         switch (m_node->child1().useKind()) {
1417         case RealNumberUse: {
1418             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
1419             
1420             LValue doubleValue = unboxDouble(value);
1421             
1422             LBasicBlock intCase = m_out.newBlock();
1423             LBasicBlock continuation = m_out.newBlock();
1424             
1425             ValueFromBlock fastResult = m_out.anchor(doubleValue);
1426             m_out.branch(
1427                 m_out.doubleEqual(doubleValue, doubleValue),
1428                 usually(continuation), rarely(intCase));
1429             
1430             LBasicBlock lastNext = m_out.appendTo(intCase, continuation);
1431
1432             FTL_TYPE_CHECK(
1433                 jsValueValue(value), m_node->child1(), SpecBytecodeRealNumber,
1434                 isNotInt32(value, provenType(m_node->child1()) & ~SpecDoubleReal));
1435             ValueFromBlock slowResult = m_out.anchor(m_out.intToDouble(unboxInt32(value)));
1436             m_out.jump(continuation);
1437             
1438             m_out.appendTo(continuation, lastNext);
1439             
1440             setDouble(m_out.phi(Double, fastResult, slowResult));
1441             return;
1442         }
1443             
1444         case NotCellUse:
1445         case NumberUse: {
1446             bool shouldConvertNonNumber = m_node->child1().useKind() == NotCellUse;
1447             
1448             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
1449
1450             LBasicBlock intCase = m_out.newBlock();
1451             LBasicBlock doubleTesting = m_out.newBlock();
1452             LBasicBlock doubleCase = m_out.newBlock();
1453             LBasicBlock nonDoubleCase = m_out.newBlock();
1454             LBasicBlock continuation = m_out.newBlock();
1455             
1456             m_out.branch(
1457                 isNotInt32(value, provenType(m_node->child1())),
1458                 unsure(doubleTesting), unsure(intCase));
1459             
1460             LBasicBlock lastNext = m_out.appendTo(intCase, doubleTesting);
1461             
1462             ValueFromBlock intToDouble = m_out.anchor(
1463                 m_out.intToDouble(unboxInt32(value)));
1464             m_out.jump(continuation);
1465             
1466             m_out.appendTo(doubleTesting, doubleCase);
1467             LValue valueIsNumber = isNumber(value, provenType(m_node->child1()));
1468             m_out.branch(valueIsNumber, usually(doubleCase), rarely(nonDoubleCase));
1469
1470             m_out.appendTo(doubleCase, nonDoubleCase);
1471             ValueFromBlock unboxedDouble = m_out.anchor(unboxDouble(value));
1472             m_out.jump(continuation);
1473
1474             if (shouldConvertNonNumber) {
1475                 LBasicBlock undefinedCase = m_out.newBlock();
1476                 LBasicBlock testNullCase = m_out.newBlock();
1477                 LBasicBlock nullCase = m_out.newBlock();
1478                 LBasicBlock testBooleanTrueCase = m_out.newBlock();
1479                 LBasicBlock convertBooleanTrueCase = m_out.newBlock();
1480                 LBasicBlock convertBooleanFalseCase = m_out.newBlock();
1481
1482                 m_out.appendTo(nonDoubleCase, undefinedCase);
1483                 LValue valueIsUndefined = m_out.equal(value, m_out.constInt64(ValueUndefined));
1484                 m_out.branch(valueIsUndefined, unsure(undefinedCase), unsure(testNullCase));
1485
1486                 m_out.appendTo(undefinedCase, testNullCase);
1487                 ValueFromBlock convertedUndefined = m_out.anchor(m_out.constDouble(PNaN));
1488                 m_out.jump(continuation);
1489
1490                 m_out.appendTo(testNullCase, nullCase);
1491                 LValue valueIsNull = m_out.equal(value, m_out.constInt64(ValueNull));
1492                 m_out.branch(valueIsNull, unsure(nullCase), unsure(testBooleanTrueCase));
1493
1494                 m_out.appendTo(nullCase, testBooleanTrueCase);
1495                 ValueFromBlock convertedNull = m_out.anchor(m_out.constDouble(0));
1496                 m_out.jump(continuation);
1497
1498                 m_out.appendTo(testBooleanTrueCase, convertBooleanTrueCase);
1499                 LValue valueIsBooleanTrue = m_out.equal(value, m_out.constInt64(ValueTrue));
1500                 m_out.branch(valueIsBooleanTrue, unsure(convertBooleanTrueCase), unsure(convertBooleanFalseCase));
1501
1502                 m_out.appendTo(convertBooleanTrueCase, convertBooleanFalseCase);
1503                 ValueFromBlock convertedTrue = m_out.anchor(m_out.constDouble(1));
1504                 m_out.jump(continuation);
1505
1506                 m_out.appendTo(convertBooleanFalseCase, continuation);
1507
1508                 LValue valueIsNotBooleanFalse = m_out.notEqual(value, m_out.constInt64(ValueFalse));
1509                 FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), ~SpecCellCheck, valueIsNotBooleanFalse);
1510                 ValueFromBlock convertedFalse = m_out.anchor(m_out.constDouble(0));
1511                 m_out.jump(continuation);
1512
1513                 m_out.appendTo(continuation, lastNext);
1514                 setDouble(m_out.phi(Double, intToDouble, unboxedDouble, convertedUndefined, convertedNull, convertedTrue, convertedFalse));
1515                 return;
1516             }
1517             m_out.appendTo(nonDoubleCase, continuation);
1518             FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), SpecBytecodeNumber, m_out.booleanTrue);
1519             m_out.unreachable();
1520
1521             m_out.appendTo(continuation, lastNext);
1522
1523             setDouble(m_out.phi(Double, intToDouble, unboxedDouble));
1524             return;
1525         }
1526             
1527         case Int52RepUse: {
1528             setDouble(strictInt52ToDouble(lowStrictInt52(m_node->child1())));
1529             return;
1530         }
1531             
1532         default:
1533             DFG_CRASH(m_graph, m_node, "Bad use kind");
1534         }
1535     }
1536
1537     void compileDoubleAsInt32()
1538     {
1539         LValue integerValue = convertDoubleToInt32(lowDouble(m_node->child1()), shouldCheckNegativeZero(m_node->arithMode()));
1540         setInt32(integerValue);
1541     }
1542
1543     void compileValueRep()
1544     {
1545         switch (m_node->child1().useKind()) {
1546         case DoubleRepUse: {
1547             LValue value = lowDouble(m_node->child1());
1548             
1549             if (m_interpreter.needsTypeCheck(m_node->child1(), ~SpecDoubleImpureNaN)) {
1550                 value = m_out.select(
1551                     m_out.doubleEqual(value, value), value, m_out.constDouble(PNaN));
1552             }
1553             
1554             setJSValue(boxDouble(value));
1555             return;
1556         }
1557             
1558         case Int52RepUse: {
1559             setJSValue(strictInt52ToJSValue(lowStrictInt52(m_node->child1())));
1560             return;
1561         }
1562             
1563         default:
1564             DFG_CRASH(m_graph, m_node, "Bad use kind");
1565         }
1566     }
1567     
1568     void compileInt52Rep()
1569     {
1570         switch (m_node->child1().useKind()) {
1571         case Int32Use:
1572             setStrictInt52(m_out.signExt32To64(lowInt32(m_node->child1())));
1573             return;
1574             
1575         case AnyIntUse:
1576             setStrictInt52(
1577                 jsValueToStrictInt52(
1578                     m_node->child1(), lowJSValue(m_node->child1(), ManualOperandSpeculation)));
1579             return;
1580             
1581         case DoubleRepAnyIntUse:
1582             setStrictInt52(
1583                 doubleToStrictInt52(
1584                     m_node->child1(), lowDouble(m_node->child1())));
1585             return;
1586             
1587         default:
1588             RELEASE_ASSERT_NOT_REACHED();
1589         }
1590     }
1591     
1592     void compileValueToInt32()
1593     {
1594         switch (m_node->child1().useKind()) {
1595         case Int52RepUse:
1596             setInt32(m_out.castToInt32(lowStrictInt52(m_node->child1())));
1597             break;
1598             
1599         case DoubleRepUse:
1600             setInt32(doubleToInt32(lowDouble(m_node->child1())));
1601             break;
1602             
1603         case NumberUse:
1604         case NotCellUse: {
1605             LoweredNodeValue value = m_int32Values.get(m_node->child1().node());
1606             if (isValid(value)) {
1607                 setInt32(value.value());
1608                 break;
1609             }
1610             
1611             value = m_jsValueValues.get(m_node->child1().node());
1612             if (isValid(value)) {
1613                 setInt32(numberOrNotCellToInt32(m_node->child1(), value.value()));
1614                 break;
1615             }
1616             
1617             // We'll basically just get here for constants. But it's good to have this
1618             // catch-all since we often add new representations into the mix.
1619             setInt32(
1620                 numberOrNotCellToInt32(
1621                     m_node->child1(),
1622                     lowJSValue(m_node->child1(), ManualOperandSpeculation)));
1623             break;
1624         }
1625             
1626         default:
1627             DFG_CRASH(m_graph, m_node, "Bad use kind");
1628             break;
1629         }
1630     }
1631     
1632     void compileBooleanToNumber()
1633     {
1634         switch (m_node->child1().useKind()) {
1635         case BooleanUse: {
1636             setInt32(m_out.zeroExt(lowBoolean(m_node->child1()), Int32));
1637             return;
1638         }
1639             
1640         case UntypedUse: {
1641             LValue value = lowJSValue(m_node->child1());
1642             
1643             if (!m_interpreter.needsTypeCheck(m_node->child1(), SpecBoolInt32 | SpecBoolean)) {
1644                 setInt32(m_out.bitAnd(m_out.castToInt32(value), m_out.int32One));
1645                 return;
1646             }
1647             
1648             LBasicBlock booleanCase = m_out.newBlock();
1649             LBasicBlock continuation = m_out.newBlock();
1650             
1651             ValueFromBlock notBooleanResult = m_out.anchor(value);
1652             m_out.branch(
1653                 isBoolean(value, provenType(m_node->child1())),
1654                 unsure(booleanCase), unsure(continuation));
1655             
1656             LBasicBlock lastNext = m_out.appendTo(booleanCase, continuation);
1657             ValueFromBlock booleanResult = m_out.anchor(m_out.bitOr(
1658                 m_out.zeroExt(unboxBoolean(value), Int64), m_tagTypeNumber));
1659             m_out.jump(continuation);
1660             
1661             m_out.appendTo(continuation, lastNext);
1662             setJSValue(m_out.phi(Int64, booleanResult, notBooleanResult));
1663             return;
1664         }
1665             
1666         default:
1667             RELEASE_ASSERT_NOT_REACHED();
1668             return;
1669         }
1670     }
1671
1672     void compileExtractOSREntryLocal()
1673     {
1674         EncodedJSValue* buffer = static_cast<EncodedJSValue*>(
1675             m_ftlState.jitCode->ftlForOSREntry()->entryBuffer()->dataBuffer());
1676         setJSValue(m_out.load64(m_out.absolute(buffer + m_node->unlinkedLocal().toLocal())));
1677     }
1678
1679     void compileExtractCatchLocal()
1680     {
1681         EncodedJSValue* buffer = static_cast<EncodedJSValue*>(m_ftlState.jitCode->common.catchOSREntryBuffer->dataBuffer());
1682         setJSValue(m_out.load64(m_out.absolute(buffer + m_node->catchOSREntryIndex())));
1683     }
1684     
1685     void compileGetStack()
1686     {
1687         StackAccessData* data = m_node->stackAccessData();
1688         AbstractValue& value = m_state.variables().operand(data->local);
1689         
1690         DFG_ASSERT(m_graph, m_node, isConcrete(data->format), data->format);
1691         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.
1692         
1693         if (isInt32Speculation(value.m_type))
1694             setInt32(m_out.load32(payloadFor(data->machineLocal)));
1695         else
1696             setJSValue(m_out.load64(addressFor(data->machineLocal)));
1697     }
1698     
1699     void compilePutStack()
1700     {
1701         StackAccessData* data = m_node->stackAccessData();
1702         switch (data->format) {
1703         case FlushedJSValue: {
1704             LValue value = lowJSValue(m_node->child1());
1705             m_out.store64(value, addressFor(data->machineLocal));
1706             break;
1707         }
1708             
1709         case FlushedDouble: {
1710             LValue value = lowDouble(m_node->child1());
1711             m_out.storeDouble(value, addressFor(data->machineLocal));
1712             break;
1713         }
1714             
1715         case FlushedInt32: {
1716             LValue value = lowInt32(m_node->child1());
1717             m_out.store32(value, payloadFor(data->machineLocal));
1718             break;
1719         }
1720             
1721         case FlushedInt52: {
1722             LValue value = lowInt52(m_node->child1());
1723             m_out.store64(value, addressFor(data->machineLocal));
1724             break;
1725         }
1726             
1727         case FlushedCell: {
1728             LValue value = lowCell(m_node->child1());
1729             m_out.store64(value, addressFor(data->machineLocal));
1730             break;
1731         }
1732             
1733         case FlushedBoolean: {
1734             speculateBoolean(m_node->child1());
1735             m_out.store64(
1736                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
1737                 addressFor(data->machineLocal));
1738             break;
1739         }
1740             
1741         default:
1742             DFG_CRASH(m_graph, m_node, "Bad flush format");
1743             break;
1744         }
1745     }
1746     
1747     void compileNoOp()
1748     {
1749         DFG_NODE_DO_TO_CHILDREN(m_graph, m_node, speculate);
1750     }
1751
1752     void compileToObjectOrCallObjectConstructor()
1753     {
1754         LValue value = lowJSValue(m_node->child1());
1755
1756         LBasicBlock isCellCase = m_out.newBlock();
1757         LBasicBlock slowCase = m_out.newBlock();
1758         LBasicBlock continuation = m_out.newBlock();
1759
1760         m_out.branch(isCell(value, provenType(m_node->child1())), usually(isCellCase), rarely(slowCase));
1761
1762         LBasicBlock lastNext = m_out.appendTo(isCellCase, slowCase);
1763         ValueFromBlock fastResult = m_out.anchor(value);
1764         m_out.branch(isObject(value), usually(continuation), rarely(slowCase));
1765
1766         m_out.appendTo(slowCase, continuation);
1767
1768         ValueFromBlock slowResult;
1769         if (m_node->op() == ToObject) {
1770             auto* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
1771             slowResult = m_out.anchor(vmCall(Int64, m_out.operation(operationToObject), m_callFrame, weakPointer(globalObject), value, m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()])));
1772         } else
1773             slowResult = m_out.anchor(vmCall(Int64, m_out.operation(operationCallObjectConstructor), m_callFrame, frozenPointer(m_node->cellOperand()), value));
1774         m_out.jump(continuation);
1775
1776         m_out.appendTo(continuation, lastNext);
1777         setJSValue(m_out.phi(Int64, fastResult, slowResult));
1778     }
1779     
1780     void compileToThis()
1781     {
1782         LValue value = lowJSValue(m_node->child1());
1783         
1784         LBasicBlock isCellCase = m_out.newBlock();
1785         LBasicBlock slowCase = m_out.newBlock();
1786         LBasicBlock continuation = m_out.newBlock();
1787         
1788         m_out.branch(
1789             isCell(value, provenType(m_node->child1())), usually(isCellCase), rarely(slowCase));
1790         
1791         LBasicBlock lastNext = m_out.appendTo(isCellCase, slowCase);
1792         ValueFromBlock fastResult = m_out.anchor(value);
1793         m_out.branch(
1794             m_out.testIsZero32(
1795                 m_out.load8ZeroExt32(value, m_heaps.JSCell_typeInfoFlags),
1796                 m_out.constInt32(OverridesToThis)),
1797             usually(continuation), rarely(slowCase));
1798         
1799         m_out.appendTo(slowCase, continuation);
1800         J_JITOperation_EJ function;
1801         if (m_graph.isStrictModeFor(m_node->origin.semantic))
1802             function = operationToThisStrict;
1803         else
1804             function = operationToThis;
1805         ValueFromBlock slowResult = m_out.anchor(
1806             vmCall(Int64, m_out.operation(function), m_callFrame, value));
1807         m_out.jump(continuation);
1808         
1809         m_out.appendTo(continuation, lastNext);
1810         setJSValue(m_out.phi(Int64, fastResult, slowResult));
1811     }
1812
1813     void compileValueAdd()
1814     {
1815         CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic);
1816         ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(m_node->origin.semantic.bytecodeIndex);
1817         Instruction* instruction = &baselineCodeBlock->instructions()[m_node->origin.semantic.bytecodeIndex];
1818         auto repatchingFunction = operationValueAddOptimize;
1819         auto nonRepatchingFunction = operationValueAdd;
1820         compileBinaryMathIC<JITAddGenerator>(arithProfile, instruction, repatchingFunction, nonRepatchingFunction);
1821     }
1822
1823     template <typename Generator, typename Func1, typename Func2,
1824         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>>
1825     void compileUnaryMathIC(ArithProfile* arithProfile, Instruction* instruction, Func1 repatchingFunction, Func2 nonRepatchingFunction)
1826     {
1827         Node* node = m_node;
1828
1829         LValue operand = lowJSValue(node->child1());
1830
1831         PatchpointValue* patchpoint = m_out.patchpoint(Int64);
1832         patchpoint->appendSomeRegister(operand);
1833         patchpoint->append(m_tagMask, ValueRep::lateReg(GPRInfo::tagMaskRegister));
1834         patchpoint->append(m_tagTypeNumber, ValueRep::lateReg(GPRInfo::tagTypeNumberRegister));
1835         RefPtr<PatchpointExceptionHandle> exceptionHandle = preparePatchpointForExceptions(patchpoint);
1836         patchpoint->numGPScratchRegisters = 1;
1837         patchpoint->clobber(RegisterSet::macroScratchRegisters());
1838         State* state = &m_ftlState;
1839         patchpoint->setGenerator(
1840             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
1841                 AllowMacroScratchRegisterUsage allowScratch(jit);
1842
1843                 Box<CCallHelpers::JumpList> exceptions =
1844                     exceptionHandle->scheduleExitCreation(params)->jumps(jit);
1845
1846 #if ENABLE(MATH_IC_STATS)
1847                 auto inlineStart = jit.label();
1848 #endif
1849
1850                 Box<MathICGenerationState> mathICGenerationState = Box<MathICGenerationState>::create();
1851                 JITUnaryMathIC<Generator>* mathIC = jit.codeBlock()->addMathIC<Generator>(arithProfile, instruction);
1852                 mathIC->m_generator = Generator(JSValueRegs(params[0].gpr()), JSValueRegs(params[1].gpr()), params.gpScratch(0));
1853
1854                 bool shouldEmitProfiling = false;
1855                 bool generatedInline = mathIC->generateInline(jit, *mathICGenerationState, shouldEmitProfiling);
1856
1857                 if (generatedInline) {
1858                     ASSERT(!mathICGenerationState->slowPathJumps.empty());
1859                     auto done = jit.label();
1860                     params.addLatePath([=] (CCallHelpers& jit) {
1861                         AllowMacroScratchRegisterUsage allowScratch(jit);
1862                         mathICGenerationState->slowPathJumps.link(&jit);
1863                         mathICGenerationState->slowPathStart = jit.label();
1864 #if ENABLE(MATH_IC_STATS)
1865                         auto slowPathStart = jit.label();
1866 #endif
1867
1868                         if (mathICGenerationState->shouldSlowPathRepatch) {
1869                             SlowPathCall call = callOperation(*state, params.unavailableRegisters(), jit, node->origin.semantic, exceptions.get(),
1870                                 repatchingFunction, params[0].gpr(), params[1].gpr(), CCallHelpers::TrustedImmPtr(mathIC));
1871                             mathICGenerationState->slowPathCall = call.call();
1872                         } else {
1873                             SlowPathCall call = callOperation(*state, params.unavailableRegisters(), jit, node->origin.semantic,
1874                                 exceptions.get(), nonRepatchingFunction, params[0].gpr(), params[1].gpr());
1875                             mathICGenerationState->slowPathCall = call.call();
1876                         }
1877                         jit.jump().linkTo(done, &jit);
1878
1879                         jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1880                             mathIC->finalizeInlineCode(*mathICGenerationState, linkBuffer);
1881                         });
1882
1883 #if ENABLE(MATH_IC_STATS)
1884                         auto slowPathEnd = jit.label();
1885                         jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1886                             size_t size = linkBuffer.locationOf(slowPathEnd).executableAddress<char*>() - linkBuffer.locationOf(slowPathStart).executableAddress<char*>();
1887                             mathIC->m_generatedCodeSize += size;
1888                         });
1889 #endif
1890                     });
1891                 } else {
1892                     callOperation(
1893                         *state, params.unavailableRegisters(), jit, node->origin.semantic, exceptions.get(),
1894                         nonRepatchingFunction, params[0].gpr(), params[1].gpr());
1895                 }
1896
1897 #if ENABLE(MATH_IC_STATS)
1898                 auto inlineEnd = jit.label();
1899                 jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1900                     size_t size = linkBuffer.locationOf(inlineEnd).executableAddress<char*>() - linkBuffer.locationOf(inlineStart).executableAddress<char*>();
1901                     mathIC->m_generatedCodeSize += size;
1902                 });
1903 #endif
1904             });
1905
1906         setJSValue(patchpoint);
1907     }
1908
1909     template <typename Generator, typename Func1, typename Func2,
1910         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>>
1911     void compileBinaryMathIC(ArithProfile* arithProfile, Instruction* instruction, Func1 repatchingFunction, Func2 nonRepatchingFunction)
1912     {
1913         Node* node = m_node;
1914         
1915         LValue left = lowJSValue(node->child1());
1916         LValue right = lowJSValue(node->child2());
1917
1918         SnippetOperand leftOperand(m_state.forNode(node->child1()).resultType());
1919         SnippetOperand rightOperand(m_state.forNode(node->child2()).resultType());
1920             
1921         PatchpointValue* patchpoint = m_out.patchpoint(Int64);
1922         patchpoint->appendSomeRegister(left);
1923         patchpoint->appendSomeRegister(right);
1924         patchpoint->append(m_tagMask, ValueRep::lateReg(GPRInfo::tagMaskRegister));
1925         patchpoint->append(m_tagTypeNumber, ValueRep::lateReg(GPRInfo::tagTypeNumberRegister));
1926         RefPtr<PatchpointExceptionHandle> exceptionHandle =
1927             preparePatchpointForExceptions(patchpoint);
1928         patchpoint->numGPScratchRegisters = 1;
1929         patchpoint->numFPScratchRegisters = 2;
1930         patchpoint->clobber(RegisterSet::macroScratchRegisters());
1931         State* state = &m_ftlState;
1932         patchpoint->setGenerator(
1933             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
1934                 AllowMacroScratchRegisterUsage allowScratch(jit);
1935
1936
1937                 Box<CCallHelpers::JumpList> exceptions =
1938                     exceptionHandle->scheduleExitCreation(params)->jumps(jit);
1939
1940 #if ENABLE(MATH_IC_STATS)
1941                 auto inlineStart = jit.label();
1942 #endif
1943
1944                 Box<MathICGenerationState> mathICGenerationState = Box<MathICGenerationState>::create();
1945                 JITBinaryMathIC<Generator>* mathIC = jit.codeBlock()->addMathIC<Generator>(arithProfile, instruction);
1946                 mathIC->m_generator = Generator(leftOperand, rightOperand, JSValueRegs(params[0].gpr()),
1947                     JSValueRegs(params[1].gpr()), JSValueRegs(params[2].gpr()), params.fpScratch(0),
1948                     params.fpScratch(1), params.gpScratch(0), InvalidFPRReg);
1949
1950                 bool shouldEmitProfiling = false;
1951                 bool generatedInline = mathIC->generateInline(jit, *mathICGenerationState, shouldEmitProfiling);
1952
1953                 if (generatedInline) {
1954                     ASSERT(!mathICGenerationState->slowPathJumps.empty());
1955                     auto done = jit.label();
1956                     params.addLatePath([=] (CCallHelpers& jit) {
1957                         AllowMacroScratchRegisterUsage allowScratch(jit);
1958                         mathICGenerationState->slowPathJumps.link(&jit);
1959                         mathICGenerationState->slowPathStart = jit.label();
1960 #if ENABLE(MATH_IC_STATS)
1961                         auto slowPathStart = jit.label();
1962 #endif
1963
1964                         if (mathICGenerationState->shouldSlowPathRepatch) {
1965                             SlowPathCall call = callOperation(*state, params.unavailableRegisters(), jit, node->origin.semantic, exceptions.get(),
1966                                 repatchingFunction, params[0].gpr(), params[1].gpr(), params[2].gpr(), CCallHelpers::TrustedImmPtr(mathIC));
1967                             mathICGenerationState->slowPathCall = call.call();
1968                         } else {
1969                             SlowPathCall call = callOperation(*state, params.unavailableRegisters(), jit, node->origin.semantic,
1970                                 exceptions.get(), nonRepatchingFunction, params[0].gpr(), params[1].gpr(), params[2].gpr());
1971                             mathICGenerationState->slowPathCall = call.call();
1972                         }
1973                         jit.jump().linkTo(done, &jit);
1974
1975                         jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1976                             mathIC->finalizeInlineCode(*mathICGenerationState, linkBuffer);
1977                         });
1978
1979 #if ENABLE(MATH_IC_STATS)
1980                         auto slowPathEnd = jit.label();
1981                         jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1982                             size_t size = linkBuffer.locationOf(slowPathEnd).executableAddress<char*>() - linkBuffer.locationOf(slowPathStart).executableAddress<char*>();
1983                             mathIC->m_generatedCodeSize += size;
1984                         });
1985 #endif
1986                     });
1987                 } else {
1988                     callOperation(
1989                         *state, params.unavailableRegisters(), jit, node->origin.semantic, exceptions.get(),
1990                         nonRepatchingFunction, params[0].gpr(), params[1].gpr(), params[2].gpr());
1991                 }
1992
1993 #if ENABLE(MATH_IC_STATS)
1994                 auto inlineEnd = jit.label();
1995                 jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1996                     size_t size = linkBuffer.locationOf(inlineEnd).executableAddress<char*>() - linkBuffer.locationOf(inlineStart).executableAddress<char*>();
1997                     mathIC->m_generatedCodeSize += size;
1998                 });
1999 #endif
2000             });
2001
2002         setJSValue(patchpoint);
2003     }
2004     
2005     void compileStrCat()
2006     {
2007         LValue result;
2008         if (m_node->child3()) {
2009             result = vmCall(
2010                 Int64, m_out.operation(operationStrCat3), m_callFrame,
2011                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
2012                 lowJSValue(m_node->child2(), ManualOperandSpeculation),
2013                 lowJSValue(m_node->child3(), ManualOperandSpeculation));
2014         } else {
2015             result = vmCall(
2016                 Int64, m_out.operation(operationStrCat2), m_callFrame,
2017                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
2018                 lowJSValue(m_node->child2(), ManualOperandSpeculation));
2019         }
2020         setJSValue(result);
2021     }
2022     
2023     void compileArithAddOrSub()
2024     {
2025         bool isSub =  m_node->op() == ArithSub;
2026         switch (m_node->binaryUseKind()) {
2027         case Int32Use: {
2028             LValue left = lowInt32(m_node->child1());
2029             LValue right = lowInt32(m_node->child2());
2030
2031             if (!shouldCheckOverflow(m_node->arithMode())) {
2032                 setInt32(isSub ? m_out.sub(left, right) : m_out.add(left, right));
2033                 break;
2034             }
2035
2036             CheckValue* result =
2037                 isSub ? m_out.speculateSub(left, right) : m_out.speculateAdd(left, right);
2038             blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);
2039             setInt32(result);
2040             break;
2041         }
2042             
2043         case Int52RepUse: {
2044             if (!abstractValue(m_node->child1()).couldBeType(SpecInt52Only)
2045                 && !abstractValue(m_node->child2()).couldBeType(SpecInt52Only)) {
2046                 Int52Kind kind;
2047                 LValue left = lowWhicheverInt52(m_node->child1(), kind);
2048                 LValue right = lowInt52(m_node->child2(), kind);
2049                 setInt52(isSub ? m_out.sub(left, right) : m_out.add(left, right), kind);
2050                 break;
2051             }
2052
2053             LValue left = lowInt52(m_node->child1());
2054             LValue right = lowInt52(m_node->child2());
2055             CheckValue* result =
2056                 isSub ? m_out.speculateSub(left, right) : m_out.speculateAdd(left, right);
2057             blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);
2058             setInt52(result);
2059             break;
2060         }
2061             
2062         case DoubleRepUse: {
2063             LValue C1 = lowDouble(m_node->child1());
2064             LValue C2 = lowDouble(m_node->child2());
2065
2066             setDouble(isSub ? m_out.doubleSub(C1, C2) : m_out.doubleAdd(C1, C2));
2067             break;
2068         }
2069
2070         case UntypedUse: {
2071             if (!isSub) {
2072                 DFG_CRASH(m_graph, m_node, "Bad use kind");
2073                 break;
2074             }
2075
2076             CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic);
2077             ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(m_node->origin.semantic.bytecodeIndex);
2078             Instruction* instruction = &baselineCodeBlock->instructions()[m_node->origin.semantic.bytecodeIndex];
2079             auto repatchingFunction = operationValueSubOptimize;
2080             auto nonRepatchingFunction = operationValueSub;
2081             compileBinaryMathIC<JITSubGenerator>(arithProfile, instruction, repatchingFunction, nonRepatchingFunction);
2082             break;
2083         }
2084
2085         default:
2086             DFG_CRASH(m_graph, m_node, "Bad use kind");
2087             break;
2088         }
2089     }
2090
2091     void compileArithClz32()
2092     {
2093         if (m_node->child1().useKind() == Int32Use || m_node->child1().useKind() == KnownInt32Use) {
2094             LValue operand = lowInt32(m_node->child1());
2095             setInt32(m_out.ctlz32(operand));
2096             return;
2097         }
2098         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse, m_node->child1().useKind());
2099         LValue argument = lowJSValue(m_node->child1());
2100         LValue result = vmCall(Int32, m_out.operation(operationArithClz32), m_callFrame, argument);
2101         setInt32(result);
2102     }
2103     
2104     void compileArithMul()
2105     {
2106         switch (m_node->binaryUseKind()) {
2107         case Int32Use: {
2108             LValue left = lowInt32(m_node->child1());
2109             LValue right = lowInt32(m_node->child2());
2110             
2111             LValue result;
2112
2113             if (!shouldCheckOverflow(m_node->arithMode()))
2114                 result = m_out.mul(left, right);
2115             else {
2116                 CheckValue* speculation = m_out.speculateMul(left, right);
2117                 blessSpeculation(speculation, Overflow, noValue(), nullptr, m_origin);
2118                 result = speculation;
2119             }
2120             
2121             if (shouldCheckNegativeZero(m_node->arithMode())) {
2122                 LBasicBlock slowCase = m_out.newBlock();
2123                 LBasicBlock continuation = m_out.newBlock();
2124                 
2125                 m_out.branch(
2126                     m_out.notZero32(result), usually(continuation), rarely(slowCase));
2127                 
2128                 LBasicBlock lastNext = m_out.appendTo(slowCase, continuation);
2129                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(left, m_out.int32Zero));
2130                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(right, m_out.int32Zero));
2131                 m_out.jump(continuation);
2132                 m_out.appendTo(continuation, lastNext);
2133             }
2134             
2135             setInt32(result);
2136             break;
2137         }
2138             
2139         case Int52RepUse: {
2140             Int52Kind kind;
2141             LValue left = lowWhicheverInt52(m_node->child1(), kind);
2142             LValue right = lowInt52(m_node->child2(), opposite(kind));
2143
2144             CheckValue* result = m_out.speculateMul(left, right);
2145             blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);
2146
2147             if (shouldCheckNegativeZero(m_node->arithMode())) {
2148                 LBasicBlock slowCase = m_out.newBlock();
2149                 LBasicBlock continuation = m_out.newBlock();
2150                 
2151                 m_out.branch(
2152                     m_out.notZero64(result), usually(continuation), rarely(slowCase));
2153                 
2154                 LBasicBlock lastNext = m_out.appendTo(slowCase, continuation);
2155                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(left, m_out.int64Zero));
2156                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(right, m_out.int64Zero));
2157                 m_out.jump(continuation);
2158                 m_out.appendTo(continuation, lastNext);
2159             }
2160             
2161             setInt52(result);
2162             break;
2163         }
2164             
2165         case DoubleRepUse: {
2166             setDouble(
2167                 m_out.doubleMul(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
2168             break;
2169         }
2170
2171         case UntypedUse: {
2172             CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic);
2173             ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(m_node->origin.semantic.bytecodeIndex);
2174             Instruction* instruction = &baselineCodeBlock->instructions()[m_node->origin.semantic.bytecodeIndex];
2175             auto repatchingFunction = operationValueMulOptimize;
2176             auto nonRepatchingFunction = operationValueMul;
2177             compileBinaryMathIC<JITMulGenerator>(arithProfile, instruction, repatchingFunction, nonRepatchingFunction);
2178             break;
2179         }
2180
2181         default:
2182             DFG_CRASH(m_graph, m_node, "Bad use kind");
2183             break;
2184         }
2185     }
2186
2187     void compileArithDiv()
2188     {
2189         switch (m_node->binaryUseKind()) {
2190         case Int32Use: {
2191             LValue numerator = lowInt32(m_node->child1());
2192             LValue denominator = lowInt32(m_node->child2());
2193
2194             if (shouldCheckNegativeZero(m_node->arithMode())) {
2195                 LBasicBlock zeroNumerator = m_out.newBlock();
2196                 LBasicBlock numeratorContinuation = m_out.newBlock();
2197
2198                 m_out.branch(
2199                     m_out.isZero32(numerator),
2200                     rarely(zeroNumerator), usually(numeratorContinuation));
2201
2202                 LBasicBlock innerLastNext = m_out.appendTo(zeroNumerator, numeratorContinuation);
2203
2204                 speculate(
2205                     NegativeZero, noValue(), 0, m_out.lessThan(denominator, m_out.int32Zero));
2206
2207                 m_out.jump(numeratorContinuation);
2208
2209                 m_out.appendTo(numeratorContinuation, innerLastNext);
2210             }
2211             
2212             if (shouldCheckOverflow(m_node->arithMode())) {
2213                 LBasicBlock unsafeDenominator = m_out.newBlock();
2214                 LBasicBlock continuation = m_out.newBlock();
2215
2216                 LValue adjustedDenominator = m_out.add(denominator, m_out.int32One);
2217                 m_out.branch(
2218                     m_out.above(adjustedDenominator, m_out.int32One),
2219                     usually(continuation), rarely(unsafeDenominator));
2220
2221                 LBasicBlock lastNext = m_out.appendTo(unsafeDenominator, continuation);
2222                 LValue neg2ToThe31 = m_out.constInt32(-2147483647-1);
2223                 speculate(Overflow, noValue(), nullptr, m_out.isZero32(denominator));
2224                 speculate(Overflow, noValue(), nullptr, m_out.equal(numerator, neg2ToThe31));
2225                 m_out.jump(continuation);
2226
2227                 m_out.appendTo(continuation, lastNext);
2228                 LValue result = m_out.div(numerator, denominator);
2229                 speculate(
2230                     Overflow, noValue(), 0,
2231                     m_out.notEqual(m_out.mul(result, denominator), numerator));
2232                 setInt32(result);
2233             } else
2234                 setInt32(m_out.chillDiv(numerator, denominator));
2235
2236             break;
2237         }
2238             
2239         case DoubleRepUse: {
2240             setDouble(m_out.doubleDiv(
2241                 lowDouble(m_node->child1()), lowDouble(m_node->child2())));
2242             break;
2243         }
2244
2245         case UntypedUse: {
2246             emitBinarySnippet<JITDivGenerator, NeedScratchFPR>(operationValueDiv);
2247             break;
2248         }
2249
2250         default:
2251             DFG_CRASH(m_graph, m_node, "Bad use kind");
2252             break;
2253         }
2254     }
2255     
2256     void compileArithMod()
2257     {
2258         switch (m_node->binaryUseKind()) {
2259         case Int32Use: {
2260             LValue numerator = lowInt32(m_node->child1());
2261             LValue denominator = lowInt32(m_node->child2());
2262
2263             LValue remainder;
2264             if (shouldCheckOverflow(m_node->arithMode())) {
2265                 LBasicBlock unsafeDenominator = m_out.newBlock();
2266                 LBasicBlock continuation = m_out.newBlock();
2267
2268                 LValue adjustedDenominator = m_out.add(denominator, m_out.int32One);
2269                 m_out.branch(
2270                     m_out.above(adjustedDenominator, m_out.int32One),
2271                     usually(continuation), rarely(unsafeDenominator));
2272
2273                 LBasicBlock lastNext = m_out.appendTo(unsafeDenominator, continuation);
2274                 LValue neg2ToThe31 = m_out.constInt32(-2147483647-1);
2275                 speculate(Overflow, noValue(), nullptr, m_out.isZero32(denominator));
2276                 speculate(Overflow, noValue(), nullptr, m_out.equal(numerator, neg2ToThe31));
2277                 m_out.jump(continuation);
2278
2279                 m_out.appendTo(continuation, lastNext);
2280                 LValue result = m_out.mod(numerator, denominator);
2281                 remainder = result;
2282             } else
2283                 remainder = m_out.chillMod(numerator, denominator);
2284
2285             if (shouldCheckNegativeZero(m_node->arithMode())) {
2286                 LBasicBlock negativeNumerator = m_out.newBlock();
2287                 LBasicBlock numeratorContinuation = m_out.newBlock();
2288
2289                 m_out.branch(
2290                     m_out.lessThan(numerator, m_out.int32Zero),
2291                     unsure(negativeNumerator), unsure(numeratorContinuation));
2292
2293                 LBasicBlock innerLastNext = m_out.appendTo(negativeNumerator, numeratorContinuation);
2294
2295                 speculate(NegativeZero, noValue(), 0, m_out.isZero32(remainder));
2296
2297                 m_out.jump(numeratorContinuation);
2298
2299                 m_out.appendTo(numeratorContinuation, innerLastNext);
2300             }
2301
2302             setInt32(remainder);
2303             break;
2304         }
2305             
2306         case DoubleRepUse: {
2307             setDouble(
2308                 m_out.doubleMod(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
2309             break;
2310         }
2311             
2312         default:
2313             DFG_CRASH(m_graph, m_node, "Bad use kind");
2314             break;
2315         }
2316     }
2317
2318     void compileArithMinOrMax()
2319     {
2320         switch (m_node->binaryUseKind()) {
2321         case Int32Use: {
2322             LValue left = lowInt32(m_node->child1());
2323             LValue right = lowInt32(m_node->child2());
2324             
2325             setInt32(
2326                 m_out.select(
2327                     m_node->op() == ArithMin
2328                         ? m_out.lessThan(left, right)
2329                         : m_out.lessThan(right, left),
2330                     left, right));
2331             break;
2332         }
2333             
2334         case DoubleRepUse: {
2335             LValue left = lowDouble(m_node->child1());
2336             LValue right = lowDouble(m_node->child2());
2337             
2338             LBasicBlock notLessThan = m_out.newBlock();
2339             LBasicBlock continuation = m_out.newBlock();
2340             
2341             Vector<ValueFromBlock, 2> results;
2342             
2343             results.append(m_out.anchor(left));
2344             m_out.branch(
2345                 m_node->op() == ArithMin
2346                     ? m_out.doubleLessThan(left, right)
2347                     : m_out.doubleGreaterThan(left, right),
2348                 unsure(continuation), unsure(notLessThan));
2349             
2350             LBasicBlock lastNext = m_out.appendTo(notLessThan, continuation);
2351             results.append(m_out.anchor(m_out.select(
2352                 m_node->op() == ArithMin
2353                     ? m_out.doubleGreaterThanOrEqual(left, right)
2354                     : m_out.doubleLessThanOrEqual(left, right),
2355                 right, m_out.constDouble(PNaN))));
2356             m_out.jump(continuation);
2357             
2358             m_out.appendTo(continuation, lastNext);
2359             setDouble(m_out.phi(Double, results));
2360             break;
2361         }
2362             
2363         default:
2364             DFG_CRASH(m_graph, m_node, "Bad use kind");
2365             break;
2366         }
2367     }
2368     
2369     void compileArithAbs()
2370     {
2371         switch (m_node->child1().useKind()) {
2372         case Int32Use: {
2373             LValue value = lowInt32(m_node->child1());
2374
2375             LValue mask = m_out.aShr(value, m_out.constInt32(31));
2376             LValue result = m_out.bitXor(mask, m_out.add(mask, value));
2377
2378             if (shouldCheckOverflow(m_node->arithMode()))
2379                 speculate(Overflow, noValue(), 0, m_out.lessThan(result, m_out.int32Zero));
2380
2381             setInt32(result);
2382             break;
2383         }
2384             
2385         case DoubleRepUse: {
2386             setDouble(m_out.doubleAbs(lowDouble(m_node->child1())));
2387             break;
2388         }
2389             
2390         default: {
2391             DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse, m_node->child1().useKind());
2392             LValue argument = lowJSValue(m_node->child1());
2393             LValue result = vmCall(Double, m_out.operation(operationArithAbs), m_callFrame, argument);
2394             setDouble(result);
2395             break;
2396         }
2397         }
2398     }
2399
2400     void compileArithUnary()
2401     {
2402         if (m_node->child1().useKind() == DoubleRepUse) {
2403             setDouble(m_out.doubleUnary(m_node->arithUnaryType(), lowDouble(m_node->child1())));
2404             return;
2405         }
2406         LValue argument = lowJSValue(m_node->child1());
2407         LValue result = vmCall(Double, m_out.operation(DFG::arithUnaryOperation(m_node->arithUnaryType())), m_callFrame, argument);
2408         setDouble(result);
2409     }
2410
2411     void compileArithPow()
2412     {
2413         if (m_node->child2().useKind() == Int32Use)
2414             setDouble(m_out.doublePowi(lowDouble(m_node->child1()), lowInt32(m_node->child2())));
2415         else {
2416             LValue base = lowDouble(m_node->child1());
2417             LValue exponent = lowDouble(m_node->child2());
2418
2419             LBasicBlock integerExponentIsSmallBlock = m_out.newBlock();
2420             LBasicBlock integerExponentPowBlock = m_out.newBlock();
2421             LBasicBlock doubleExponentPowBlockEntry = m_out.newBlock();
2422             LBasicBlock nanExceptionBaseIsOne = m_out.newBlock();
2423             LBasicBlock nanExceptionExponentIsInfinity = m_out.newBlock();
2424             LBasicBlock testExponentIsOneHalf = m_out.newBlock();
2425             LBasicBlock handleBaseZeroExponentIsOneHalf = m_out.newBlock();
2426             LBasicBlock handleInfinityForExponentIsOneHalf = m_out.newBlock();
2427             LBasicBlock exponentIsOneHalfNormal = m_out.newBlock();
2428             LBasicBlock exponentIsOneHalfInfinity = m_out.newBlock();
2429             LBasicBlock testExponentIsNegativeOneHalf = m_out.newBlock();
2430             LBasicBlock testBaseZeroExponentIsNegativeOneHalf = m_out.newBlock();
2431             LBasicBlock handleBaseZeroExponentIsNegativeOneHalf = m_out.newBlock();
2432             LBasicBlock handleInfinityForExponentIsNegativeOneHalf = m_out.newBlock();
2433             LBasicBlock exponentIsNegativeOneHalfNormal = m_out.newBlock();
2434             LBasicBlock exponentIsNegativeOneHalfInfinity = m_out.newBlock();
2435             LBasicBlock powBlock = m_out.newBlock();
2436             LBasicBlock nanExceptionResultIsNaN = m_out.newBlock();
2437             LBasicBlock continuation = m_out.newBlock();
2438
2439             LValue integerExponent = m_out.doubleToInt(exponent);
2440             LValue integerExponentConvertedToDouble = m_out.intToDouble(integerExponent);
2441             LValue exponentIsInteger = m_out.doubleEqual(exponent, integerExponentConvertedToDouble);
2442             m_out.branch(exponentIsInteger, unsure(integerExponentIsSmallBlock), unsure(doubleExponentPowBlockEntry));
2443
2444             LBasicBlock lastNext = m_out.appendTo(integerExponentIsSmallBlock, integerExponentPowBlock);
2445             LValue integerExponentBelowMax = m_out.belowOrEqual(integerExponent, m_out.constInt32(maxExponentForIntegerMathPow));
2446             m_out.branch(integerExponentBelowMax, usually(integerExponentPowBlock), rarely(doubleExponentPowBlockEntry));
2447
2448             m_out.appendTo(integerExponentPowBlock, doubleExponentPowBlockEntry);
2449             ValueFromBlock powDoubleIntResult = m_out.anchor(m_out.doublePowi(base, integerExponent));
2450             m_out.jump(continuation);
2451
2452             // If y is NaN, the result is NaN.
2453             m_out.appendTo(doubleExponentPowBlockEntry, nanExceptionBaseIsOne);
2454             LValue exponentIsNaN;
2455             if (provenType(m_node->child2()) & SpecDoubleNaN)
2456                 exponentIsNaN = m_out.doubleNotEqualOrUnordered(exponent, exponent);
2457             else
2458                 exponentIsNaN = m_out.booleanFalse;
2459             m_out.branch(exponentIsNaN, rarely(nanExceptionResultIsNaN), usually(nanExceptionBaseIsOne));
2460
2461             // If abs(x) is 1 and y is +infinity, the result is NaN.
2462             // If abs(x) is 1 and y is -infinity, the result is NaN.
2463
2464             //     Test if base == 1.
2465             m_out.appendTo(nanExceptionBaseIsOne, nanExceptionExponentIsInfinity);
2466             LValue absoluteBase = m_out.doubleAbs(base);
2467             LValue absoluteBaseIsOne = m_out.doubleEqual(absoluteBase, m_out.constDouble(1));
2468             m_out.branch(absoluteBaseIsOne, rarely(nanExceptionExponentIsInfinity), usually(testExponentIsOneHalf));
2469
2470             //     Test if abs(y) == Infinity.
2471             m_out.appendTo(nanExceptionExponentIsInfinity, testExponentIsOneHalf);
2472             LValue absoluteExponent = m_out.doubleAbs(exponent);
2473             LValue absoluteExponentIsInfinity = m_out.doubleEqual(absoluteExponent, m_out.constDouble(std::numeric_limits<double>::infinity()));
2474             m_out.branch(absoluteExponentIsInfinity, rarely(nanExceptionResultIsNaN), usually(testExponentIsOneHalf));
2475
2476             // If y == 0.5 or y == -0.5, handle it through SQRT.
2477             // We have be carefuly with -0 and -Infinity.
2478
2479             //     Test if y == 0.5
2480             m_out.appendTo(testExponentIsOneHalf, handleBaseZeroExponentIsOneHalf);
2481             LValue exponentIsOneHalf = m_out.doubleEqual(exponent, m_out.constDouble(0.5));
2482             m_out.branch(exponentIsOneHalf, rarely(handleBaseZeroExponentIsOneHalf), usually(testExponentIsNegativeOneHalf));
2483
2484             //     Handle x == -0.
2485             m_out.appendTo(handleBaseZeroExponentIsOneHalf, handleInfinityForExponentIsOneHalf);
2486             LValue baseIsZeroExponentIsOneHalf = m_out.doubleEqual(base, m_out.doubleZero);
2487             ValueFromBlock zeroResultExponentIsOneHalf = m_out.anchor(m_out.doubleZero);
2488             m_out.branch(baseIsZeroExponentIsOneHalf, rarely(continuation), usually(handleInfinityForExponentIsOneHalf));
2489
2490             //     Test if abs(x) == Infinity.
2491             m_out.appendTo(handleInfinityForExponentIsOneHalf, exponentIsOneHalfNormal);
2492             LValue absoluteBaseIsInfinityOneHalf = m_out.doubleEqual(absoluteBase, m_out.constDouble(std::numeric_limits<double>::infinity()));
2493             m_out.branch(absoluteBaseIsInfinityOneHalf, rarely(exponentIsOneHalfInfinity), usually(exponentIsOneHalfNormal));
2494
2495             //     The exponent is 0.5, the base is finite or NaN, we can use SQRT.
2496             m_out.appendTo(exponentIsOneHalfNormal, exponentIsOneHalfInfinity);
2497             ValueFromBlock sqrtResult = m_out.anchor(m_out.doubleSqrt(base));
2498             m_out.jump(continuation);
2499
2500             //     The exponent is 0.5, the base is infinite, the result is always infinite.
2501             m_out.appendTo(exponentIsOneHalfInfinity, testExponentIsNegativeOneHalf);
2502             ValueFromBlock sqrtInfinityResult = m_out.anchor(m_out.constDouble(std::numeric_limits<double>::infinity()));
2503             m_out.jump(continuation);
2504
2505             //     Test if y == -0.5
2506             m_out.appendTo(testExponentIsNegativeOneHalf, testBaseZeroExponentIsNegativeOneHalf);
2507             LValue exponentIsNegativeOneHalf = m_out.doubleEqual(exponent, m_out.constDouble(-0.5));
2508             m_out.branch(exponentIsNegativeOneHalf, rarely(testBaseZeroExponentIsNegativeOneHalf), usually(powBlock));
2509
2510             //     Handle x == -0.
2511             m_out.appendTo(testBaseZeroExponentIsNegativeOneHalf, handleBaseZeroExponentIsNegativeOneHalf);
2512             LValue baseIsZeroExponentIsNegativeOneHalf = m_out.doubleEqual(base, m_out.doubleZero);
2513             m_out.branch(baseIsZeroExponentIsNegativeOneHalf, rarely(handleBaseZeroExponentIsNegativeOneHalf), usually(handleInfinityForExponentIsNegativeOneHalf));
2514
2515             m_out.appendTo(handleBaseZeroExponentIsNegativeOneHalf, handleInfinityForExponentIsNegativeOneHalf);
2516             ValueFromBlock oneOverSqrtZeroResult = m_out.anchor(m_out.constDouble(std::numeric_limits<double>::infinity()));
2517             m_out.jump(continuation);
2518
2519             //     Test if abs(x) == Infinity.
2520             m_out.appendTo(handleInfinityForExponentIsNegativeOneHalf, exponentIsNegativeOneHalfNormal);
2521             LValue absoluteBaseIsInfinityNegativeOneHalf = m_out.doubleEqual(absoluteBase, m_out.constDouble(std::numeric_limits<double>::infinity()));
2522             m_out.branch(absoluteBaseIsInfinityNegativeOneHalf, rarely(exponentIsNegativeOneHalfInfinity), usually(exponentIsNegativeOneHalfNormal));
2523
2524             //     The exponent is -0.5, the base is finite or NaN, we can use 1/SQRT.
2525             m_out.appendTo(exponentIsNegativeOneHalfNormal, exponentIsNegativeOneHalfInfinity);
2526             LValue sqrtBase = m_out.doubleSqrt(base);
2527             ValueFromBlock oneOverSqrtResult = m_out.anchor(m_out.div(m_out.constDouble(1.), sqrtBase));
2528             m_out.jump(continuation);
2529
2530             //     The exponent is -0.5, the base is infinite, the result is always zero.
2531             m_out.appendTo(exponentIsNegativeOneHalfInfinity, powBlock);
2532             ValueFromBlock oneOverSqrtInfinityResult = m_out.anchor(m_out.doubleZero);
2533             m_out.jump(continuation);
2534
2535             m_out.appendTo(powBlock, nanExceptionResultIsNaN);
2536             ValueFromBlock powResult = m_out.anchor(m_out.doublePow(base, exponent));
2537             m_out.jump(continuation);
2538
2539             m_out.appendTo(nanExceptionResultIsNaN, continuation);
2540             ValueFromBlock pureNan = m_out.anchor(m_out.constDouble(PNaN));
2541             m_out.jump(continuation);
2542
2543             m_out.appendTo(continuation, lastNext);
2544             setDouble(m_out.phi(Double, powDoubleIntResult, zeroResultExponentIsOneHalf, sqrtResult, sqrtInfinityResult, oneOverSqrtZeroResult, oneOverSqrtResult, oneOverSqrtInfinityResult, powResult, pureNan));
2545         }
2546     }
2547
2548     void compileArithRandom()
2549     {
2550         JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
2551
2552         // Inlined WeakRandom::advance().
2553         // uint64_t x = m_low;
2554         void* lowAddress = reinterpret_cast<uint8_t*>(globalObject) + JSGlobalObject::weakRandomOffset() + WeakRandom::lowOffset();
2555         LValue low = m_out.load64(m_out.absolute(lowAddress));
2556         // uint64_t y = m_high;
2557         void* highAddress = reinterpret_cast<uint8_t*>(globalObject) + JSGlobalObject::weakRandomOffset() + WeakRandom::highOffset();
2558         LValue high = m_out.load64(m_out.absolute(highAddress));
2559         // m_low = y;
2560         m_out.store64(high, m_out.absolute(lowAddress));
2561
2562         // x ^= x << 23;
2563         LValue phase1 = m_out.bitXor(m_out.shl(low, m_out.constInt64(23)), low);
2564
2565         // x ^= x >> 17;
2566         LValue phase2 = m_out.bitXor(m_out.lShr(phase1, m_out.constInt64(17)), phase1);
2567
2568         // x ^= y ^ (y >> 26);
2569         LValue phase3 = m_out.bitXor(m_out.bitXor(high, m_out.lShr(high, m_out.constInt64(26))), phase2);
2570
2571         // m_high = x;
2572         m_out.store64(phase3, m_out.absolute(highAddress));
2573
2574         // return x + y;
2575         LValue random64 = m_out.add(phase3, high);
2576
2577         // Extract random 53bit. [0, 53] bit is safe integer number ranges in double representation.
2578         LValue random53 = m_out.bitAnd(random64, m_out.constInt64((1ULL << 53) - 1));
2579
2580         LValue double53Integer = m_out.intToDouble(random53);
2581
2582         // Convert `(53bit double integer value) / (1 << 53)` to `(53bit double integer value) * (1.0 / (1 << 53))`.
2583         // In latter case, `1.0 / (1 << 53)` will become a double value represented as (mantissa = 0 & exp = 970, it means 1e-(2**54)).
2584         static const double scale = 1.0 / (1ULL << 53);
2585
2586         // Multiplying 1e-(2**54) with the double integer does not change anything of the mantissa part of the double integer.
2587         // It just reduces the exp part of the given 53bit double integer.
2588         // (Except for 0.0. This is specially handled and in this case, exp just becomes 0.)
2589         // Now we get 53bit precision random double value in [0, 1).
2590         LValue result = m_out.doubleMul(double53Integer, m_out.constDouble(scale));
2591
2592         setDouble(result);
2593     }
2594
2595     void compileArithRound()
2596     {
2597         if (m_node->child1().useKind() == DoubleRepUse) {
2598             LValue result = nullptr;
2599             if (producesInteger(m_node->arithRoundingMode()) && !shouldCheckNegativeZero(m_node->arithRoundingMode())) {
2600                 LValue value = lowDouble(m_node->child1());
2601                 result = m_out.doubleFloor(m_out.doubleAdd(value, m_out.constDouble(0.5)));
2602             } else {
2603                 LBasicBlock realPartIsMoreThanHalf = m_out.newBlock();
2604                 LBasicBlock continuation = m_out.newBlock();
2605
2606                 LValue value = lowDouble(m_node->child1());
2607                 LValue integerValue = m_out.doubleCeil(value);
2608                 ValueFromBlock integerValueResult = m_out.anchor(integerValue);
2609
2610                 LValue realPart = m_out.doubleSub(integerValue, value);
2611
2612                 m_out.branch(m_out.doubleGreaterThanOrUnordered(realPart, m_out.constDouble(0.5)), unsure(realPartIsMoreThanHalf), unsure(continuation));
2613
2614                 LBasicBlock lastNext = m_out.appendTo(realPartIsMoreThanHalf, continuation);
2615                 LValue integerValueRoundedDown = m_out.doubleSub(integerValue, m_out.constDouble(1));
2616                 ValueFromBlock integerValueRoundedDownResult = m_out.anchor(integerValueRoundedDown);
2617                 m_out.jump(continuation);
2618                 m_out.appendTo(continuation, lastNext);
2619
2620                 result = m_out.phi(Double, integerValueResult, integerValueRoundedDownResult);
2621             }
2622
2623             if (producesInteger(m_node->arithRoundingMode())) {
2624                 LValue integerValue = convertDoubleToInt32(result, shouldCheckNegativeZero(m_node->arithRoundingMode()));
2625                 setInt32(integerValue);
2626             } else
2627                 setDouble(result);
2628             return;
2629         }
2630
2631         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse, m_node->child1().useKind());
2632         LValue argument = lowJSValue(m_node->child1());
2633         setJSValue(vmCall(Int64, m_out.operation(operationArithRound), m_callFrame, argument));
2634     }
2635
2636     void compileArithFloor()
2637     {
2638         if (m_node->child1().useKind() == DoubleRepUse) {
2639             LValue value = lowDouble(m_node->child1());
2640             LValue integerValue = m_out.doubleFloor(value);
2641             if (producesInteger(m_node->arithRoundingMode()))
2642                 setInt32(convertDoubleToInt32(integerValue, shouldCheckNegativeZero(m_node->arithRoundingMode())));
2643             else
2644                 setDouble(integerValue);
2645             return;
2646         }
2647         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse, m_node->child1().useKind());
2648         LValue argument = lowJSValue(m_node->child1());
2649         setJSValue(vmCall(Int64, m_out.operation(operationArithFloor), m_callFrame, argument));
2650     }
2651
2652     void compileArithCeil()
2653     {
2654         if (m_node->child1().useKind() == DoubleRepUse) {
2655             LValue value = lowDouble(m_node->child1());
2656             LValue integerValue = m_out.doubleCeil(value);
2657             if (producesInteger(m_node->arithRoundingMode()))
2658                 setInt32(convertDoubleToInt32(integerValue, shouldCheckNegativeZero(m_node->arithRoundingMode())));
2659             else
2660                 setDouble(integerValue);
2661             return;
2662         }
2663         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse, m_node->child1().useKind());
2664         LValue argument = lowJSValue(m_node->child1());
2665         setJSValue(vmCall(Int64, m_out.operation(operationArithCeil), m_callFrame, argument));
2666     }
2667
2668     void compileArithTrunc()
2669     {
2670         if (m_node->child1().useKind() == DoubleRepUse) {
2671             LValue value = lowDouble(m_node->child1());
2672             LValue result = m_out.doubleTrunc(value);
2673             if (producesInteger(m_node->arithRoundingMode()))
2674                 setInt32(convertDoubleToInt32(result, shouldCheckNegativeZero(m_node->arithRoundingMode())));
2675             else
2676                 setDouble(result);
2677             return;
2678         }
2679         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse, m_node->child1().useKind());
2680         LValue argument = lowJSValue(m_node->child1());
2681         setJSValue(vmCall(Int64, m_out.operation(operationArithTrunc), m_callFrame, argument));
2682     }
2683
2684     void compileArithSqrt()
2685     {
2686         if (m_node->child1().useKind() == DoubleRepUse) {
2687             setDouble(m_out.doubleSqrt(lowDouble(m_node->child1())));
2688             return;
2689         }
2690         LValue argument = lowJSValue(m_node->child1());
2691         LValue result = vmCall(Double, m_out.operation(operationArithSqrt), m_callFrame, argument);
2692         setDouble(result);
2693     }
2694
2695     void compileArithFRound()
2696     {
2697         if (m_node->child1().useKind() == DoubleRepUse) {
2698             setDouble(m_out.fround(lowDouble(m_node->child1())));
2699             return;
2700         }
2701         LValue argument = lowJSValue(m_node->child1());
2702         LValue result = vmCall(Double, m_out.operation(operationArithFRound), m_callFrame, argument);
2703         setDouble(result);
2704     }
2705     
2706     void compileArithNegate()
2707     {
2708         switch (m_node->child1().useKind()) {
2709         case Int32Use: {
2710             LValue value = lowInt32(m_node->child1());
2711             
2712             LValue result;
2713             if (!shouldCheckOverflow(m_node->arithMode()))
2714                 result = m_out.neg(value);
2715             else if (!shouldCheckNegativeZero(m_node->arithMode())) {
2716                 CheckValue* check = m_out.speculateSub(m_out.int32Zero, value);
2717                 blessSpeculation(check, Overflow, noValue(), nullptr, m_origin);
2718                 result = check;
2719             } else {
2720                 speculate(Overflow, noValue(), 0, m_out.testIsZero32(value, m_out.constInt32(0x7fffffff)));
2721                 result = m_out.neg(value);
2722             }
2723
2724             setInt32(result);
2725             break;
2726         }
2727             
2728         case Int52RepUse: {
2729             if (!abstractValue(m_node->child1()).couldBeType(SpecInt52Only)) {
2730                 Int52Kind kind;
2731                 LValue value = lowWhicheverInt52(m_node->child1(), kind);
2732                 LValue result = m_out.neg(value);
2733                 if (shouldCheckNegativeZero(m_node->arithMode()))
2734                     speculate(NegativeZero, noValue(), 0, m_out.isZero64(result));
2735                 setInt52(result, kind);
2736                 break;
2737             }
2738             
2739             LValue value = lowInt52(m_node->child1());
2740             CheckValue* result = m_out.speculateSub(m_out.int64Zero, value);
2741             blessSpeculation(result, Int52Overflow, noValue(), nullptr, m_origin);
2742             if (shouldCheckNegativeZero(m_node->arithMode()))
2743                 speculate(NegativeZero, noValue(), 0, m_out.isZero64(result));
2744             setInt52(result);
2745             break;
2746         }
2747             
2748         case DoubleRepUse: {
2749             setDouble(m_out.doubleNeg(lowDouble(m_node->child1())));
2750             break;
2751         }
2752             
2753         default:
2754             DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse, m_node->child1().useKind());
2755             CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic);
2756             ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(m_node->origin.semantic.bytecodeIndex);
2757             Instruction* instruction = &baselineCodeBlock->instructions()[m_node->origin.semantic.bytecodeIndex];
2758             auto repatchingFunction = operationArithNegateOptimize;
2759             auto nonRepatchingFunction = operationArithNegate;
2760             compileUnaryMathIC<JITNegGenerator>(arithProfile, instruction, repatchingFunction, nonRepatchingFunction);
2761             break;
2762         }
2763     }
2764     
2765     void compileBitAnd()
2766     {
2767         if (m_node->isBinaryUseKind(UntypedUse)) {
2768             emitBinaryBitOpSnippet<JITBitAndGenerator>(operationValueBitAnd);
2769             return;
2770         }
2771         setInt32(m_out.bitAnd(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2772     }
2773     
2774     void compileBitOr()
2775     {
2776         if (m_node->isBinaryUseKind(UntypedUse)) {
2777             emitBinaryBitOpSnippet<JITBitOrGenerator>(operationValueBitOr);
2778             return;
2779         }
2780         setInt32(m_out.bitOr(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2781     }
2782     
2783     void compileBitXor()
2784     {
2785         if (m_node->isBinaryUseKind(UntypedUse)) {
2786             emitBinaryBitOpSnippet<JITBitXorGenerator>(operationValueBitXor);
2787             return;
2788         }
2789         setInt32(m_out.bitXor(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2790     }
2791     
2792     void compileBitRShift()
2793     {
2794         if (m_node->isBinaryUseKind(UntypedUse)) {
2795             emitRightShiftSnippet(JITRightShiftGenerator::SignedShift);
2796             return;
2797         }
2798         setInt32(m_out.aShr(
2799             lowInt32(m_node->child1()),
2800             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2801     }
2802     
2803     void compileBitLShift()
2804     {
2805         if (m_node->isBinaryUseKind(UntypedUse)) {
2806             emitBinaryBitOpSnippet<JITLeftShiftGenerator>(operationValueBitLShift);
2807             return;
2808         }
2809         setInt32(m_out.shl(
2810             lowInt32(m_node->child1()),
2811             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2812     }
2813     
2814     void compileBitURShift()
2815     {
2816         if (m_node->isBinaryUseKind(UntypedUse)) {
2817             emitRightShiftSnippet(JITRightShiftGenerator::UnsignedShift);
2818             return;
2819         }
2820         setInt32(m_out.lShr(
2821             lowInt32(m_node->child1()),
2822             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2823     }
2824     
2825     void compileUInt32ToNumber()
2826     {
2827         LValue value = lowInt32(m_node->child1());
2828
2829         if (doesOverflow(m_node->arithMode())) {
2830             setStrictInt52(m_out.zeroExtPtr(value));
2831             return;
2832         }
2833
2834         speculate(Overflow, noValue(), 0, m_out.lessThan(value, m_out.int32Zero));
2835         setInt32(value);
2836     }
2837     
2838     void compileCheckStructure()
2839     {
2840         ExitKind exitKind;
2841         if (m_node->child1()->hasConstant())
2842             exitKind = BadConstantCache;
2843         else
2844             exitKind = BadCache;
2845
2846         switch (m_node->child1().useKind()) {
2847         case CellUse:
2848         case KnownCellUse: {
2849             LValue cell = lowCell(m_node->child1());
2850             
2851             checkStructure(
2852                 m_out.load32(cell, m_heaps.JSCell_structureID), jsValueValue(cell),
2853                 exitKind, m_node->structureSet(),
2854                 [&] (RegisteredStructure structure) {
2855                     return weakStructureID(structure);
2856                 });
2857             return;
2858         }
2859
2860         case CellOrOtherUse: {
2861             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
2862
2863             LBasicBlock cellCase = m_out.newBlock();
2864             LBasicBlock notCellCase = m_out.newBlock();
2865             LBasicBlock continuation = m_out.newBlock();
2866
2867             m_out.branch(
2868                 isCell(value, provenType(m_node->child1())), unsure(cellCase), unsure(notCellCase));
2869
2870             LBasicBlock lastNext = m_out.appendTo(cellCase, notCellCase);
2871             checkStructure(
2872                 m_out.load32(value, m_heaps.JSCell_structureID), jsValueValue(value),
2873                 exitKind, m_node->structureSet(),
2874                 [&] (RegisteredStructure structure) {
2875                     return weakStructureID(structure);
2876                 });
2877             m_out.jump(continuation);
2878
2879             m_out.appendTo(notCellCase, continuation);
2880             FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), SpecCell | SpecOther, isNotOther(value));
2881             m_out.jump(continuation);
2882
2883             m_out.appendTo(continuation, lastNext);
2884             return;
2885         }
2886
2887         default:
2888             DFG_CRASH(m_graph, m_node, "Bad use kind");
2889             return;
2890         }
2891     }
2892
2893     void compileCheckStructureOrEmpty()
2894     {
2895         ExitKind exitKind;
2896         if (m_node->child1()->hasConstant())
2897             exitKind = BadConstantCache;
2898         else
2899             exitKind = BadCache;
2900
2901         LValue cell = lowCell(m_node->child1());
2902         bool maySeeEmptyValue = m_interpreter.forNode(m_node->child1()).m_type & SpecEmpty;
2903         LBasicBlock notEmpty;
2904         LBasicBlock continuation;
2905         LBasicBlock lastNext;
2906         if (maySeeEmptyValue) {
2907             notEmpty = m_out.newBlock();
2908             continuation = m_out.newBlock();
2909             m_out.branch(m_out.isZero64(cell), unsure(continuation), unsure(notEmpty));
2910             lastNext = m_out.appendTo(notEmpty, continuation);
2911         }
2912
2913         checkStructure(
2914             m_out.load32(cell, m_heaps.JSCell_structureID), jsValueValue(cell),
2915             exitKind, m_node->structureSet(),
2916             [&] (RegisteredStructure structure) {
2917                 return weakStructureID(structure);
2918             });
2919
2920         if (maySeeEmptyValue) {
2921             m_out.jump(continuation);
2922             m_out.appendTo(continuation, lastNext);
2923         }
2924     }
2925     
2926     void compileCheckCell()
2927     {
2928         LValue cell = lowCell(m_node->child1());
2929         
2930         speculate(
2931             BadCell, jsValueValue(cell), m_node->child1().node(),
2932             m_out.notEqual(cell, weakPointer(m_node->cellOperand()->cell())));
2933     }
2934     
2935     void compileCheckBadCell()
2936     {
2937         terminate(BadCell);
2938     }
2939
2940     void compileCheckNotEmpty()
2941     {
2942         speculate(TDZFailure, noValue(), nullptr, m_out.isZero64(lowJSValue(m_node->child1())));
2943     }
2944
2945     void compileAssertNotEmpty()
2946     {
2947         if (!validationEnabled())
2948             return;
2949
2950         B3::PatchpointValue* patchpoint = m_out.patchpoint(Void);
2951         patchpoint->appendSomeRegister(lowJSValue(m_node->child1()));
2952         patchpoint->setGenerator(
2953             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
2954                 AllowMacroScratchRegisterUsage allowScratch(jit);
2955                 GPRReg input =  params[0].gpr();
2956                 CCallHelpers::Jump done = jit.branchTest64(CCallHelpers::NonZero, input);
2957                 jit.breakpoint();
2958                 done.link(&jit);
2959             });
2960     }
2961
2962     void compileCheckStringIdent()
2963     {
2964         UniquedStringImpl* uid = m_node->uidOperand();
2965         LValue stringImpl = lowStringIdent(m_node->child1());
2966         speculate(BadIdent, noValue(), nullptr, m_out.notEqual(stringImpl, m_out.constIntPtr(uid)));
2967     }
2968
2969     void compileGetExecutable()
2970     {
2971         LValue cell = lowCell(m_node->child1());
2972         speculateFunction(m_node->child1(), cell);
2973         setJSValue(
2974             m_out.bitXor(
2975                 m_out.loadPtr(cell, m_heaps.JSFunction_executable),
2976                 m_out.constIntPtr(JSFunctionPoison::key())));
2977     }
2978     
2979     void compileArrayify()
2980     {
2981         LValue cell = lowCell(m_node->child1());
2982         LValue property = !!m_node->child2() ? lowInt32(m_node->child2()) : 0;
2983         
2984         LBasicBlock unexpectedStructure = m_out.newBlock();
2985         LBasicBlock continuation = m_out.newBlock();
2986         
2987         auto isUnexpectedArray = [&] (LValue cell) {
2988             if (m_node->op() == Arrayify)
2989                 return m_out.logicalNot(isArrayTypeForArrayify(cell, m_node->arrayMode()));
2990
2991             ASSERT(m_node->op() == ArrayifyToStructure);
2992             return m_out.notEqual(m_out.load32(cell, m_heaps.JSCell_structureID), weakStructureID(m_node->structure()));
2993         };
2994
2995         m_out.branch(isUnexpectedArray(cell), rarely(unexpectedStructure), usually(continuation));
2996
2997         LBasicBlock lastNext = m_out.appendTo(unexpectedStructure, continuation);
2998         
2999         if (property) {
3000             switch (m_node->arrayMode().type()) {
3001             case Array::Int32:
3002             case Array::Double:
3003             case Array::Contiguous:
3004                 speculate(
3005                     Uncountable, noValue(), 0,
3006                     m_out.aboveOrEqual(property, m_out.constInt32(MIN_SPARSE_ARRAY_INDEX)));
3007                 break;
3008             default:
3009                 break;
3010             }
3011         }
3012         
3013         switch (m_node->arrayMode().type()) {
3014         case Array::Int32:
3015             vmCall(Void, m_out.operation(operationEnsureInt32), m_callFrame, cell);
3016             break;
3017         case Array::Double:
3018             vmCall(Void, m_out.operation(operationEnsureDouble), m_callFrame, cell);
3019             break;
3020         case Array::Contiguous:
3021             vmCall(Void, m_out.operation(operationEnsureContiguous), m_callFrame, cell);
3022             break;
3023         case Array::ArrayStorage:
3024         case Array::SlowPutArrayStorage:
3025             vmCall(Void, m_out.operation(operationEnsureArrayStorage), m_callFrame, cell);
3026             break;
3027         default:
3028             DFG_CRASH(m_graph, m_node, "Bad array type");
3029             break;
3030         }
3031         
3032         speculate(BadIndexingType, jsValueValue(cell), 0, isUnexpectedArray(cell));
3033         m_out.jump(continuation);
3034         
3035         m_out.appendTo(continuation, lastNext);
3036     }
3037     
3038     void compilePutStructure()
3039     {
3040         m_ftlState.jitCode->common.notifyCompilingStructureTransition(m_graph.m_plan, codeBlock(), m_node);
3041         
3042         RegisteredStructure oldStructure = m_node->transition()->previous;
3043         RegisteredStructure newStructure = m_node->transition()->next;
3044         ASSERT_UNUSED(oldStructure, oldStructure->indexingType() == newStructure->indexingType());
3045         ASSERT(oldStructure->typeInfo().inlineTypeFlags() == newStructure->typeInfo().inlineTypeFlags());
3046         ASSERT(oldStructure->typeInfo().type() == newStructure->typeInfo().type());
3047
3048         LValue cell = lowCell(m_node->child1()); 
3049         m_out.store32(
3050             weakStructureID(newStructure),
3051             cell, m_heaps.JSCell_structureID);
3052     }
3053     
3054     void compileGetById(AccessType type)
3055     {
3056         ASSERT(type == AccessType::Get || type == AccessType::TryGet || type == AccessType::GetDirect);
3057         switch (m_node->child1().useKind()) {
3058         case CellUse: {
3059             setJSValue(getById(lowCell(m_node->child1()), type));
3060             return;
3061         }
3062             
3063         case UntypedUse: {
3064             // This is pretty weird, since we duplicate the slow path both here and in the
3065             // code generated by the IC. We should investigate making this less bad.
3066             // https://bugs.webkit.org/show_bug.cgi?id=127830
3067             LValue value = lowJSValue(m_node->child1());
3068             
3069             LBasicBlock cellCase = m_out.newBlock();
3070             LBasicBlock notCellCase = m_out.newBlock();
3071             LBasicBlock continuation = m_out.newBlock();
3072             
3073             m_out.branch(
3074                 isCell(value, provenType(m_node->child1())), unsure(cellCase), unsure(notCellCase));
3075             
3076             LBasicBlock lastNext = m_out.appendTo(cellCase, notCellCase);
3077             ValueFromBlock cellResult = m_out.anchor(getById(value, type));
3078             m_out.jump(continuation);
3079
3080             J_JITOperation_EJI getByIdFunction = appropriateGenericGetByIdFunction(type);
3081
3082             m_out.appendTo(notCellCase, continuation);
3083             ValueFromBlock notCellResult = m_out.anchor(vmCall(
3084                 Int64, m_out.operation(getByIdFunction),
3085                 m_callFrame, value,
3086                 m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()])));
3087             m_out.jump(continuation);
3088             
3089             m_out.appendTo(continuation, lastNext);
3090             setJSValue(m_out.phi(Int64, cellResult, notCellResult));
3091             return;
3092         }
3093             
3094         default:
3095             DFG_CRASH(m_graph, m_node, "Bad use kind");
3096             return;
3097         }
3098     }
3099
3100     void compileGetByIdWithThis()
3101     {
3102         if (m_node->child1().useKind() == CellUse && m_node->child2().useKind() == CellUse)
3103             setJSValue(getByIdWithThis(lowCell(m_node->child1()), lowCell(m_node->child2())));
3104         else {
3105             LValue base = lowJSValue(m_node->child1());
3106             LValue thisValue = lowJSValue(m_node->child2());
3107             
3108             LBasicBlock baseCellCase = m_out.newBlock();
3109             LBasicBlock notCellCase = m_out.newBlock();
3110             LBasicBlock thisValueCellCase = m_out.newBlock();
3111             LBasicBlock continuation = m_out.newBlock();
3112             
3113             m_out.branch(
3114                 isCell(base, provenType(m_node->child1())), unsure(baseCellCase), unsure(notCellCase));
3115             
3116             LBasicBlock lastNext = m_out.appendTo(baseCellCase, thisValueCellCase);
3117             
3118             m_out.branch(
3119                 isCell(thisValue, provenType(m_node->child2())), unsure(thisValueCellCase), unsure(notCellCase));
3120             
3121             m_out.appendTo(thisValueCellCase, notCellCase);
3122             ValueFromBlock cellResult = m_out.anchor(getByIdWithThis(base, thisValue));
3123             m_out.jump(continuation);
3124
3125             m_out.appendTo(notCellCase, continuation);
3126             ValueFromBlock notCellResult = m_out.anchor(vmCall(
3127                 Int64, m_out.operation(operationGetByIdWithThisGeneric),
3128                 m_callFrame, base, thisValue,
3129                 m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()])));
3130             m_out.jump(continuation);
3131             
3132             m_out.appendTo(continuation, lastNext);
3133             setJSValue(m_out.phi(Int64, cellResult, notCellResult));
3134         }
3135         
3136     }
3137
3138     void compileGetByValWithThis()
3139     {
3140         LValue base = lowJSValue(m_node->child1());
3141         LValue thisValue = lowJSValue(m_node->child2());
3142         LValue subscript = lowJSValue(m_node->child3());
3143
3144