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