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