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