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