Templatize CodePtr/Refs/FunctionPtrs with PtrTags.
[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 GetArgumentCountIncludingThis:
928             compileGetArgumentCountIncludingThis();
929             break;
930         case SetArgumentCountIncludingThis:
931             compileSetArgumentCountIncludingThis();
932             break;
933         case GetScope:
934             compileGetScope();
935             break;
936         case SkipScope:
937             compileSkipScope();
938             break;
939         case GetGlobalObject:
940             compileGetGlobalObject();
941             break;
942         case GetGlobalThis:
943             compileGetGlobalThis();
944             break;
945         case GetClosureVar:
946             compileGetClosureVar();
947             break;
948         case PutClosureVar:
949             compilePutClosureVar();
950             break;
951         case GetFromArguments:
952             compileGetFromArguments();
953             break;
954         case PutToArguments:
955             compilePutToArguments();
956             break;
957         case GetArgument:
958             compileGetArgument();
959             break;
960         case CompareEq:
961             compileCompareEq();
962             break;
963         case CompareStrictEq:
964             compileCompareStrictEq();
965             break;
966         case CompareLess:
967             compileCompareLess();
968             break;
969         case CompareLessEq:
970             compileCompareLessEq();
971             break;
972         case CompareGreater:
973             compileCompareGreater();
974             break;
975         case CompareGreaterEq:
976             compileCompareGreaterEq();
977             break;
978         case CompareBelow:
979             compileCompareBelow();
980             break;
981         case CompareBelowEq:
982             compileCompareBelowEq();
983             break;
984         case CompareEqPtr:
985             compileCompareEqPtr();
986             break;
987         case LogicalNot:
988             compileLogicalNot();
989             break;
990         case Call:
991         case TailCallInlinedCaller:
992         case Construct:
993             compileCallOrConstruct();
994             break;
995         case DirectCall:
996         case DirectTailCallInlinedCaller:
997         case DirectConstruct:
998         case DirectTailCall:
999             compileDirectCallOrConstruct();
1000             break;
1001         case TailCall:
1002             compileTailCall();
1003             break;
1004         case CallVarargs:
1005         case CallForwardVarargs:
1006         case TailCallVarargs:
1007         case TailCallVarargsInlinedCaller:
1008         case TailCallForwardVarargs:
1009         case TailCallForwardVarargsInlinedCaller:
1010         case ConstructVarargs:
1011         case ConstructForwardVarargs:
1012             compileCallOrConstructVarargs();
1013             break;
1014         case CallEval:
1015             compileCallEval();
1016             break;
1017         case LoadVarargs:
1018             compileLoadVarargs();
1019             break;
1020         case ForwardVarargs:
1021             compileForwardVarargs();
1022             break;
1023         case DFG::Jump:
1024             compileJump();
1025             break;
1026         case DFG::Branch:
1027             compileBranch();
1028             break;
1029         case DFG::Switch:
1030             compileSwitch();
1031             break;
1032         case DFG::EntrySwitch:
1033             compileEntrySwitch();
1034             break;
1035         case DFG::Return:
1036             compileReturn();
1037             break;
1038         case ForceOSRExit:
1039             compileForceOSRExit();
1040             break;
1041         case CPUIntrinsic:
1042 #if CPU(X86_64)
1043             compileCPUIntrinsic();
1044 #else
1045             RELEASE_ASSERT_NOT_REACHED();
1046 #endif
1047             break;
1048         case Throw:
1049             compileThrow();
1050             break;
1051         case ThrowStaticError:
1052             compileThrowStaticError();
1053             break;
1054         case InvalidationPoint:
1055             compileInvalidationPoint();
1056             break;
1057         case IsEmpty:
1058             compileIsEmpty();
1059             break;
1060         case IsUndefined:
1061             compileIsUndefined();
1062             break;
1063         case IsBoolean:
1064             compileIsBoolean();
1065             break;
1066         case IsNumber:
1067             compileIsNumber();
1068             break;
1069         case NumberIsInteger:
1070             compileNumberIsInteger();
1071             break;
1072         case IsCellWithType:
1073             compileIsCellWithType();
1074             break;
1075         case MapHash:
1076             compileMapHash();
1077             break;
1078         case NormalizeMapKey:
1079             compileNormalizeMapKey();
1080             break;
1081         case GetMapBucket:
1082             compileGetMapBucket();
1083             break;
1084         case GetMapBucketHead:
1085             compileGetMapBucketHead();
1086             break;
1087         case GetMapBucketNext:
1088             compileGetMapBucketNext();
1089             break;
1090         case LoadKeyFromMapBucket:
1091             compileLoadKeyFromMapBucket();
1092             break;
1093         case LoadValueFromMapBucket:
1094             compileLoadValueFromMapBucket();
1095             break;
1096         case ExtractValueFromWeakMapGet:
1097             compileExtractValueFromWeakMapGet();
1098             break;
1099         case SetAdd:
1100             compileSetAdd();
1101             break;
1102         case MapSet:
1103             compileMapSet();
1104             break;
1105         case WeakMapGet:
1106             compileWeakMapGet();
1107             break;
1108         case WeakSetAdd:
1109             compileWeakSetAdd();
1110             break;
1111         case WeakMapSet:
1112             compileWeakMapSet();
1113             break;
1114         case IsObject:
1115             compileIsObject();
1116             break;
1117         case IsObjectOrNull:
1118             compileIsObjectOrNull();
1119             break;
1120         case IsFunction:
1121             compileIsFunction();
1122             break;
1123         case IsTypedArrayView:
1124             compileIsTypedArrayView();
1125             break;
1126         case ParseInt:
1127             compileParseInt();
1128             break;
1129         case TypeOf:
1130             compileTypeOf();
1131             break;
1132         case CheckTypeInfoFlags:
1133             compileCheckTypeInfoFlags();
1134             break;
1135         case OverridesHasInstance:
1136             compileOverridesHasInstance();
1137             break;
1138         case InstanceOf:
1139             compileInstanceOf();
1140             break;
1141         case InstanceOfCustom:
1142             compileInstanceOfCustom();
1143             break;
1144         case CountExecution:
1145             compileCountExecution();
1146             break;
1147         case SuperSamplerBegin:
1148             compileSuperSamplerBegin();
1149             break;
1150         case SuperSamplerEnd:
1151             compileSuperSamplerEnd();
1152             break;
1153         case StoreBarrier:
1154         case FencedStoreBarrier:
1155             compileStoreBarrier();
1156             break;
1157         case HasIndexedProperty:
1158             compileHasIndexedProperty();
1159             break;
1160         case HasGenericProperty:
1161             compileHasGenericProperty();
1162             break;
1163         case HasStructureProperty:
1164             compileHasStructureProperty();
1165             break;
1166         case GetDirectPname:
1167             compileGetDirectPname();
1168             break;
1169         case GetEnumerableLength:
1170             compileGetEnumerableLength();
1171             break;
1172         case GetPropertyEnumerator:
1173             compileGetPropertyEnumerator();
1174             break;
1175         case GetEnumeratorStructurePname:
1176             compileGetEnumeratorStructurePname();
1177             break;
1178         case GetEnumeratorGenericPname:
1179             compileGetEnumeratorGenericPname();
1180             break;
1181         case ToIndexString:
1182             compileToIndexString();
1183             break;
1184         case CheckStructureImmediate:
1185             compileCheckStructureImmediate();
1186             break;
1187         case MaterializeNewObject:
1188             compileMaterializeNewObject();
1189             break;
1190         case MaterializeCreateActivation:
1191             compileMaterializeCreateActivation();
1192             break;
1193         case CheckTraps:
1194             if (Options::usePollingTraps())
1195                 compileCheckTraps();
1196             break;
1197         case CreateRest:
1198             compileCreateRest();
1199             break;
1200         case GetRestLength:
1201             compileGetRestLength();
1202             break;
1203         case RegExpExec:
1204             compileRegExpExec();
1205             break;
1206         case RegExpExecNonGlobalOrSticky:
1207             compileRegExpExecNonGlobalOrSticky();
1208             break;
1209         case RegExpTest:
1210             compileRegExpTest();
1211             break;
1212         case RegExpMatchFast:
1213             compileRegExpMatchFast();
1214             break;
1215         case RegExpMatchFastGlobal:
1216             compileRegExpMatchFastGlobal();
1217             break;
1218         case NewRegexp:
1219             compileNewRegexp();
1220             break;
1221         case SetFunctionName:
1222             compileSetFunctionName();
1223             break;
1224         case StringReplace:
1225         case StringReplaceRegExp:
1226             compileStringReplace();
1227             break;
1228         case GetRegExpObjectLastIndex:
1229             compileGetRegExpObjectLastIndex();
1230             break;
1231         case SetRegExpObjectLastIndex:
1232             compileSetRegExpObjectLastIndex();
1233             break;
1234         case LogShadowChickenPrologue:
1235             compileLogShadowChickenPrologue();
1236             break;
1237         case LogShadowChickenTail:
1238             compileLogShadowChickenTail();
1239             break;
1240         case RecordRegExpCachedResult:
1241             compileRecordRegExpCachedResult();
1242             break;
1243         case ResolveScopeForHoistingFuncDeclInEval:
1244             compileResolveScopeForHoistingFuncDeclInEval();
1245             break;
1246         case ResolveScope:
1247             compileResolveScope();
1248             break;
1249         case GetDynamicVar:
1250             compileGetDynamicVar();
1251             break;
1252         case PutDynamicVar:
1253             compilePutDynamicVar();
1254             break;
1255         case Unreachable:
1256             compileUnreachable();
1257             break;
1258         case StringSlice:
1259             compileStringSlice();
1260             break;
1261         case ToLowerCase:
1262             compileToLowerCase();
1263             break;
1264         case NumberToStringWithRadix:
1265             compileNumberToStringWithRadix();
1266             break;
1267         case NumberToStringWithValidRadixConstant:
1268             compileNumberToStringWithValidRadixConstant();
1269             break;
1270         case CheckSubClass:
1271             compileCheckSubClass();
1272             break;
1273         case CallDOM:
1274             compileCallDOM();
1275             break;
1276         case CallDOMGetter:
1277             compileCallDOMGetter();
1278             break;
1279
1280         case PhantomLocal:
1281         case LoopHint:
1282         case MovHint:
1283         case ZombieHint:
1284         case ExitOK:
1285         case PhantomNewObject:
1286         case PhantomNewFunction:
1287         case PhantomNewGeneratorFunction:
1288         case PhantomNewAsyncGeneratorFunction:
1289         case PhantomNewAsyncFunction:
1290         case PhantomCreateActivation:
1291         case PhantomDirectArguments:
1292         case PhantomCreateRest:
1293         case PhantomSpread:
1294         case PhantomNewArrayWithSpread:
1295         case PhantomNewArrayBuffer:
1296         case PhantomClonedArguments:
1297         case PhantomNewRegexp:
1298         case PutHint:
1299         case BottomValue:
1300         case KillStack:
1301         case InitializeEntrypointArguments:
1302             break;
1303         default:
1304             DFG_CRASH(m_graph, m_node, "Unrecognized node in FTL backend");
1305             break;
1306         }
1307         
1308         if (m_node->isTerminal())
1309             return false;
1310         
1311         if (!m_state.isValid()) {
1312             safelyInvalidateAfterTermination();
1313             return false;
1314         }
1315
1316         m_availabilityCalculator.executeNode(m_node);
1317         m_interpreter.executeEffects(nodeIndex);
1318         
1319         return true;
1320     }
1321
1322     void compileUpsilon()
1323     {
1324         LValue upsilonValue = nullptr;
1325         switch (m_node->child1().useKind()) {
1326         case DoubleRepUse:
1327             upsilonValue = lowDouble(m_node->child1());
1328             break;
1329         case Int32Use:
1330         case KnownInt32Use:
1331             upsilonValue = lowInt32(m_node->child1());
1332             break;
1333         case Int52RepUse:
1334             upsilonValue = lowInt52(m_node->child1());
1335             break;
1336         case BooleanUse:
1337         case KnownBooleanUse:
1338             upsilonValue = lowBoolean(m_node->child1());
1339             break;
1340         case CellUse:
1341         case KnownCellUse:
1342             upsilonValue = lowCell(m_node->child1());
1343             break;
1344         case UntypedUse:
1345             upsilonValue = lowJSValue(m_node->child1());
1346             break;
1347         default:
1348             DFG_CRASH(m_graph, m_node, "Bad use kind");
1349             break;
1350         }
1351         ValueFromBlock upsilon = m_out.anchor(upsilonValue);
1352         LValue phiNode = m_phis.get(m_node->phi());
1353         m_out.addIncomingToPhi(phiNode, upsilon);
1354     }
1355     
1356     void compilePhi()
1357     {
1358         LValue phi = m_phis.get(m_node);
1359         m_out.m_block->append(phi);
1360
1361         switch (m_node->flags() & NodeResultMask) {
1362         case NodeResultDouble:
1363             setDouble(phi);
1364             break;
1365         case NodeResultInt32:
1366             setInt32(phi);
1367             break;
1368         case NodeResultInt52:
1369             setInt52(phi);
1370             break;
1371         case NodeResultBoolean:
1372             setBoolean(phi);
1373             break;
1374         case NodeResultJS:
1375             setJSValue(phi);
1376             break;
1377         default:
1378             DFG_CRASH(m_graph, m_node, "Bad use kind");
1379             break;
1380         }
1381     }
1382     
1383     void compileDoubleConstant()
1384     {
1385         setDouble(m_out.constDouble(m_node->asNumber()));
1386     }
1387     
1388     void compileInt52Constant()
1389     {
1390         int64_t value = m_node->asAnyInt();
1391         
1392         setInt52(m_out.constInt64(value << JSValue::int52ShiftAmount));
1393         setStrictInt52(m_out.constInt64(value));
1394     }
1395
1396     void compileLazyJSConstant()
1397     {
1398         PatchpointValue* patchpoint = m_out.patchpoint(Int64);
1399         LazyJSValue value = m_node->lazyJSValue();
1400         patchpoint->setGenerator(
1401             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
1402                 value.emit(jit, JSValueRegs(params[0].gpr()));
1403             });
1404         patchpoint->effects = Effects::none();
1405         setJSValue(patchpoint);
1406     }
1407
1408     void compileDoubleRep()
1409     {
1410         switch (m_node->child1().useKind()) {
1411         case RealNumberUse: {
1412             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
1413             
1414             LValue doubleValue = unboxDouble(value);
1415             
1416             LBasicBlock intCase = m_out.newBlock();
1417             LBasicBlock continuation = m_out.newBlock();
1418             
1419             ValueFromBlock fastResult = m_out.anchor(doubleValue);
1420             m_out.branch(
1421                 m_out.doubleEqual(doubleValue, doubleValue),
1422                 usually(continuation), rarely(intCase));
1423             
1424             LBasicBlock lastNext = m_out.appendTo(intCase, continuation);
1425
1426             FTL_TYPE_CHECK(
1427                 jsValueValue(value), m_node->child1(), SpecBytecodeRealNumber,
1428                 isNotInt32(value, provenType(m_node->child1()) & ~SpecDoubleReal));
1429             ValueFromBlock slowResult = m_out.anchor(m_out.intToDouble(unboxInt32(value)));
1430             m_out.jump(continuation);
1431             
1432             m_out.appendTo(continuation, lastNext);
1433             
1434             setDouble(m_out.phi(Double, fastResult, slowResult));
1435             return;
1436         }
1437             
1438         case NotCellUse:
1439         case NumberUse: {
1440             bool shouldConvertNonNumber = m_node->child1().useKind() == NotCellUse;
1441             
1442             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
1443
1444             LBasicBlock intCase = m_out.newBlock();
1445             LBasicBlock doubleTesting = m_out.newBlock();
1446             LBasicBlock doubleCase = m_out.newBlock();
1447             LBasicBlock nonDoubleCase = m_out.newBlock();
1448             LBasicBlock continuation = m_out.newBlock();
1449             
1450             m_out.branch(
1451                 isNotInt32(value, provenType(m_node->child1())),
1452                 unsure(doubleTesting), unsure(intCase));
1453             
1454             LBasicBlock lastNext = m_out.appendTo(intCase, doubleTesting);
1455             
1456             ValueFromBlock intToDouble = m_out.anchor(
1457                 m_out.intToDouble(unboxInt32(value)));
1458             m_out.jump(continuation);
1459             
1460             m_out.appendTo(doubleTesting, doubleCase);
1461             LValue valueIsNumber = isNumber(value, provenType(m_node->child1()));
1462             m_out.branch(valueIsNumber, usually(doubleCase), rarely(nonDoubleCase));
1463
1464             m_out.appendTo(doubleCase, nonDoubleCase);
1465             ValueFromBlock unboxedDouble = m_out.anchor(unboxDouble(value));
1466             m_out.jump(continuation);
1467
1468             if (shouldConvertNonNumber) {
1469                 LBasicBlock undefinedCase = m_out.newBlock();
1470                 LBasicBlock testNullCase = m_out.newBlock();
1471                 LBasicBlock nullCase = m_out.newBlock();
1472                 LBasicBlock testBooleanTrueCase = m_out.newBlock();
1473                 LBasicBlock convertBooleanTrueCase = m_out.newBlock();
1474                 LBasicBlock convertBooleanFalseCase = m_out.newBlock();
1475
1476                 m_out.appendTo(nonDoubleCase, undefinedCase);
1477                 LValue valueIsUndefined = m_out.equal(value, m_out.constInt64(ValueUndefined));
1478                 m_out.branch(valueIsUndefined, unsure(undefinedCase), unsure(testNullCase));
1479
1480                 m_out.appendTo(undefinedCase, testNullCase);
1481                 ValueFromBlock convertedUndefined = m_out.anchor(m_out.constDouble(PNaN));
1482                 m_out.jump(continuation);
1483
1484                 m_out.appendTo(testNullCase, nullCase);
1485                 LValue valueIsNull = m_out.equal(value, m_out.constInt64(ValueNull));
1486                 m_out.branch(valueIsNull, unsure(nullCase), unsure(testBooleanTrueCase));
1487
1488                 m_out.appendTo(nullCase, testBooleanTrueCase);
1489                 ValueFromBlock convertedNull = m_out.anchor(m_out.constDouble(0));
1490                 m_out.jump(continuation);
1491
1492                 m_out.appendTo(testBooleanTrueCase, convertBooleanTrueCase);
1493                 LValue valueIsBooleanTrue = m_out.equal(value, m_out.constInt64(ValueTrue));
1494                 m_out.branch(valueIsBooleanTrue, unsure(convertBooleanTrueCase), unsure(convertBooleanFalseCase));
1495
1496                 m_out.appendTo(convertBooleanTrueCase, convertBooleanFalseCase);
1497                 ValueFromBlock convertedTrue = m_out.anchor(m_out.constDouble(1));
1498                 m_out.jump(continuation);
1499
1500                 m_out.appendTo(convertBooleanFalseCase, continuation);
1501
1502                 LValue valueIsNotBooleanFalse = m_out.notEqual(value, m_out.constInt64(ValueFalse));
1503                 FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), ~SpecCellCheck, valueIsNotBooleanFalse);
1504                 ValueFromBlock convertedFalse = m_out.anchor(m_out.constDouble(0));
1505                 m_out.jump(continuation);
1506
1507                 m_out.appendTo(continuation, lastNext);
1508                 setDouble(m_out.phi(Double, intToDouble, unboxedDouble, convertedUndefined, convertedNull, convertedTrue, convertedFalse));
1509                 return;
1510             }
1511             m_out.appendTo(nonDoubleCase, continuation);
1512             FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), SpecBytecodeNumber, m_out.booleanTrue);
1513             m_out.unreachable();
1514
1515             m_out.appendTo(continuation, lastNext);
1516
1517             setDouble(m_out.phi(Double, intToDouble, unboxedDouble));
1518             return;
1519         }
1520             
1521         case Int52RepUse: {
1522             setDouble(strictInt52ToDouble(lowStrictInt52(m_node->child1())));
1523             return;
1524         }
1525             
1526         default:
1527             DFG_CRASH(m_graph, m_node, "Bad use kind");
1528         }
1529     }
1530
1531     void compileDoubleAsInt32()
1532     {
1533         LValue integerValue = convertDoubleToInt32(lowDouble(m_node->child1()), shouldCheckNegativeZero(m_node->arithMode()));
1534         setInt32(integerValue);
1535     }
1536
1537     void compileValueRep()
1538     {
1539         switch (m_node->child1().useKind()) {
1540         case DoubleRepUse: {
1541             LValue value = lowDouble(m_node->child1());
1542             
1543             if (m_interpreter.needsTypeCheck(m_node->child1(), ~SpecDoubleImpureNaN)) {
1544                 value = m_out.select(
1545                     m_out.doubleEqual(value, value), value, m_out.constDouble(PNaN));
1546             }
1547             
1548             setJSValue(boxDouble(value));
1549             return;
1550         }
1551             
1552         case Int52RepUse: {
1553             setJSValue(strictInt52ToJSValue(lowStrictInt52(m_node->child1())));
1554             return;
1555         }
1556             
1557         default:
1558             DFG_CRASH(m_graph, m_node, "Bad use kind");
1559         }
1560     }
1561     
1562     void compileInt52Rep()
1563     {
1564         switch (m_node->child1().useKind()) {
1565         case Int32Use:
1566             setStrictInt52(m_out.signExt32To64(lowInt32(m_node->child1())));
1567             return;
1568             
1569         case AnyIntUse:
1570             setStrictInt52(
1571                 jsValueToStrictInt52(
1572                     m_node->child1(), lowJSValue(m_node->child1(), ManualOperandSpeculation)));
1573             return;
1574             
1575         case DoubleRepAnyIntUse:
1576             setStrictInt52(
1577                 doubleToStrictInt52(
1578                     m_node->child1(), lowDouble(m_node->child1())));
1579             return;
1580             
1581         default:
1582             RELEASE_ASSERT_NOT_REACHED();
1583         }
1584     }
1585     
1586     void compileValueToInt32()
1587     {
1588         switch (m_node->child1().useKind()) {
1589         case Int52RepUse:
1590             setInt32(m_out.castToInt32(lowStrictInt52(m_node->child1())));
1591             break;
1592             
1593         case DoubleRepUse:
1594             setInt32(doubleToInt32(lowDouble(m_node->child1())));
1595             break;
1596             
1597         case NumberUse:
1598         case NotCellUse: {
1599             LoweredNodeValue value = m_int32Values.get(m_node->child1().node());
1600             if (isValid(value)) {
1601                 setInt32(value.value());
1602                 break;
1603             }
1604             
1605             value = m_jsValueValues.get(m_node->child1().node());
1606             if (isValid(value)) {
1607                 setInt32(numberOrNotCellToInt32(m_node->child1(), value.value()));
1608                 break;
1609             }
1610             
1611             // We'll basically just get here for constants. But it's good to have this
1612             // catch-all since we often add new representations into the mix.
1613             setInt32(
1614                 numberOrNotCellToInt32(
1615                     m_node->child1(),
1616                     lowJSValue(m_node->child1(), ManualOperandSpeculation)));
1617             break;
1618         }
1619             
1620         default:
1621             DFG_CRASH(m_graph, m_node, "Bad use kind");
1622             break;
1623         }
1624     }
1625     
1626     void compileBooleanToNumber()
1627     {
1628         switch (m_node->child1().useKind()) {
1629         case BooleanUse: {
1630             setInt32(m_out.zeroExt(lowBoolean(m_node->child1()), Int32));
1631             return;
1632         }
1633             
1634         case UntypedUse: {
1635             LValue value = lowJSValue(m_node->child1());
1636             
1637             if (!m_interpreter.needsTypeCheck(m_node->child1(), SpecBoolInt32 | SpecBoolean)) {
1638                 setInt32(m_out.bitAnd(m_out.castToInt32(value), m_out.int32One));
1639                 return;
1640             }
1641             
1642             LBasicBlock booleanCase = m_out.newBlock();
1643             LBasicBlock continuation = m_out.newBlock();
1644             
1645             ValueFromBlock notBooleanResult = m_out.anchor(value);
1646             m_out.branch(
1647                 isBoolean(value, provenType(m_node->child1())),
1648                 unsure(booleanCase), unsure(continuation));
1649             
1650             LBasicBlock lastNext = m_out.appendTo(booleanCase, continuation);
1651             ValueFromBlock booleanResult = m_out.anchor(m_out.bitOr(
1652                 m_out.zeroExt(unboxBoolean(value), Int64), m_tagTypeNumber));
1653             m_out.jump(continuation);
1654             
1655             m_out.appendTo(continuation, lastNext);
1656             setJSValue(m_out.phi(Int64, booleanResult, notBooleanResult));
1657             return;
1658         }
1659             
1660         default:
1661             RELEASE_ASSERT_NOT_REACHED();
1662             return;
1663         }
1664     }
1665
1666     void compileExtractOSREntryLocal()
1667     {
1668         EncodedJSValue* buffer = static_cast<EncodedJSValue*>(
1669             m_ftlState.jitCode->ftlForOSREntry()->entryBuffer()->dataBuffer());
1670         setJSValue(m_out.load64(m_out.absolute(buffer + m_node->unlinkedLocal().toLocal())));
1671     }
1672
1673     void compileExtractCatchLocal()
1674     {
1675         EncodedJSValue* buffer = static_cast<EncodedJSValue*>(m_ftlState.jitCode->common.catchOSREntryBuffer->dataBuffer());
1676         setJSValue(m_out.load64(m_out.absolute(buffer + m_node->catchOSREntryIndex())));
1677     }
1678     
1679     void compileGetStack()
1680     {
1681         StackAccessData* data = m_node->stackAccessData();
1682         AbstractValue& value = m_state.variables().operand(data->local);
1683         
1684         DFG_ASSERT(m_graph, m_node, isConcrete(data->format), data->format);
1685         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.
1686         
1687         if (isInt32Speculation(value.m_type))
1688             setInt32(m_out.load32(payloadFor(data->machineLocal)));
1689         else
1690             setJSValue(m_out.load64(addressFor(data->machineLocal)));
1691     }
1692     
1693     void compilePutStack()
1694     {
1695         StackAccessData* data = m_node->stackAccessData();
1696         switch (data->format) {
1697         case FlushedJSValue: {
1698             LValue value = lowJSValue(m_node->child1());
1699             m_out.store64(value, addressFor(data->machineLocal));
1700             break;
1701         }
1702             
1703         case FlushedDouble: {
1704             LValue value = lowDouble(m_node->child1());
1705             m_out.storeDouble(value, addressFor(data->machineLocal));
1706             break;
1707         }
1708             
1709         case FlushedInt32: {
1710             LValue value = lowInt32(m_node->child1());
1711             m_out.store32(value, payloadFor(data->machineLocal));
1712             break;
1713         }
1714             
1715         case FlushedInt52: {
1716             LValue value = lowInt52(m_node->child1());
1717             m_out.store64(value, addressFor(data->machineLocal));
1718             break;
1719         }
1720             
1721         case FlushedCell: {
1722             LValue value = lowCell(m_node->child1());
1723             m_out.store64(value, addressFor(data->machineLocal));
1724             break;
1725         }
1726             
1727         case FlushedBoolean: {
1728             speculateBoolean(m_node->child1());
1729             m_out.store64(
1730                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
1731                 addressFor(data->machineLocal));
1732             break;
1733         }
1734             
1735         default:
1736             DFG_CRASH(m_graph, m_node, "Bad flush format");
1737             break;
1738         }
1739     }
1740     
1741     void compileNoOp()
1742     {
1743         DFG_NODE_DO_TO_CHILDREN(m_graph, m_node, speculate);
1744     }
1745
1746     void compileToObjectOrCallObjectConstructor()
1747     {
1748         LValue value = lowJSValue(m_node->child1());
1749
1750         LBasicBlock isCellCase = m_out.newBlock();
1751         LBasicBlock slowCase = m_out.newBlock();
1752         LBasicBlock continuation = m_out.newBlock();
1753
1754         m_out.branch(isCell(value, provenType(m_node->child1())), usually(isCellCase), rarely(slowCase));
1755
1756         LBasicBlock lastNext = m_out.appendTo(isCellCase, slowCase);
1757         ValueFromBlock fastResult = m_out.anchor(value);
1758         m_out.branch(isObject(value), usually(continuation), rarely(slowCase));
1759
1760         m_out.appendTo(slowCase, continuation);
1761
1762         ValueFromBlock slowResult;
1763         if (m_node->op() == ToObject) {
1764             auto* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
1765             slowResult = m_out.anchor(vmCall(Int64, m_out.operation(operationToObject), m_callFrame, weakPointer(globalObject), value, m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()])));
1766         } else
1767             slowResult = m_out.anchor(vmCall(Int64, m_out.operation(operationCallObjectConstructor), m_callFrame, frozenPointer(m_node->cellOperand()), value));
1768         m_out.jump(continuation);
1769
1770         m_out.appendTo(continuation, lastNext);
1771         setJSValue(m_out.phi(Int64, fastResult, slowResult));
1772     }
1773     
1774     void compileToThis()
1775     {
1776         LValue value = lowJSValue(m_node->child1());
1777         
1778         LBasicBlock isCellCase = m_out.newBlock();
1779         LBasicBlock slowCase = m_out.newBlock();
1780         LBasicBlock continuation = m_out.newBlock();
1781         
1782         m_out.branch(
1783             isCell(value, provenType(m_node->child1())), usually(isCellCase), rarely(slowCase));
1784         
1785         LBasicBlock lastNext = m_out.appendTo(isCellCase, slowCase);
1786         ValueFromBlock fastResult = m_out.anchor(value);
1787         m_out.branch(
1788             m_out.testIsZero32(
1789                 m_out.load8ZeroExt32(value, m_heaps.JSCell_typeInfoFlags),
1790                 m_out.constInt32(OverridesToThis)),
1791             usually(continuation), rarely(slowCase));
1792         
1793         m_out.appendTo(slowCase, continuation);
1794         J_JITOperation_EJ function;
1795         if (m_graph.isStrictModeFor(m_node->origin.semantic))
1796             function = operationToThisStrict;
1797         else
1798             function = operationToThis;
1799         ValueFromBlock slowResult = m_out.anchor(
1800             vmCall(Int64, m_out.operation(function), m_callFrame, value));
1801         m_out.jump(continuation);
1802         
1803         m_out.appendTo(continuation, lastNext);
1804         setJSValue(m_out.phi(Int64, fastResult, slowResult));
1805     }
1806
1807     void compileValueAdd()
1808     {
1809         CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic);
1810         ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(m_node->origin.semantic.bytecodeIndex);
1811         Instruction* instruction = &baselineCodeBlock->instructions()[m_node->origin.semantic.bytecodeIndex];
1812         auto repatchingFunction = operationValueAddOptimize;
1813         auto nonRepatchingFunction = operationValueAdd;
1814         compileBinaryMathIC<JITAddGenerator>(arithProfile, instruction, repatchingFunction, nonRepatchingFunction);
1815     }
1816
1817     template <typename Generator, typename Func1, typename Func2,
1818         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>>
1819     void compileUnaryMathIC(ArithProfile* arithProfile, Instruction* instruction, Func1 repatchingFunction, Func2 nonRepatchingFunction)
1820     {
1821         Node* node = m_node;
1822
1823         LValue operand = lowJSValue(node->child1());
1824
1825         PatchpointValue* patchpoint = m_out.patchpoint(Int64);
1826         patchpoint->appendSomeRegister(operand);
1827         patchpoint->append(m_tagMask, ValueRep::lateReg(GPRInfo::tagMaskRegister));
1828         patchpoint->append(m_tagTypeNumber, ValueRep::lateReg(GPRInfo::tagTypeNumberRegister));
1829         RefPtr<PatchpointExceptionHandle> exceptionHandle = preparePatchpointForExceptions(patchpoint);
1830         patchpoint->numGPScratchRegisters = 1;
1831         patchpoint->clobber(RegisterSet::macroScratchRegisters());
1832         State* state = &m_ftlState;
1833         patchpoint->setGenerator(
1834             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
1835                 AllowMacroScratchRegisterUsage allowScratch(jit);
1836
1837                 Box<CCallHelpers::JumpList> exceptions =
1838                     exceptionHandle->scheduleExitCreation(params)->jumps(jit);
1839
1840 #if ENABLE(MATH_IC_STATS)
1841                 auto inlineStart = jit.label();
1842 #endif
1843
1844                 Box<MathICGenerationState> mathICGenerationState = Box<MathICGenerationState>::create();
1845                 JITUnaryMathIC<Generator>* mathIC = jit.codeBlock()->addMathIC<Generator>(arithProfile, instruction);
1846                 mathIC->m_generator = Generator(JSValueRegs(params[0].gpr()), JSValueRegs(params[1].gpr()), params.gpScratch(0));
1847
1848                 bool shouldEmitProfiling = false;
1849                 bool generatedInline = mathIC->generateInline(jit, *mathICGenerationState, shouldEmitProfiling);
1850
1851                 if (generatedInline) {
1852                     ASSERT(!mathICGenerationState->slowPathJumps.empty());
1853                     auto done = jit.label();
1854                     params.addLatePath([=] (CCallHelpers& jit) {
1855                         AllowMacroScratchRegisterUsage allowScratch(jit);
1856                         mathICGenerationState->slowPathJumps.link(&jit);
1857                         mathICGenerationState->slowPathStart = jit.label();
1858 #if ENABLE(MATH_IC_STATS)
1859                         auto slowPathStart = jit.label();
1860 #endif
1861
1862                         if (mathICGenerationState->shouldSlowPathRepatch) {
1863                             SlowPathCall call = callOperation(*state, params.unavailableRegisters(), jit, node->origin.semantic, exceptions.get(),
1864                                 repatchingFunction, params[0].gpr(), params[1].gpr(), CCallHelpers::TrustedImmPtr(mathIC));
1865                             mathICGenerationState->slowPathCall = call.call();
1866                         } else {
1867                             SlowPathCall call = callOperation(*state, params.unavailableRegisters(), jit, node->origin.semantic,
1868                                 exceptions.get(), nonRepatchingFunction, params[0].gpr(), params[1].gpr());
1869                             mathICGenerationState->slowPathCall = call.call();
1870                         }
1871                         jit.jump().linkTo(done, &jit);
1872
1873                         jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1874                             mathIC->finalizeInlineCode(*mathICGenerationState, linkBuffer);
1875                         });
1876
1877 #if ENABLE(MATH_IC_STATS)
1878                         auto slowPathEnd = jit.label();
1879                         jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1880                             size_t size = linkBuffer.locationOf(slowPathEnd).executableAddress<char*>() - linkBuffer.locationOf(slowPathStart).executableAddress<char*>();
1881                             mathIC->m_generatedCodeSize += size;
1882                         });
1883 #endif
1884                     });
1885                 } else {
1886                     callOperation(
1887                         *state, params.unavailableRegisters(), jit, node->origin.semantic, exceptions.get(),
1888                         nonRepatchingFunction, params[0].gpr(), params[1].gpr());
1889                 }
1890
1891 #if ENABLE(MATH_IC_STATS)
1892                 auto inlineEnd = jit.label();
1893                 jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1894                     size_t size = linkBuffer.locationOf(inlineEnd).executableAddress<char*>() - linkBuffer.locationOf(inlineStart).executableAddress<char*>();
1895                     mathIC->m_generatedCodeSize += size;
1896                 });
1897 #endif
1898             });
1899
1900         setJSValue(patchpoint);
1901     }
1902
1903     template <typename Generator, typename Func1, typename Func2,
1904         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>>
1905     void compileBinaryMathIC(ArithProfile* arithProfile, Instruction* instruction, Func1 repatchingFunction, Func2 nonRepatchingFunction)
1906     {
1907         Node* node = m_node;
1908         
1909         LValue left = lowJSValue(node->child1());
1910         LValue right = lowJSValue(node->child2());
1911
1912         SnippetOperand leftOperand(m_state.forNode(node->child1()).resultType());
1913         SnippetOperand rightOperand(m_state.forNode(node->child2()).resultType());
1914             
1915         PatchpointValue* patchpoint = m_out.patchpoint(Int64);
1916         patchpoint->appendSomeRegister(left);
1917         patchpoint->appendSomeRegister(right);
1918         patchpoint->append(m_tagMask, ValueRep::lateReg(GPRInfo::tagMaskRegister));
1919         patchpoint->append(m_tagTypeNumber, ValueRep::lateReg(GPRInfo::tagTypeNumberRegister));
1920         RefPtr<PatchpointExceptionHandle> exceptionHandle =
1921             preparePatchpointForExceptions(patchpoint);
1922         patchpoint->numGPScratchRegisters = 1;
1923         patchpoint->numFPScratchRegisters = 2;
1924         patchpoint->clobber(RegisterSet::macroScratchRegisters());
1925         State* state = &m_ftlState;
1926         patchpoint->setGenerator(
1927             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
1928                 AllowMacroScratchRegisterUsage allowScratch(jit);
1929
1930
1931                 Box<CCallHelpers::JumpList> exceptions =
1932                     exceptionHandle->scheduleExitCreation(params)->jumps(jit);
1933
1934 #if ENABLE(MATH_IC_STATS)
1935                 auto inlineStart = jit.label();
1936 #endif
1937
1938                 Box<MathICGenerationState> mathICGenerationState = Box<MathICGenerationState>::create();
1939                 JITBinaryMathIC<Generator>* mathIC = jit.codeBlock()->addMathIC<Generator>(arithProfile, instruction);
1940                 mathIC->m_generator = Generator(leftOperand, rightOperand, JSValueRegs(params[0].gpr()),
1941                     JSValueRegs(params[1].gpr()), JSValueRegs(params[2].gpr()), params.fpScratch(0),
1942                     params.fpScratch(1), params.gpScratch(0), InvalidFPRReg);
1943
1944                 bool shouldEmitProfiling = false;
1945                 bool generatedInline = mathIC->generateInline(jit, *mathICGenerationState, shouldEmitProfiling);
1946
1947                 if (generatedInline) {
1948                     ASSERT(!mathICGenerationState->slowPathJumps.empty());
1949                     auto done = jit.label();
1950                     params.addLatePath([=] (CCallHelpers& jit) {
1951                         AllowMacroScratchRegisterUsage allowScratch(jit);
1952                         mathICGenerationState->slowPathJumps.link(&jit);
1953                         mathICGenerationState->slowPathStart = jit.label();
1954 #if ENABLE(MATH_IC_STATS)
1955                         auto slowPathStart = jit.label();
1956 #endif
1957
1958                         if (mathICGenerationState->shouldSlowPathRepatch) {
1959                             SlowPathCall call = callOperation(*state, params.unavailableRegisters(), jit, node->origin.semantic, exceptions.get(),
1960                                 repatchingFunction, params[0].gpr(), params[1].gpr(), params[2].gpr(), CCallHelpers::TrustedImmPtr(mathIC));
1961                             mathICGenerationState->slowPathCall = call.call();
1962                         } else {
1963                             SlowPathCall call = callOperation(*state, params.unavailableRegisters(), jit, node->origin.semantic,
1964                                 exceptions.get(), nonRepatchingFunction, params[0].gpr(), params[1].gpr(), params[2].gpr());
1965                             mathICGenerationState->slowPathCall = call.call();
1966                         }
1967                         jit.jump().linkTo(done, &jit);
1968
1969                         jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1970                             mathIC->finalizeInlineCode(*mathICGenerationState, linkBuffer);
1971                         });
1972
1973 #if ENABLE(MATH_IC_STATS)
1974                         auto slowPathEnd = jit.label();
1975                         jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1976                             size_t size = linkBuffer.locationOf(slowPathEnd).executableAddress<char*>() - linkBuffer.locationOf(slowPathStart).executableAddress<char*>();
1977                             mathIC->m_generatedCodeSize += size;
1978                         });
1979 #endif
1980                     });
1981                 } else {
1982                     callOperation(
1983                         *state, params.unavailableRegisters(), jit, node->origin.semantic, exceptions.get(),
1984                         nonRepatchingFunction, params[0].gpr(), params[1].gpr(), params[2].gpr());
1985                 }
1986
1987 #if ENABLE(MATH_IC_STATS)
1988                 auto inlineEnd = jit.label();
1989                 jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1990                     size_t size = linkBuffer.locationOf(inlineEnd).executableAddress<char*>() - linkBuffer.locationOf(inlineStart).executableAddress<char*>();
1991                     mathIC->m_generatedCodeSize += size;
1992                 });
1993 #endif
1994             });
1995
1996         setJSValue(patchpoint);
1997     }
1998     
1999     void compileStrCat()
2000     {
2001         LValue result;
2002         if (m_node->child3()) {
2003             result = vmCall(
2004                 Int64, m_out.operation(operationStrCat3), m_callFrame,
2005                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
2006                 lowJSValue(m_node->child2(), ManualOperandSpeculation),
2007                 lowJSValue(m_node->child3(), ManualOperandSpeculation));
2008         } else {
2009             result = vmCall(
2010                 Int64, m_out.operation(operationStrCat2), m_callFrame,
2011                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
2012                 lowJSValue(m_node->child2(), ManualOperandSpeculation));
2013         }
2014         setJSValue(result);
2015     }
2016     
2017     void compileArithAddOrSub()
2018     {
2019         bool isSub =  m_node->op() == ArithSub;
2020         switch (m_node->binaryUseKind()) {
2021         case Int32Use: {
2022             LValue left = lowInt32(m_node->child1());
2023             LValue right = lowInt32(m_node->child2());
2024
2025             if (!shouldCheckOverflow(m_node->arithMode())) {
2026                 setInt32(isSub ? m_out.sub(left, right) : m_out.add(left, right));
2027                 break;
2028             }
2029
2030             CheckValue* result =
2031                 isSub ? m_out.speculateSub(left, right) : m_out.speculateAdd(left, right);
2032             blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);
2033             setInt32(result);
2034             break;
2035         }
2036             
2037         case Int52RepUse: {
2038             if (!abstractValue(m_node->child1()).couldBeType(SpecInt52Only)
2039                 && !abstractValue(m_node->child2()).couldBeType(SpecInt52Only)) {
2040                 Int52Kind kind;
2041                 LValue left = lowWhicheverInt52(m_node->child1(), kind);
2042                 LValue right = lowInt52(m_node->child2(), kind);
2043                 setInt52(isSub ? m_out.sub(left, right) : m_out.add(left, right), kind);
2044                 break;
2045             }
2046
2047             LValue left = lowInt52(m_node->child1());
2048             LValue right = lowInt52(m_node->child2());
2049             CheckValue* result =
2050                 isSub ? m_out.speculateSub(left, right) : m_out.speculateAdd(left, right);
2051             blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);
2052             setInt52(result);
2053             break;
2054         }
2055             
2056         case DoubleRepUse: {
2057             LValue C1 = lowDouble(m_node->child1());
2058             LValue C2 = lowDouble(m_node->child2());
2059
2060             setDouble(isSub ? m_out.doubleSub(C1, C2) : m_out.doubleAdd(C1, C2));
2061             break;
2062         }
2063
2064         case UntypedUse: {
2065             if (!isSub) {
2066                 DFG_CRASH(m_graph, m_node, "Bad use kind");
2067                 break;
2068             }
2069
2070             CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic);
2071             ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(m_node->origin.semantic.bytecodeIndex);
2072             Instruction* instruction = &baselineCodeBlock->instructions()[m_node->origin.semantic.bytecodeIndex];
2073             auto repatchingFunction = operationValueSubOptimize;
2074             auto nonRepatchingFunction = operationValueSub;
2075             compileBinaryMathIC<JITSubGenerator>(arithProfile, instruction, repatchingFunction, nonRepatchingFunction);
2076             break;
2077         }
2078
2079         default:
2080             DFG_CRASH(m_graph, m_node, "Bad use kind");
2081             break;
2082         }
2083     }
2084
2085     void compileArithClz32()
2086     {
2087         if (m_node->child1().useKind() == Int32Use || m_node->child1().useKind() == KnownInt32Use) {
2088             LValue operand = lowInt32(m_node->child1());
2089             setInt32(m_out.ctlz32(operand));
2090             return;
2091         }
2092         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse, m_node->child1().useKind());
2093         LValue argument = lowJSValue(m_node->child1());
2094         LValue result = vmCall(Int32, m_out.operation(operationArithClz32), m_callFrame, argument);
2095         setInt32(result);
2096     }
2097     
2098     void compileArithMul()
2099     {
2100         switch (m_node->binaryUseKind()) {
2101         case Int32Use: {
2102             LValue left = lowInt32(m_node->child1());
2103             LValue right = lowInt32(m_node->child2());
2104             
2105             LValue result;
2106
2107             if (!shouldCheckOverflow(m_node->arithMode()))
2108                 result = m_out.mul(left, right);
2109             else {
2110                 CheckValue* speculation = m_out.speculateMul(left, right);
2111                 blessSpeculation(speculation, Overflow, noValue(), nullptr, m_origin);
2112                 result = speculation;
2113             }
2114             
2115             if (shouldCheckNegativeZero(m_node->arithMode())) {
2116                 LBasicBlock slowCase = m_out.newBlock();
2117                 LBasicBlock continuation = m_out.newBlock();
2118                 
2119                 m_out.branch(
2120                     m_out.notZero32(result), usually(continuation), rarely(slowCase));
2121                 
2122                 LBasicBlock lastNext = m_out.appendTo(slowCase, continuation);
2123                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(left, m_out.int32Zero));
2124                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(right, m_out.int32Zero));
2125                 m_out.jump(continuation);
2126                 m_out.appendTo(continuation, lastNext);
2127             }
2128             
2129             setInt32(result);
2130             break;
2131         }
2132             
2133         case Int52RepUse: {
2134             Int52Kind kind;
2135             LValue left = lowWhicheverInt52(m_node->child1(), kind);
2136             LValue right = lowInt52(m_node->child2(), opposite(kind));
2137
2138             CheckValue* result = m_out.speculateMul(left, right);
2139             blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);
2140
2141             if (shouldCheckNegativeZero(m_node->arithMode())) {
2142                 LBasicBlock slowCase = m_out.newBlock();
2143                 LBasicBlock continuation = m_out.newBlock();
2144                 
2145                 m_out.branch(
2146                     m_out.notZero64(result), usually(continuation), rarely(slowCase));
2147                 
2148                 LBasicBlock lastNext = m_out.appendTo(slowCase, continuation);
2149                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(left, m_out.int64Zero));
2150                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(right, m_out.int64Zero));
2151                 m_out.jump(continuation);
2152                 m_out.appendTo(continuation, lastNext);
2153             }
2154             
2155             setInt52(result);
2156             break;
2157         }
2158             
2159         case DoubleRepUse: {
2160             setDouble(
2161                 m_out.doubleMul(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
2162             break;
2163         }
2164
2165         case UntypedUse: {
2166             CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic);
2167             ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(m_node->origin.semantic.bytecodeIndex);
2168             Instruction* instruction = &baselineCodeBlock->instructions()[m_node->origin.semantic.bytecodeIndex];
2169             auto repatchingFunction = operationValueMulOptimize;
2170             auto nonRepatchingFunction = operationValueMul;
2171             compileBinaryMathIC<JITMulGenerator>(arithProfile, instruction, repatchingFunction, nonRepatchingFunction);
2172             break;
2173         }
2174
2175         default:
2176             DFG_CRASH(m_graph, m_node, "Bad use kind");
2177             break;
2178         }
2179     }
2180
2181     void compileArithDiv()
2182     {
2183         switch (m_node->binaryUseKind()) {
2184         case Int32Use: {
2185             LValue numerator = lowInt32(m_node->child1());
2186             LValue denominator = lowInt32(m_node->child2());
2187
2188             if (shouldCheckNegativeZero(m_node->arithMode())) {
2189                 LBasicBlock zeroNumerator = m_out.newBlock();
2190                 LBasicBlock numeratorContinuation = m_out.newBlock();
2191
2192                 m_out.branch(
2193                     m_out.isZero32(numerator),
2194                     rarely(zeroNumerator), usually(numeratorContinuation));
2195
2196                 LBasicBlock innerLastNext = m_out.appendTo(zeroNumerator, numeratorContinuation);
2197
2198                 speculate(
2199                     NegativeZero, noValue(), 0, m_out.lessThan(denominator, m_out.int32Zero));
2200
2201                 m_out.jump(numeratorContinuation);
2202
2203                 m_out.appendTo(numeratorContinuation, innerLastNext);
2204             }
2205             
2206             if (shouldCheckOverflow(m_node->arithMode())) {
2207                 LBasicBlock unsafeDenominator = m_out.newBlock();
2208                 LBasicBlock continuation = m_out.newBlock();
2209
2210                 LValue adjustedDenominator = m_out.add(denominator, m_out.int32One);
2211                 m_out.branch(
2212                     m_out.above(adjustedDenominator, m_out.int32One),
2213                     usually(continuation), rarely(unsafeDenominator));
2214
2215                 LBasicBlock lastNext = m_out.appendTo(unsafeDenominator, continuation);
2216                 LValue neg2ToThe31 = m_out.constInt32(-2147483647-1);
2217                 speculate(Overflow, noValue(), nullptr, m_out.isZero32(denominator));
2218                 speculate(Overflow, noValue(), nullptr, m_out.equal(numerator, neg2ToThe31));
2219                 m_out.jump(continuation);
2220
2221                 m_out.appendTo(continuation, lastNext);
2222                 LValue result = m_out.div(numerator, denominator);
2223                 speculate(
2224                     Overflow, noValue(), 0,
2225                     m_out.notEqual(m_out.mul(result, denominator), numerator));
2226                 setInt32(result);
2227             } else
2228                 setInt32(m_out.chillDiv(numerator, denominator));
2229
2230             break;
2231         }
2232             
2233         case DoubleRepUse: {
2234             setDouble(m_out.doubleDiv(
2235                 lowDouble(m_node->child1()), lowDouble(m_node->child2())));
2236             break;
2237         }
2238
2239         case UntypedUse: {
2240             emitBinarySnippet<JITDivGenerator, NeedScratchFPR>(operationValueDiv);
2241             break;
2242         }
2243
2244         default:
2245             DFG_CRASH(m_graph, m_node, "Bad use kind");
2246             break;
2247         }
2248     }
2249     
2250     void compileArithMod()
2251     {
2252         switch (m_node->binaryUseKind()) {
2253         case Int32Use: {
2254             LValue numerator = lowInt32(m_node->child1());
2255             LValue denominator = lowInt32(m_node->child2());
2256
2257             LValue remainder;
2258             if (shouldCheckOverflow(m_node->arithMode())) {
2259                 LBasicBlock unsafeDenominator = m_out.newBlock();
2260                 LBasicBlock continuation = m_out.newBlock();
2261
2262                 LValue adjustedDenominator = m_out.add(denominator, m_out.int32One);
2263                 m_out.branch(
2264                     m_out.above(adjustedDenominator, m_out.int32One),
2265                     usually(continuation), rarely(unsafeDenominator));
2266
2267                 LBasicBlock lastNext = m_out.appendTo(unsafeDenominator, continuation);
2268                 LValue neg2ToThe31 = m_out.constInt32(-2147483647-1);
2269                 speculate(Overflow, noValue(), nullptr, m_out.isZero32(denominator));
2270                 speculate(Overflow, noValue(), nullptr, m_out.equal(numerator, neg2ToThe31));
2271                 m_out.jump(continuation);
2272
2273                 m_out.appendTo(continuation, lastNext);
2274                 LValue result = m_out.mod(numerator, denominator);
2275                 remainder = result;
2276             } else
2277                 remainder = m_out.chillMod(numerator, denominator);
2278
2279             if (shouldCheckNegativeZero(m_node->arithMode())) {
2280                 LBasicBlock negativeNumerator = m_out.newBlock();
2281                 LBasicBlock numeratorContinuation = m_out.newBlock();
2282
2283                 m_out.branch(
2284                     m_out.lessThan(numerator, m_out.int32Zero),
2285                     unsure(negativeNumerator), unsure(numeratorContinuation));
2286
2287                 LBasicBlock innerLastNext = m_out.appendTo(negativeNumerator, numeratorContinuation);
2288
2289                 speculate(NegativeZero, noValue(), 0, m_out.isZero32(remainder));
2290
2291                 m_out.jump(numeratorContinuation);
2292
2293                 m_out.appendTo(numeratorContinuation, innerLastNext);
2294             }
2295
2296             setInt32(remainder);
2297             break;
2298         }
2299             
2300         case DoubleRepUse: {
2301             setDouble(
2302                 m_out.doubleMod(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
2303             break;
2304         }
2305             
2306         default:
2307             DFG_CRASH(m_graph, m_node, "Bad use kind");
2308             break;
2309         }
2310     }
2311
2312     void compileArithMinOrMax()
2313     {
2314         switch (m_node->binaryUseKind()) {
2315         case Int32Use: {
2316             LValue left = lowInt32(m_node->child1());
2317             LValue right = lowInt32(m_node->child2());
2318             
2319             setInt32(
2320                 m_out.select(
2321                     m_node->op() == ArithMin
2322                         ? m_out.lessThan(left, right)
2323                         : m_out.lessThan(right, left),
2324                     left, right));
2325             break;
2326         }
2327             
2328         case DoubleRepUse: {
2329             LValue left = lowDouble(m_node->child1());
2330             LValue right = lowDouble(m_node->child2());
2331             
2332             LBasicBlock notLessThan = m_out.newBlock();
2333             LBasicBlock continuation = m_out.newBlock();
2334             
2335             Vector<ValueFromBlock, 2> results;
2336             
2337             results.append(m_out.anchor(left));
2338             m_out.branch(
2339                 m_node->op() == ArithMin
2340                     ? m_out.doubleLessThan(left, right)
2341                     : m_out.doubleGreaterThan(left, right),
2342                 unsure(continuation), unsure(notLessThan));
2343             
2344             LBasicBlock lastNext = m_out.appendTo(notLessThan, continuation);
2345             results.append(m_out.anchor(m_out.select(
2346                 m_node->op() == ArithMin
2347                     ? m_out.doubleGreaterThanOrEqual(left, right)
2348                     : m_out.doubleLessThanOrEqual(left, right),
2349                 right, m_out.constDouble(PNaN))));
2350             m_out.jump(continuation);
2351             
2352             m_out.appendTo(continuation, lastNext);
2353             setDouble(m_out.phi(Double, results));
2354             break;
2355         }
2356             
2357         default:
2358             DFG_CRASH(m_graph, m_node, "Bad use kind");
2359             break;
2360         }
2361     }
2362     
2363     void compileArithAbs()
2364     {
2365         switch (m_node->child1().useKind()) {
2366         case Int32Use: {
2367             LValue value = lowInt32(m_node->child1());
2368
2369             LValue mask = m_out.aShr(value, m_out.constInt32(31));
2370             LValue result = m_out.bitXor(mask, m_out.add(mask, value));
2371
2372             if (shouldCheckOverflow(m_node->arithMode()))
2373                 speculate(Overflow, noValue(), 0, m_out.lessThan(result, m_out.int32Zero));
2374
2375             setInt32(result);
2376             break;
2377         }
2378             
2379         case DoubleRepUse: {
2380             setDouble(m_out.doubleAbs(lowDouble(m_node->child1())));
2381             break;
2382         }
2383             
2384         default: {
2385             DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse, m_node->child1().useKind());
2386             LValue argument = lowJSValue(m_node->child1());
2387             LValue result = vmCall(Double, m_out.operation(operationArithAbs), m_callFrame, argument);
2388             setDouble(result);
2389             break;
2390         }
2391         }
2392     }
2393
2394     void compileArithUnary()
2395     {
2396         if (m_node->child1().useKind() == DoubleRepUse) {
2397             setDouble(m_out.doubleUnary(m_node->arithUnaryType(), lowDouble(m_node->child1())));
2398             return;
2399         }
2400         LValue argument = lowJSValue(m_node->child1());
2401         LValue result = vmCall(Double, m_out.operation(DFG::arithUnaryOperation(m_node->arithUnaryType())), m_callFrame, argument);
2402         setDouble(result);
2403     }
2404
2405     void compileArithPow()
2406     {
2407         if (m_node->child2().useKind() == Int32Use)
2408             setDouble(m_out.doublePowi(lowDouble(m_node->child1()), lowInt32(m_node->child2())));
2409         else {
2410             LValue base = lowDouble(m_node->child1());
2411             LValue exponent = lowDouble(m_node->child2());
2412
2413             LBasicBlock integerExponentIsSmallBlock = m_out.newBlock();
2414             LBasicBlock integerExponentPowBlock = m_out.newBlock();
2415             LBasicBlock doubleExponentPowBlockEntry = m_out.newBlock();
2416             LBasicBlock nanExceptionBaseIsOne = m_out.newBlock();
2417             LBasicBlock nanExceptionExponentIsInfinity = m_out.newBlock();
2418             LBasicBlock testExponentIsOneHalf = m_out.newBlock();
2419             LBasicBlock handleBaseZeroExponentIsOneHalf = m_out.newBlock();
2420             LBasicBlock handleInfinityForExponentIsOneHalf = m_out.newBlock();
2421             LBasicBlock exponentIsOneHalfNormal = m_out.newBlock();
2422             LBasicBlock exponentIsOneHalfInfinity = m_out.newBlock();
2423             LBasicBlock testExponentIsNegativeOneHalf = m_out.newBlock();
2424             LBasicBlock testBaseZeroExponentIsNegativeOneHalf = m_out.newBlock();
2425             LBasicBlock handleBaseZeroExponentIsNegativeOneHalf = m_out.newBlock();
2426             LBasicBlock handleInfinityForExponentIsNegativeOneHalf = m_out.newBlock();
2427             LBasicBlock exponentIsNegativeOneHalfNormal = m_out.newBlock();
2428             LBasicBlock exponentIsNegativeOneHalfInfinity = m_out.newBlock();
2429             LBasicBlock powBlock = m_out.newBlock();
2430             LBasicBlock nanExceptionResultIsNaN = m_out.newBlock();
2431             LBasicBlock continuation = m_out.newBlock();
2432
2433             LValue integerExponent = m_out.doubleToInt(exponent);
2434             LValue integerExponentConvertedToDouble = m_out.intToDouble(integerExponent);
2435             LValue exponentIsInteger = m_out.doubleEqual(exponent, integerExponentConvertedToDouble);
2436             m_out.branch(exponentIsInteger, unsure(integerExponentIsSmallBlock), unsure(doubleExponentPowBlockEntry));
2437
2438             LBasicBlock lastNext = m_out.appendTo(integerExponentIsSmallBlock, integerExponentPowBlock);
2439             LValue integerExponentBelowMax = m_out.belowOrEqual(integerExponent, m_out.constInt32(maxExponentForIntegerMathPow));
2440             m_out.branch(integerExponentBelowMax, usually(integerExponentPowBlock), rarely(doubleExponentPowBlockEntry));
2441
2442             m_out.appendTo(integerExponentPowBlock, doubleExponentPowBlockEntry);
2443             ValueFromBlock powDoubleIntResult = m_out.anchor(m_out.doublePowi(base, integerExponent));
2444             m_out.jump(continuation);
2445
2446             // If y is NaN, the result is NaN.
2447             m_out.appendTo(doubleExponentPowBlockEntry, nanExceptionBaseIsOne);
2448             LValue exponentIsNaN;
2449             if (provenType(m_node->child2()) & SpecDoubleNaN)
2450                 exponentIsNaN = m_out.doubleNotEqualOrUnordered(exponent, exponent);
2451             else
2452                 exponentIsNaN = m_out.booleanFalse;
2453             m_out.branch(exponentIsNaN, rarely(nanExceptionResultIsNaN), usually(nanExceptionBaseIsOne));
2454
2455             // If abs(x) is 1 and y is +infinity, the result is NaN.
2456             // If abs(x) is 1 and y is -infinity, the result is NaN.
2457
2458             //     Test if base == 1.
2459             m_out.appendTo(nanExceptionBaseIsOne, nanExceptionExponentIsInfinity);
2460             LValue absoluteBase = m_out.doubleAbs(base);
2461             LValue absoluteBaseIsOne = m_out.doubleEqual(absoluteBase, m_out.constDouble(1));
2462             m_out.branch(absoluteBaseIsOne, rarely(nanExceptionExponentIsInfinity), usually(testExponentIsOneHalf));
2463
2464             //     Test if abs(y) == Infinity.
2465             m_out.appendTo(nanExceptionExponentIsInfinity, testExponentIsOneHalf);
2466             LValue absoluteExponent = m_out.doubleAbs(exponent);
2467             LValue absoluteExponentIsInfinity = m_out.doubleEqual(absoluteExponent, m_out.constDouble(std::numeric_limits<double>::infinity()));
2468             m_out.branch(absoluteExponentIsInfinity, rarely(nanExceptionResultIsNaN), usually(testExponentIsOneHalf));
2469
2470             // If y == 0.5 or y == -0.5, handle it through SQRT.
2471             // We have be carefuly with -0 and -Infinity.
2472
2473             //     Test if y == 0.5
2474             m_out.appendTo(testExponentIsOneHalf, handleBaseZeroExponentIsOneHalf);
2475             LValue exponentIsOneHalf = m_out.doubleEqual(exponent, m_out.constDouble(0.5));
2476             m_out.branch(exponentIsOneHalf, rarely(handleBaseZeroExponentIsOneHalf), usually(testExponentIsNegativeOneHalf));
2477
2478             //     Handle x == -0.
2479             m_out.appendTo(handleBaseZeroExponentIsOneHalf, handleInfinityForExponentIsOneHalf);
2480             LValue baseIsZeroExponentIsOneHalf = m_out.doubleEqual(base, m_out.doubleZero);
2481             ValueFromBlock zeroResultExponentIsOneHalf = m_out.anchor(m_out.doubleZero);
2482             m_out.branch(baseIsZeroExponentIsOneHalf, rarely(continuation), usually(handleInfinityForExponentIsOneHalf));
2483
2484             //     Test if abs(x) == Infinity.
2485             m_out.appendTo(handleInfinityForExponentIsOneHalf, exponentIsOneHalfNormal);
2486             LValue absoluteBaseIsInfinityOneHalf = m_out.doubleEqual(absoluteBase, m_out.constDouble(std::numeric_limits<double>::infinity()));
2487             m_out.branch(absoluteBaseIsInfinityOneHalf, rarely(exponentIsOneHalfInfinity), usually(exponentIsOneHalfNormal));
2488
2489             //     The exponent is 0.5, the base is finite or NaN, we can use SQRT.
2490             m_out.appendTo(exponentIsOneHalfNormal, exponentIsOneHalfInfinity);
2491             ValueFromBlock sqrtResult = m_out.anchor(m_out.doubleSqrt(base));
2492             m_out.jump(continuation);
2493
2494             //     The exponent is 0.5, the base is infinite, the result is always infinite.
2495             m_out.appendTo(exponentIsOneHalfInfinity, testExponentIsNegativeOneHalf);
2496             ValueFromBlock sqrtInfinityResult = m_out.anchor(m_out.constDouble(std::numeric_limits<double>::infinity()));
2497             m_out.jump(continuation);
2498
2499             //     Test if y == -0.5
2500             m_out.appendTo(testExponentIsNegativeOneHalf, testBaseZeroExponentIsNegativeOneHalf);
2501             LValue exponentIsNegativeOneHalf = m_out.doubleEqual(exponent, m_out.constDouble(-0.5));
2502             m_out.branch(exponentIsNegativeOneHalf, rarely(testBaseZeroExponentIsNegativeOneHalf), usually(powBlock));
2503
2504             //     Handle x == -0.
2505             m_out.appendTo(testBaseZeroExponentIsNegativeOneHalf, handleBaseZeroExponentIsNegativeOneHalf);
2506             LValue baseIsZeroExponentIsNegativeOneHalf = m_out.doubleEqual(base, m_out.doubleZero);
2507             m_out.branch(baseIsZeroExponentIsNegativeOneHalf, rarely(handleBaseZeroExponentIsNegativeOneHalf), usually(handleInfinityForExponentIsNegativeOneHalf));
2508
2509             m_out.appendTo(handleBaseZeroExponentIsNegativeOneHalf, handleInfinityForExponentIsNegativeOneHalf);
2510             ValueFromBlock oneOverSqrtZeroResult = m_out.anchor(m_out.constDouble(std::numeric_limits<double>::infinity()));
2511             m_out.jump(continuation);
2512
2513             //     Test if abs(x) == Infinity.
2514             m_out.appendTo(handleInfinityForExponentIsNegativeOneHalf, exponentIsNegativeOneHalfNormal);
2515             LValue absoluteBaseIsInfinityNegativeOneHalf = m_out.doubleEqual(absoluteBase, m_out.constDouble(std::numeric_limits<double>::infinity()));
2516             m_out.branch(absoluteBaseIsInfinityNegativeOneHalf, rarely(exponentIsNegativeOneHalfInfinity), usually(exponentIsNegativeOneHalfNormal));
2517
2518             //     The exponent is -0.5, the base is finite or NaN, we can use 1/SQRT.
2519             m_out.appendTo(exponentIsNegativeOneHalfNormal, exponentIsNegativeOneHalfInfinity);
2520             LValue sqrtBase = m_out.doubleSqrt(base);
2521             ValueFromBlock oneOverSqrtResult = m_out.anchor(m_out.div(m_out.constDouble(1.), sqrtBase));
2522             m_out.jump(continuation);
2523
2524             //     The exponent is -0.5, the base is infinite, the result is always zero.
2525             m_out.appendTo(exponentIsNegativeOneHalfInfinity, powBlock);
2526             ValueFromBlock oneOverSqrtInfinityResult = m_out.anchor(m_out.doubleZero);
2527             m_out.jump(continuation);
2528
2529             m_out.appendTo(powBlock, nanExceptionResultIsNaN);
2530             ValueFromBlock powResult = m_out.anchor(m_out.doublePow(base, exponent));
2531             m_out.jump(continuation);
2532
2533             m_out.appendTo(nanExceptionResultIsNaN, continuation);
2534             ValueFromBlock pureNan = m_out.anchor(m_out.constDouble(PNaN));
2535             m_out.jump(continuation);
2536
2537             m_out.appendTo(continuation, lastNext);
2538             setDouble(m_out.phi(Double, powDoubleIntResult, zeroResultExponentIsOneHalf, sqrtResult, sqrtInfinityResult, oneOverSqrtZeroResult, oneOverSqrtResult, oneOverSqrtInfinityResult, powResult, pureNan));
2539         }
2540     }
2541
2542     void compileArithRandom()
2543     {
2544         JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
2545
2546         // Inlined WeakRandom::advance().
2547         // uint64_t x = m_low;
2548         void* lowAddress = reinterpret_cast<uint8_t*>(globalObject) + JSGlobalObject::weakRandomOffset() + WeakRandom::lowOffset();
2549         LValue low = m_out.load64(m_out.absolute(lowAddress));
2550         // uint64_t y = m_high;
2551         void* highAddress = reinterpret_cast<uint8_t*>(globalObject) + JSGlobalObject::weakRandomOffset() + WeakRandom::highOffset();
2552         LValue high = m_out.load64(m_out.absolute(highAddress));
2553         // m_low = y;
2554         m_out.store64(high, m_out.absolute(lowAddress));
2555
2556         // x ^= x << 23;
2557         LValue phase1 = m_out.bitXor(m_out.shl(low, m_out.constInt64(23)), low);
2558
2559         // x ^= x >> 17;
2560         LValue phase2 = m_out.bitXor(m_out.lShr(phase1, m_out.constInt64(17)), phase1);
2561
2562         // x ^= y ^ (y >> 26);
2563         LValue phase3 = m_out.bitXor(m_out.bitXor(high, m_out.lShr(high, m_out.constInt64(26))), phase2);
2564
2565         // m_high = x;
2566         m_out.store64(phase3, m_out.absolute(highAddress));
2567
2568         // return x + y;
2569         LValue random64 = m_out.add(phase3, high);
2570
2571         // Extract random 53bit. [0, 53] bit is safe integer number ranges in double representation.
2572         LValue random53 = m_out.bitAnd(random64, m_out.constInt64((1ULL << 53) - 1));
2573
2574         LValue double53Integer = m_out.intToDouble(random53);
2575
2576         // Convert `(53bit double integer value) / (1 << 53)` to `(53bit double integer value) * (1.0 / (1 << 53))`.
2577         // In latter case, `1.0 / (1 << 53)` will become a double value represented as (mantissa = 0 & exp = 970, it means 1e-(2**54)).
2578         static const double scale = 1.0 / (1ULL << 53);
2579
2580         // Multiplying 1e-(2**54) with the double integer does not change anything of the mantissa part of the double integer.
2581         // It just reduces the exp part of the given 53bit double integer.
2582         // (Except for 0.0. This is specially handled and in this case, exp just becomes 0.)
2583         // Now we get 53bit precision random double value in [0, 1).
2584         LValue result = m_out.doubleMul(double53Integer, m_out.constDouble(scale));
2585
2586         setDouble(result);
2587     }
2588
2589     void compileArithRound()
2590     {
2591         if (m_node->child1().useKind() == DoubleRepUse) {
2592             LValue result = nullptr;
2593             if (producesInteger(m_node->arithRoundingMode()) && !shouldCheckNegativeZero(m_node->arithRoundingMode())) {
2594                 LValue value = lowDouble(m_node->child1());
2595                 result = m_out.doubleFloor(m_out.doubleAdd(value, m_out.constDouble(0.5)));
2596             } else {
2597                 LBasicBlock realPartIsMoreThanHalf = m_out.newBlock();
2598                 LBasicBlock continuation = m_out.newBlock();
2599
2600                 LValue value = lowDouble(m_node->child1());
2601                 LValue integerValue = m_out.doubleCeil(value);
2602                 ValueFromBlock integerValueResult = m_out.anchor(integerValue);
2603
2604                 LValue realPart = m_out.doubleSub(integerValue, value);
2605
2606                 m_out.branch(m_out.doubleGreaterThanOrUnordered(realPart, m_out.constDouble(0.5)), unsure(realPartIsMoreThanHalf), unsure(continuation));
2607
2608                 LBasicBlock lastNext = m_out.appendTo(realPartIsMoreThanHalf, continuation);
2609                 LValue integerValueRoundedDown = m_out.doubleSub(integerValue, m_out.constDouble(1));
2610                 ValueFromBlock integerValueRoundedDownResult = m_out.anchor(integerValueRoundedDown);
2611                 m_out.jump(continuation);
2612                 m_out.appendTo(continuation, lastNext);
2613
2614                 result = m_out.phi(Double, integerValueResult, integerValueRoundedDownResult);
2615             }
2616
2617             if (producesInteger(m_node->arithRoundingMode())) {
2618                 LValue integerValue = convertDoubleToInt32(result, shouldCheckNegativeZero(m_node->arithRoundingMode()));
2619                 setInt32(integerValue);
2620             } else
2621                 setDouble(result);
2622             return;
2623         }
2624
2625         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse, m_node->child1().useKind());
2626         LValue argument = lowJSValue(m_node->child1());
2627         setJSValue(vmCall(Int64, m_out.operation(operationArithRound), m_callFrame, argument));
2628     }
2629
2630     void compileArithFloor()
2631     {
2632         if (m_node->child1().useKind() == DoubleRepUse) {
2633             LValue value = lowDouble(m_node->child1());
2634             LValue integerValue = m_out.doubleFloor(value);
2635             if (producesInteger(m_node->arithRoundingMode()))
2636                 setInt32(convertDoubleToInt32(integerValue, shouldCheckNegativeZero(m_node->arithRoundingMode())));
2637             else
2638                 setDouble(integerValue);
2639             return;
2640         }
2641         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse, m_node->child1().useKind());
2642         LValue argument = lowJSValue(m_node->child1());
2643         setJSValue(vmCall(Int64, m_out.operation(operationArithFloor), m_callFrame, argument));
2644     }
2645
2646     void compileArithCeil()
2647     {
2648         if (m_node->child1().useKind() == DoubleRepUse) {
2649             LValue value = lowDouble(m_node->child1());
2650             LValue integerValue = m_out.doubleCeil(value);
2651             if (producesInteger(m_node->arithRoundingMode()))
2652                 setInt32(convertDoubleToInt32(integerValue, shouldCheckNegativeZero(m_node->arithRoundingMode())));
2653             else
2654                 setDouble(integerValue);
2655             return;
2656         }
2657         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse, m_node->child1().useKind());
2658         LValue argument = lowJSValue(m_node->child1());
2659         setJSValue(vmCall(Int64, m_out.operation(operationArithCeil), m_callFrame, argument));
2660     }
2661
2662     void compileArithTrunc()
2663     {
2664         if (m_node->child1().useKind() == DoubleRepUse) {
2665             LValue value = lowDouble(m_node->child1());
2666             LValue result = m_out.doubleTrunc(value);
2667             if (producesInteger(m_node->arithRoundingMode()))
2668                 setInt32(convertDoubleToInt32(result, shouldCheckNegativeZero(m_node->arithRoundingMode())));
2669             else
2670                 setDouble(result);
2671             return;
2672         }
2673         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse, m_node->child1().useKind());
2674         LValue argument = lowJSValue(m_node->child1());
2675         setJSValue(vmCall(Int64, m_out.operation(operationArithTrunc), m_callFrame, argument));
2676     }
2677
2678     void compileArithSqrt()
2679     {
2680         if (m_node->child1().useKind() == DoubleRepUse) {
2681             setDouble(m_out.doubleSqrt(lowDouble(m_node->child1())));
2682             return;
2683         }
2684         LValue argument = lowJSValue(m_node->child1());
2685         LValue result = vmCall(Double, m_out.operation(operationArithSqrt), m_callFrame, argument);
2686         setDouble(result);
2687     }
2688
2689     void compileArithFRound()
2690     {
2691         if (m_node->child1().useKind() == DoubleRepUse) {
2692             setDouble(m_out.fround(lowDouble(m_node->child1())));
2693             return;
2694         }
2695         LValue argument = lowJSValue(m_node->child1());
2696         LValue result = vmCall(Double, m_out.operation(operationArithFRound), m_callFrame, argument);
2697         setDouble(result);
2698     }
2699     
2700     void compileArithNegate()
2701     {
2702         switch (m_node->child1().useKind()) {
2703         case Int32Use: {
2704             LValue value = lowInt32(m_node->child1());
2705             
2706             LValue result;
2707             if (!shouldCheckOverflow(m_node->arithMode()))
2708                 result = m_out.neg(value);
2709             else if (!shouldCheckNegativeZero(m_node->arithMode())) {
2710                 CheckValue* check = m_out.speculateSub(m_out.int32Zero, value);
2711                 blessSpeculation(check, Overflow, noValue(), nullptr, m_origin);
2712                 result = check;
2713             } else {
2714                 speculate(Overflow, noValue(), 0, m_out.testIsZero32(value, m_out.constInt32(0x7fffffff)));
2715                 result = m_out.neg(value);
2716             }
2717
2718             setInt32(result);
2719             break;
2720         }
2721             
2722         case Int52RepUse: {
2723             if (!abstractValue(m_node->child1()).couldBeType(SpecInt52Only)) {
2724                 Int52Kind kind;
2725                 LValue value = lowWhicheverInt52(m_node->child1(), kind);
2726                 LValue result = m_out.neg(value);
2727                 if (shouldCheckNegativeZero(m_node->arithMode()))
2728                     speculate(NegativeZero, noValue(), 0, m_out.isZero64(result));
2729                 setInt52(result, kind);
2730                 break;
2731             }
2732             
2733             LValue value = lowInt52(m_node->child1());
2734             CheckValue* result = m_out.speculateSub(m_out.int64Zero, value);
2735             blessSpeculation(result, Int52Overflow, noValue(), nullptr, m_origin);
2736             if (shouldCheckNegativeZero(m_node->arithMode()))
2737                 speculate(NegativeZero, noValue(), 0, m_out.isZero64(result));
2738             setInt52(result);
2739             break;
2740         }
2741             
2742         case DoubleRepUse: {
2743             setDouble(m_out.doubleNeg(lowDouble(m_node->child1())));
2744             break;
2745         }
2746             
2747         default:
2748             DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse, m_node->child1().useKind());
2749             CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic);
2750             ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(m_node->origin.semantic.bytecodeIndex);
2751             Instruction* instruction = &baselineCodeBlock->instructions()[m_node->origin.semantic.bytecodeIndex];
2752             auto repatchingFunction = operationArithNegateOptimize;
2753             auto nonRepatchingFunction = operationArithNegate;
2754             compileUnaryMathIC<JITNegGenerator>(arithProfile, instruction, repatchingFunction, nonRepatchingFunction);
2755             break;
2756         }
2757     }
2758     
2759     void compileBitAnd()
2760     {
2761         if (m_node->isBinaryUseKind(UntypedUse)) {
2762             emitBinaryBitOpSnippet<JITBitAndGenerator>(operationValueBitAnd);
2763             return;
2764         }
2765         setInt32(m_out.bitAnd(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2766     }
2767     
2768     void compileBitOr()
2769     {
2770         if (m_node->isBinaryUseKind(UntypedUse)) {
2771             emitBinaryBitOpSnippet<JITBitOrGenerator>(operationValueBitOr);
2772             return;
2773         }
2774         setInt32(m_out.bitOr(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2775     }
2776     
2777     void compileBitXor()
2778     {
2779         if (m_node->isBinaryUseKind(UntypedUse)) {
2780             emitBinaryBitOpSnippet<JITBitXorGenerator>(operationValueBitXor);
2781             return;
2782         }
2783         setInt32(m_out.bitXor(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2784     }
2785     
2786     void compileBitRShift()
2787     {
2788         if (m_node->isBinaryUseKind(UntypedUse)) {
2789             emitRightShiftSnippet(JITRightShiftGenerator::SignedShift);
2790             return;
2791         }
2792         setInt32(m_out.aShr(
2793             lowInt32(m_node->child1()),
2794             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2795     }
2796     
2797     void compileBitLShift()
2798     {
2799         if (m_node->isBinaryUseKind(UntypedUse)) {
2800             emitBinaryBitOpSnippet<JITLeftShiftGenerator>(operationValueBitLShift);
2801             return;
2802         }
2803         setInt32(m_out.shl(
2804             lowInt32(m_node->child1()),
2805             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2806     }
2807     
2808     void compileBitURShift()
2809     {
2810         if (m_node->isBinaryUseKind(UntypedUse)) {
2811             emitRightShiftSnippet(JITRightShiftGenerator::UnsignedShift);
2812             return;
2813         }
2814         setInt32(m_out.lShr(
2815             lowInt32(m_node->child1()),
2816             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2817     }
2818     
2819     void compileUInt32ToNumber()
2820     {
2821         LValue value = lowInt32(m_node->child1());
2822
2823         if (doesOverflow(m_node->arithMode())) {
2824             setStrictInt52(m_out.zeroExtPtr(value));
2825             return;
2826         }
2827
2828         speculate(Overflow, noValue(), 0, m_out.lessThan(value, m_out.int32Zero));
2829         setInt32(value);
2830     }
2831     
2832     void compileCheckStructure()
2833     {
2834         ExitKind exitKind;
2835         if (m_node->child1()->hasConstant())
2836             exitKind = BadConstantCache;
2837         else
2838             exitKind = BadCache;
2839
2840         switch (m_node->child1().useKind()) {
2841         case CellUse:
2842         case KnownCellUse: {
2843             LValue cell = lowCell(m_node->child1());
2844             
2845             checkStructure(
2846                 m_out.load32(cell, m_heaps.JSCell_structureID), jsValueValue(cell),
2847                 exitKind, m_node->structureSet(),
2848                 [&] (RegisteredStructure structure) {
2849                     return weakStructureID(structure);
2850                 });
2851             return;
2852         }
2853
2854         case CellOrOtherUse: {
2855             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
2856
2857             LBasicBlock cellCase = m_out.newBlock();
2858             LBasicBlock notCellCase = m_out.newBlock();
2859             LBasicBlock continuation = m_out.newBlock();
2860
2861             m_out.branch(
2862                 isCell(value, provenType(m_node->child1())), unsure(cellCase), unsure(notCellCase));
2863
2864             LBasicBlock lastNext = m_out.appendTo(cellCase, notCellCase);
2865             checkStructure(
2866                 m_out.load32(value, m_heaps.JSCell_structureID), jsValueValue(value),
2867                 exitKind, m_node->structureSet(),
2868                 [&] (RegisteredStructure structure) {
2869                     return weakStructureID(structure);
2870                 });
2871             m_out.jump(continuation);
2872
2873             m_out.appendTo(notCellCase, continuation);
2874             FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), SpecCell | SpecOther, isNotOther(value));
2875             m_out.jump(continuation);
2876
2877             m_out.appendTo(continuation, lastNext);
2878             return;
2879         }
2880
2881         default:
2882             DFG_CRASH(m_graph, m_node, "Bad use kind");
2883             return;
2884         }
2885     }
2886
2887     void compileCheckStructureOrEmpty()
2888     {
2889         ExitKind exitKind;
2890         if (m_node->child1()->hasConstant())
2891             exitKind = BadConstantCache;
2892         else
2893             exitKind = BadCache;
2894
2895         LValue cell = lowCell(m_node->child1());
2896         bool maySeeEmptyValue = m_interpreter.forNode(m_node->child1()).m_type & SpecEmpty;
2897         LBasicBlock notEmpty;
2898         LBasicBlock continuation;
2899         LBasicBlock lastNext;
2900         if (maySeeEmptyValue) {
2901             notEmpty = m_out.newBlock();
2902             continuation = m_out.newBlock();
2903             m_out.branch(m_out.isZero64(cell), unsure(continuation), unsure(notEmpty));
2904             lastNext = m_out.appendTo(notEmpty, continuation);
2905         }
2906
2907         checkStructure(
2908             m_out.load32(cell, m_heaps.JSCell_structureID), jsValueValue(cell),
2909             exitKind, m_node->structureSet(),
2910             [&] (RegisteredStructure structure) {
2911                 return weakStructureID(structure);
2912             });
2913
2914         if (maySeeEmptyValue) {
2915             m_out.jump(continuation);
2916             m_out.appendTo(continuation, lastNext);
2917         }
2918     }
2919     
2920     void compileCheckCell()
2921     {
2922         LValue cell = lowCell(m_node->child1());
2923         
2924         speculate(
2925             BadCell, jsValueValue(cell), m_node->child1().node(),
2926             m_out.notEqual(cell, weakPointer(m_node->cellOperand()->cell())));
2927     }
2928     
2929     void compileCheckBadCell()
2930     {
2931         terminate(BadCell);
2932     }
2933
2934     void compileCheckNotEmpty()
2935     {
2936         speculate(TDZFailure, noValue(), nullptr, m_out.isZero64(lowJSValue(m_node->child1())));
2937     }
2938
2939     void compileAssertNotEmpty()
2940     {
2941         if (!validationEnabled())
2942             return;
2943
2944         B3::PatchpointValue* patchpoint = m_out.patchpoint(Void);
2945         patchpoint->appendSomeRegister(lowJSValue(m_node->child1()));
2946         patchpoint->setGenerator(
2947             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
2948                 AllowMacroScratchRegisterUsage allowScratch(jit);
2949                 GPRReg input =  params[0].gpr();
2950                 CCallHelpers::Jump done = jit.branchTest64(CCallHelpers::NonZero, input);
2951                 jit.breakpoint();
2952                 done.link(&jit);
2953             });
2954     }
2955
2956     void compileCheckStringIdent()
2957     {
2958         UniquedStringImpl* uid = m_node->uidOperand();
2959         LValue stringImpl = lowStringIdent(m_node->child1());
2960         speculate(BadIdent, noValue(), nullptr, m_out.notEqual(stringImpl, m_out.constIntPtr(uid)));
2961     }
2962
2963     void compileGetExecutable()
2964     {
2965         LValue cell = lowCell(m_node->child1());
2966         speculateFunction(m_node->child1(), cell);
2967         setJSValue(
2968             m_out.bitXor(
2969                 m_out.loadPtr(cell, m_heaps.JSFunction_executable),
2970                 m_out.constIntPtr(JSFunctionPoison::key())));
2971     }
2972     
2973     void compileArrayify()
2974     {
2975         LValue cell = lowCell(m_node->child1());
2976         LValue property = !!m_node->child2() ? lowInt32(m_node->child2()) : 0;
2977         
2978         LBasicBlock unexpectedStructure = m_out.newBlock();
2979         LBasicBlock continuation = m_out.newBlock();
2980         
2981         auto isUnexpectedArray = [&] (LValue cell) {
2982             if (m_node->op() == Arrayify)
2983                 return m_out.logicalNot(isArrayTypeForArrayify(cell, m_node->arrayMode()));
2984
2985             ASSERT(m_node->op() == ArrayifyToStructure);
2986             return m_out.notEqual(m_out.load32(cell, m_heaps.JSCell_structureID), weakStructureID(m_node->structure()));
2987         };
2988
2989         m_out.branch(isUnexpectedArray(cell), rarely(unexpectedStructure), usually(continuation));
2990
2991         LBasicBlock lastNext = m_out.appendTo(unexpectedStructure, continuation);
2992         
2993         if (property) {
2994             switch (m_node->arrayMode().type()) {
2995             case Array::Int32:
2996             case Array::Double:
2997             case Array::Contiguous:
2998                 speculate(
2999                     Uncountable, noValue(), 0,
3000                     m_out.aboveOrEqual(property, m_out.constInt32(MIN_SPARSE_ARRAY_INDEX)));
3001                 break;
3002             default:
3003                 break;
3004             }
3005         }
3006         
3007         switch (m_node->arrayMode().type()) {
3008         case Array::Int32:
3009             vmCall(Void, m_out.operation(operationEnsureInt32), m_callFrame, cell);
3010             break;
3011         case Array::Double:
3012             vmCall(Void, m_out.operation(operationEnsureDouble), m_callFrame, cell);
3013             break;
3014         case Array::Contiguous:
3015             vmCall(Void, m_out.operation(operationEnsureContiguous), m_callFrame, cell);
3016             break;
3017         case Array::ArrayStorage:
3018         case Array::SlowPutArrayStorage:
3019             vmCall(Void, m_out.operation(operationEnsureArrayStorage), m_callFrame, cell);
3020             break;
3021         default:
3022             DFG_CRASH(m_graph, m_node, "Bad array type");
3023             break;
3024         }
3025         
3026         speculate(BadIndexingType, jsValueValue(cell), 0, isUnexpectedArray(cell));
3027         m_out.jump(continuation);
3028         
3029         m_out.appendTo(continuation, lastNext);
3030     }
3031     
3032     void compilePutStructure()
3033     {
3034         m_ftlState.jitCode->common.notifyCompilingStructureTransition(m_graph.m_plan, codeBlock(), m_node);
3035         
3036         RegisteredStructure oldStructure = m_node->transition()->previous;
3037         RegisteredStructure newStructure = m_node->transition()->next;
3038         ASSERT_UNUSED(oldStructure, oldStructure->indexingType() == newStructure->indexingType());
3039         ASSERT(oldStructure->typeInfo().inlineTypeFlags() == newStructure->typeInfo().inlineTypeFlags());
3040         ASSERT(oldStructure->typeInfo().type() == newStructure->typeInfo().type());
3041
3042         LValue cell = lowCell(m_node->child1()); 
3043         m_out.store32(
3044             weakStructureID(newStructure),
3045             cell, m_heaps.JSCell_structureID);
3046     }
3047     
3048     void compileGetById(AccessType type)
3049     {
3050         ASSERT(type == AccessType::Get || type == AccessType::TryGet || type == AccessType::GetDirect);
3051         switch (m_node->child1().useKind()) {
3052         case CellUse: {
3053             setJSValue(getById(lowCell(m_node->child1()), type));
3054             return;
3055         }
3056             
3057         case UntypedUse: {
3058             // This is pretty weird, since we duplicate the slow path both here and in the
3059             // code generated by the IC. We should investigate making this less bad.
3060             // https://bugs.webkit.org/show_bug.cgi?id=127830
3061             LValue value = lowJSValue(m_node->child1());
3062             
3063             LBasicBlock cellCase = m_out.newBlock();
3064             LBasicBlock notCellCase = m_out.newBlock();
3065             LBasicBlock continuation = m_out.newBlock();
3066             
3067             m_out.branch(
3068                 isCell(value, provenType(m_node->child1())), unsure(cellCase), unsure(notCellCase));
3069             
3070             LBasicBlock lastNext = m_out.appendTo(cellCase, notCellCase);
3071             ValueFromBlock cellResult = m_out.anchor(getById(value, type));
3072             m_out.jump(continuation);
3073
3074             J_JITOperation_EJI getByIdFunction = appropriateGenericGetByIdFunction(type);
3075
3076             m_out.appendTo(notCellCase, continuation);
3077             ValueFromBlock notCellResult = m_out.anchor(vmCall(
3078                 Int64, m_out.operation(getByIdFunction),
3079                 m_callFrame, value,
3080                 m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()])));
3081             m_out.jump(continuation);
3082             
3083             m_out.appendTo(continuation, lastNext);
3084             setJSValue(m_out.phi(Int64, cellResult, notCellResult));
3085             return;
3086         }
3087             
3088         default:
3089             DFG_CRASH(m_graph, m_node, "Bad use kind");
3090             return;
3091         }
3092     }
3093
3094     void compileGetByIdWithThis()
3095     {
3096         if (m_node->child1().useKind() == CellUse && m_node->child2().useKind() == CellUse)
3097             setJSValue(getByIdWithThis(lowCell(m_node->child1()), lowCell(m_node->child2())));
3098         else {
3099             LValue base = lowJSValue(m_node->child1());
3100             LValue thisValue = lowJSValue(m_node->child2());
3101             
3102             LBasicBlock baseCellCase = m_out.newBlock();
3103             LBasicBlock notCellCase = m_out.newBlock();
3104             LBasicBlock thisValueCellCase = m_out.newBlock();
3105             LBasicBlock continuation = m_out.newBlock();
3106             
3107             m_out.branch(
3108                 isCell(base, provenType(m_node->child1())), unsure(baseCellCase), unsure(notCellCase));
3109             
3110             LBasicBlock lastNext = m_out.appendTo(baseCellCase, thisValueCellCase);
3111             
3112             m_out.branch(
3113                 isCell(thisValue, provenType(m_node->child2())), unsure(thisValueCellCase), unsure(notCellCase));
3114             
3115             m_out.appendTo(thisValueCellCase, notCellCase);
3116             ValueFromBlock cellResult = m_out.anchor(getByIdWithThis(base, thisValue));
3117             m_out.jump(continuation);
3118
3119             m_out.appendTo(notCellCase, continuation);
3120             ValueFromBlock notCellResult = m_out.anchor(vmCall(
3121                 Int64, m_out.operation(operationGetByIdWithThisGeneric),
3122                 m_callFrame, base, thisValue,
3123                 m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()])));
3124             m_out.jump(continuation);
3125             
3126             m_out.appendTo(continuation, lastNext);
3127             setJSValue(m_out.phi(Int64, cellResult, notCellResult));
3128         }
3129         
3130     }
3131
3132     void compileGetByValWithThis()
3133     {
3134         LValue base = lowJSValue(m_node->child1());
3135         LValue thisValue = lowJSValue(m_node->child2());
3136         LValue subscript = lowJSValue(m_node->child3());
3137
3138         LValue result = vmCall(Int64, m_out.operation(operationGetByValWithThis), m_callFrame, base, thisValue, subscript);
3139         setJSValue(result);
3140     }
3141
3142     void compilePutByIdWithThis()
3143     {
3144         LValue base = lowJSVal