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