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