The GC should be optionally concurrent and disabled by default
[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::GetPure);
627             break;
628         case GetById:
629         case GetByIdFlush:
630             compileGetById(AccessType::Get);
631             break;
632         case GetByIdWithThis:
633             compileGetByIdWithThis();
634             break;
635         case In:
636             compileIn();
637             break;
638         case HasOwnProperty:
639             compileHasOwnProperty();
640             break;
641         case PutById:
642         case PutByIdDirect:
643         case PutByIdFlush:
644             compilePutById();
645             break;
646         case PutByIdWithThis:
647             compilePutByIdWithThis();
648             break;
649         case PutGetterById:
650         case PutSetterById:
651             compilePutAccessorById();
652             break;
653         case PutGetterSetterById:
654             compilePutGetterSetterById();
655             break;
656         case PutGetterByVal:
657         case PutSetterByVal:
658             compilePutAccessorByVal();
659             break;
660         case GetButterfly:
661             compileGetButterfly();
662             break;
663         case ConstantStoragePointer:
664             compileConstantStoragePointer();
665             break;
666         case GetIndexedPropertyStorage:
667             compileGetIndexedPropertyStorage();
668             break;
669         case CheckArray:
670             compileCheckArray();
671             break;
672         case GetArrayLength:
673             compileGetArrayLength();
674             break;
675         case CheckInBounds:
676             compileCheckInBounds();
677             break;
678         case GetByVal:
679             compileGetByVal();
680             break;
681         case GetMyArgumentByVal:
682         case GetMyArgumentByValOutOfBounds:
683             compileGetMyArgumentByVal();
684             break;
685         case GetByValWithThis:
686             compileGetByValWithThis();
687             break;
688         case PutByVal:
689         case PutByValAlias:
690         case PutByValDirect:
691             compilePutByVal();
692             break;
693         case PutByValWithThis:
694             compilePutByValWithThis();
695             break;
696         case DefineDataProperty:
697             compileDefineDataProperty();
698             break;
699         case DefineAccessorProperty:
700             compileDefineAccessorProperty();
701             break;
702         case ArrayPush:
703             compileArrayPush();
704             break;
705         case ArrayPop:
706             compileArrayPop();
707             break;
708         case CreateActivation:
709             compileCreateActivation();
710             break;
711         case NewFunction:
712         case NewGeneratorFunction:
713         case NewAsyncFunction:
714             compileNewFunction();
715             break;
716         case CreateDirectArguments:
717             compileCreateDirectArguments();
718             break;
719         case CreateScopedArguments:
720             compileCreateScopedArguments();
721             break;
722         case CreateClonedArguments:
723             compileCreateClonedArguments();
724             break;
725         case NewObject:
726             compileNewObject();
727             break;
728         case NewArray:
729             compileNewArray();
730             break;
731         case NewArrayWithSpread:
732             compileNewArrayWithSpread();
733             break;
734         case Spread:
735             compileSpread();
736             break;
737         case NewArrayBuffer:
738             compileNewArrayBuffer();
739             break;
740         case NewArrayWithSize:
741             compileNewArrayWithSize();
742             break;
743         case NewTypedArray:
744             compileNewTypedArray();
745             break;
746         case GetTypedArrayByteOffset:
747             compileGetTypedArrayByteOffset();
748             break;
749         case AllocatePropertyStorage:
750             compileAllocatePropertyStorage();
751             break;
752         case ReallocatePropertyStorage:
753             compileReallocatePropertyStorage();
754             break;
755         case ToNumber:
756             compileToNumber();
757             break;
758         case ToString:
759         case CallStringConstructor:
760             compileToStringOrCallStringConstructor();
761             break;
762         case ToPrimitive:
763             compileToPrimitive();
764             break;
765         case MakeRope:
766             compileMakeRope();
767             break;
768         case StringCharAt:
769             compileStringCharAt();
770             break;
771         case StringCharCodeAt:
772             compileStringCharCodeAt();
773             break;
774         case StringFromCharCode:
775             compileStringFromCharCode();
776             break;
777         case GetByOffset:
778         case GetGetterSetterByOffset:
779             compileGetByOffset();
780             break;
781         case GetGetter:
782             compileGetGetter();
783             break;
784         case GetSetter:
785             compileGetSetter();
786             break;
787         case MultiGetByOffset:
788             compileMultiGetByOffset();
789             break;
790         case PutByOffset:
791             compilePutByOffset();
792             break;
793         case MultiPutByOffset:
794             compileMultiPutByOffset();
795             break;
796         case GetGlobalVar:
797         case GetGlobalLexicalVariable:
798             compileGetGlobalVariable();
799             break;
800         case PutGlobalVariable:
801             compilePutGlobalVariable();
802             break;
803         case NotifyWrite:
804             compileNotifyWrite();
805             break;
806         case GetCallee:
807             compileGetCallee();
808             break;
809         case GetArgumentCountIncludingThis:
810             compileGetArgumentCountIncludingThis();
811             break;
812         case GetScope:
813             compileGetScope();
814             break;
815         case SkipScope:
816             compileSkipScope();
817             break;
818         case GetGlobalObject:
819             compileGetGlobalObject();
820             break;
821         case GetClosureVar:
822             compileGetClosureVar();
823             break;
824         case PutClosureVar:
825             compilePutClosureVar();
826             break;
827         case GetFromArguments:
828             compileGetFromArguments();
829             break;
830         case PutToArguments:
831             compilePutToArguments();
832             break;
833         case GetArgument:
834             compileGetArgument();
835             break;
836         case CompareEq:
837             compileCompareEq();
838             break;
839         case CompareStrictEq:
840             compileCompareStrictEq();
841             break;
842         case CompareLess:
843             compileCompareLess();
844             break;
845         case CompareLessEq:
846             compileCompareLessEq();
847             break;
848         case CompareGreater:
849             compileCompareGreater();
850             break;
851         case CompareGreaterEq:
852             compileCompareGreaterEq();
853             break;
854         case CompareEqPtr:
855             compileCompareEqPtr();
856             break;
857         case LogicalNot:
858             compileLogicalNot();
859             break;
860         case Call:
861         case TailCallInlinedCaller:
862         case Construct:
863             compileCallOrConstruct();
864             break;
865         case DirectCall:
866         case DirectTailCallInlinedCaller:
867         case DirectConstruct:
868         case DirectTailCall:
869             compileDirectCallOrConstruct();
870             break;
871         case TailCall:
872             compileTailCall();
873             break;
874         case CallVarargs:
875         case CallForwardVarargs:
876         case TailCallVarargs:
877         case TailCallVarargsInlinedCaller:
878         case TailCallForwardVarargs:
879         case TailCallForwardVarargsInlinedCaller:
880         case ConstructVarargs:
881         case ConstructForwardVarargs:
882             compileCallOrConstructVarargs();
883             break;
884         case CallEval:
885             compileCallEval();
886             break;
887         case LoadVarargs:
888             compileLoadVarargs();
889             break;
890         case ForwardVarargs:
891             compileForwardVarargs();
892             break;
893         case DFG::Jump:
894             compileJump();
895             break;
896         case DFG::Branch:
897             compileBranch();
898             break;
899         case DFG::Switch:
900             compileSwitch();
901             break;
902         case DFG::Return:
903             compileReturn();
904             break;
905         case ForceOSRExit:
906             compileForceOSRExit();
907             break;
908         case Throw:
909         case ThrowStaticError:
910             compileThrow();
911             break;
912         case InvalidationPoint:
913             compileInvalidationPoint();
914             break;
915         case IsEmpty:
916             compileIsEmpty();
917             break;
918         case IsUndefined:
919             compileIsUndefined();
920             break;
921         case IsBoolean:
922             compileIsBoolean();
923             break;
924         case IsNumber:
925             compileIsNumber();
926             break;
927         case IsCellWithType:
928             compileIsCellWithType();
929             break;
930         case MapHash:
931             compileMapHash();
932             break;
933         case GetMapBucket:
934             compileGetMapBucket();
935             break;
936         case LoadFromJSMapBucket:
937             compileLoadFromJSMapBucket();
938             break;
939         case IsNonEmptyMapBucket:
940             compileIsNonEmptyMapBucket();
941             break;
942         case IsObject:
943             compileIsObject();
944             break;
945         case IsObjectOrNull:
946             compileIsObjectOrNull();
947             break;
948         case IsFunction:
949             compileIsFunction();
950             break;
951         case IsTypedArrayView:
952             compileIsTypedArrayView();
953             break;
954         case TypeOf:
955             compileTypeOf();
956             break;
957         case CheckTypeInfoFlags:
958             compileCheckTypeInfoFlags();
959             break;
960         case OverridesHasInstance:
961             compileOverridesHasInstance();
962             break;
963         case InstanceOf:
964             compileInstanceOf();
965             break;
966         case InstanceOfCustom:
967             compileInstanceOfCustom();
968             break;
969         case CountExecution:
970             compileCountExecution();
971             break;
972         case StoreBarrier:
973         case FencedStoreBarrier:
974             compileStoreBarrier();
975             break;
976         case HasIndexedProperty:
977             compileHasIndexedProperty();
978             break;
979         case HasGenericProperty:
980             compileHasGenericProperty();
981             break;
982         case HasStructureProperty:
983             compileHasStructureProperty();
984             break;
985         case GetDirectPname:
986             compileGetDirectPname();
987             break;
988         case GetEnumerableLength:
989             compileGetEnumerableLength();
990             break;
991         case GetPropertyEnumerator:
992             compileGetPropertyEnumerator();
993             break;
994         case GetEnumeratorStructurePname:
995             compileGetEnumeratorStructurePname();
996             break;
997         case GetEnumeratorGenericPname:
998             compileGetEnumeratorGenericPname();
999             break;
1000         case ToIndexString:
1001             compileToIndexString();
1002             break;
1003         case CheckStructureImmediate:
1004             compileCheckStructureImmediate();
1005             break;
1006         case MaterializeNewObject:
1007             compileMaterializeNewObject();
1008             break;
1009         case MaterializeCreateActivation:
1010             compileMaterializeCreateActivation();
1011             break;
1012         case CheckWatchdogTimer:
1013             compileCheckWatchdogTimer();
1014             break;
1015         case CreateRest:
1016             compileCreateRest();
1017             break;
1018         case GetRestLength:
1019             compileGetRestLength();
1020             break;
1021         case RegExpExec:
1022             compileRegExpExec();
1023             break;
1024         case RegExpTest:
1025             compileRegExpTest();
1026             break;
1027         case NewRegexp:
1028             compileNewRegexp();
1029             break;
1030         case SetFunctionName:
1031             compileSetFunctionName();
1032             break;
1033         case StringReplace:
1034         case StringReplaceRegExp:
1035             compileStringReplace();
1036             break;
1037         case GetRegExpObjectLastIndex:
1038             compileGetRegExpObjectLastIndex();
1039             break;
1040         case SetRegExpObjectLastIndex:
1041             compileSetRegExpObjectLastIndex();
1042             break;
1043         case LogShadowChickenPrologue:
1044             compileLogShadowChickenPrologue();
1045             break;
1046         case LogShadowChickenTail:
1047             compileLogShadowChickenTail();
1048             break;
1049         case RecordRegExpCachedResult:
1050             compileRecordRegExpCachedResult();
1051             break;
1052         case ResolveScope:
1053             compileResolveScope();
1054             break;
1055         case GetDynamicVar:
1056             compileGetDynamicVar();
1057             break;
1058         case PutDynamicVar:
1059             compilePutDynamicVar();
1060             break;
1061         case Unreachable:
1062             compileUnreachable();
1063             break;
1064         case ToLowerCase:
1065             compileToLowerCase();
1066             break;
1067         case CheckDOM:
1068             compileCheckDOM();
1069             break;
1070         case CallDOM:
1071             compileCallDOM();
1072             break;
1073         case CallDOMGetter:
1074             compileCallDOMGetter();
1075             break;
1076
1077         case PhantomLocal:
1078         case LoopHint:
1079         case MovHint:
1080         case ZombieHint:
1081         case ExitOK:
1082         case PhantomNewObject:
1083         case PhantomNewFunction:
1084         case PhantomNewGeneratorFunction:
1085         case PhantomNewAsyncFunction:
1086         case PhantomCreateActivation:
1087         case PhantomDirectArguments:
1088         case PhantomCreateRest:
1089         case PhantomClonedArguments:
1090         case PutHint:
1091         case BottomValue:
1092         case KillStack:
1093             break;
1094         default:
1095             DFG_CRASH(m_graph, m_node, "Unrecognized node in FTL backend");
1096             break;
1097         }
1098         
1099         if (m_node->isTerminal())
1100             return false;
1101         
1102         if (!m_state.isValid()) {
1103             safelyInvalidateAfterTermination();
1104             return false;
1105         }
1106
1107         m_availabilityCalculator.executeNode(m_node);
1108         m_interpreter.executeEffects(nodeIndex);
1109         
1110         return true;
1111     }
1112
1113     void compileUpsilon()
1114     {
1115         LValue upsilonValue = nullptr;
1116         switch (m_node->child1().useKind()) {
1117         case DoubleRepUse:
1118             upsilonValue = lowDouble(m_node->child1());
1119             break;
1120         case Int32Use:
1121         case KnownInt32Use:
1122             upsilonValue = lowInt32(m_node->child1());
1123             break;
1124         case Int52RepUse:
1125             upsilonValue = lowInt52(m_node->child1());
1126             break;
1127         case BooleanUse:
1128         case KnownBooleanUse:
1129             upsilonValue = lowBoolean(m_node->child1());
1130             break;
1131         case CellUse:
1132         case KnownCellUse:
1133             upsilonValue = lowCell(m_node->child1());
1134             break;
1135         case UntypedUse:
1136             upsilonValue = lowJSValue(m_node->child1());
1137             break;
1138         default:
1139             DFG_CRASH(m_graph, m_node, "Bad use kind");
1140             break;
1141         }
1142         ValueFromBlock upsilon = m_out.anchor(upsilonValue);
1143         LValue phiNode = m_phis.get(m_node->phi());
1144         m_out.addIncomingToPhi(phiNode, upsilon);
1145     }
1146     
1147     void compilePhi()
1148     {
1149         LValue phi = m_phis.get(m_node);
1150         m_out.m_block->append(phi);
1151
1152         switch (m_node->flags() & NodeResultMask) {
1153         case NodeResultDouble:
1154             setDouble(phi);
1155             break;
1156         case NodeResultInt32:
1157             setInt32(phi);
1158             break;
1159         case NodeResultInt52:
1160             setInt52(phi);
1161             break;
1162         case NodeResultBoolean:
1163             setBoolean(phi);
1164             break;
1165         case NodeResultJS:
1166             setJSValue(phi);
1167             break;
1168         default:
1169             DFG_CRASH(m_graph, m_node, "Bad use kind");
1170             break;
1171         }
1172     }
1173     
1174     void compileDoubleConstant()
1175     {
1176         setDouble(m_out.constDouble(m_node->asNumber()));
1177     }
1178     
1179     void compileInt52Constant()
1180     {
1181         int64_t value = m_node->asAnyInt();
1182         
1183         setInt52(m_out.constInt64(value << JSValue::int52ShiftAmount));
1184         setStrictInt52(m_out.constInt64(value));
1185     }
1186
1187     void compileLazyJSConstant()
1188     {
1189         PatchpointValue* patchpoint = m_out.patchpoint(Int64);
1190         LazyJSValue value = m_node->lazyJSValue();
1191         patchpoint->setGenerator(
1192             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
1193                 value.emit(jit, JSValueRegs(params[0].gpr()));
1194             });
1195         patchpoint->effects = Effects::none();
1196         setJSValue(patchpoint);
1197     }
1198
1199     void compileDoubleRep()
1200     {
1201         switch (m_node->child1().useKind()) {
1202         case RealNumberUse: {
1203             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
1204             
1205             LValue doubleValue = unboxDouble(value);
1206             
1207             LBasicBlock intCase = m_out.newBlock();
1208             LBasicBlock continuation = m_out.newBlock();
1209             
1210             ValueFromBlock fastResult = m_out.anchor(doubleValue);
1211             m_out.branch(
1212                 m_out.doubleEqual(doubleValue, doubleValue),
1213                 usually(continuation), rarely(intCase));
1214             
1215             LBasicBlock lastNext = m_out.appendTo(intCase, continuation);
1216
1217             FTL_TYPE_CHECK(
1218                 jsValueValue(value), m_node->child1(), SpecBytecodeRealNumber,
1219                 isNotInt32(value, provenType(m_node->child1()) & ~SpecDoubleReal));
1220             ValueFromBlock slowResult = m_out.anchor(m_out.intToDouble(unboxInt32(value)));
1221             m_out.jump(continuation);
1222             
1223             m_out.appendTo(continuation, lastNext);
1224             
1225             setDouble(m_out.phi(Double, fastResult, slowResult));
1226             return;
1227         }
1228             
1229         case NotCellUse:
1230         case NumberUse: {
1231             bool shouldConvertNonNumber = m_node->child1().useKind() == NotCellUse;
1232             
1233             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
1234
1235             LBasicBlock intCase = m_out.newBlock();
1236             LBasicBlock doubleTesting = m_out.newBlock();
1237             LBasicBlock doubleCase = m_out.newBlock();
1238             LBasicBlock nonDoubleCase = m_out.newBlock();
1239             LBasicBlock continuation = m_out.newBlock();
1240             
1241             m_out.branch(
1242                 isNotInt32(value, provenType(m_node->child1())),
1243                 unsure(doubleTesting), unsure(intCase));
1244             
1245             LBasicBlock lastNext = m_out.appendTo(intCase, doubleTesting);
1246             
1247             ValueFromBlock intToDouble = m_out.anchor(
1248                 m_out.intToDouble(unboxInt32(value)));
1249             m_out.jump(continuation);
1250             
1251             m_out.appendTo(doubleTesting, doubleCase);
1252             LValue valueIsNumber = isNumber(value, provenType(m_node->child1()));
1253             m_out.branch(valueIsNumber, usually(doubleCase), rarely(nonDoubleCase));
1254
1255             m_out.appendTo(doubleCase, nonDoubleCase);
1256             ValueFromBlock unboxedDouble = m_out.anchor(unboxDouble(value));
1257             m_out.jump(continuation);
1258
1259             if (shouldConvertNonNumber) {
1260                 LBasicBlock undefinedCase = m_out.newBlock();
1261                 LBasicBlock testNullCase = m_out.newBlock();
1262                 LBasicBlock nullCase = m_out.newBlock();
1263                 LBasicBlock testBooleanTrueCase = m_out.newBlock();
1264                 LBasicBlock convertBooleanTrueCase = m_out.newBlock();
1265                 LBasicBlock convertBooleanFalseCase = m_out.newBlock();
1266
1267                 m_out.appendTo(nonDoubleCase, undefinedCase);
1268                 LValue valueIsUndefined = m_out.equal(value, m_out.constInt64(ValueUndefined));
1269                 m_out.branch(valueIsUndefined, unsure(undefinedCase), unsure(testNullCase));
1270
1271                 m_out.appendTo(undefinedCase, testNullCase);
1272                 ValueFromBlock convertedUndefined = m_out.anchor(m_out.constDouble(PNaN));
1273                 m_out.jump(continuation);
1274
1275                 m_out.appendTo(testNullCase, nullCase);
1276                 LValue valueIsNull = m_out.equal(value, m_out.constInt64(ValueNull));
1277                 m_out.branch(valueIsNull, unsure(nullCase), unsure(testBooleanTrueCase));
1278
1279                 m_out.appendTo(nullCase, testBooleanTrueCase);
1280                 ValueFromBlock convertedNull = m_out.anchor(m_out.constDouble(0));
1281                 m_out.jump(continuation);
1282
1283                 m_out.appendTo(testBooleanTrueCase, convertBooleanTrueCase);
1284                 LValue valueIsBooleanTrue = m_out.equal(value, m_out.constInt64(ValueTrue));
1285                 m_out.branch(valueIsBooleanTrue, unsure(convertBooleanTrueCase), unsure(convertBooleanFalseCase));
1286
1287                 m_out.appendTo(convertBooleanTrueCase, convertBooleanFalseCase);
1288                 ValueFromBlock convertedTrue = m_out.anchor(m_out.constDouble(1));
1289                 m_out.jump(continuation);
1290
1291                 m_out.appendTo(convertBooleanFalseCase, continuation);
1292
1293                 LValue valueIsNotBooleanFalse = m_out.notEqual(value, m_out.constInt64(ValueFalse));
1294                 FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), ~SpecCell, valueIsNotBooleanFalse);
1295                 ValueFromBlock convertedFalse = m_out.anchor(m_out.constDouble(0));
1296                 m_out.jump(continuation);
1297
1298                 m_out.appendTo(continuation, lastNext);
1299                 setDouble(m_out.phi(Double, intToDouble, unboxedDouble, convertedUndefined, convertedNull, convertedTrue, convertedFalse));
1300                 return;
1301             }
1302             m_out.appendTo(nonDoubleCase, continuation);
1303             FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), SpecBytecodeNumber, m_out.booleanTrue);
1304             m_out.unreachable();
1305
1306             m_out.appendTo(continuation, lastNext);
1307
1308             setDouble(m_out.phi(Double, intToDouble, unboxedDouble));
1309             return;
1310         }
1311             
1312         case Int52RepUse: {
1313             setDouble(strictInt52ToDouble(lowStrictInt52(m_node->child1())));
1314             return;
1315         }
1316             
1317         default:
1318             DFG_CRASH(m_graph, m_node, "Bad use kind");
1319         }
1320     }
1321
1322     void compileDoubleAsInt32()
1323     {
1324         LValue integerValue = convertDoubleToInt32(lowDouble(m_node->child1()), shouldCheckNegativeZero(m_node->arithMode()));
1325         setInt32(integerValue);
1326     }
1327
1328     void compileValueRep()
1329     {
1330         switch (m_node->child1().useKind()) {
1331         case DoubleRepUse: {
1332             LValue value = lowDouble(m_node->child1());
1333             
1334             if (m_interpreter.needsTypeCheck(m_node->child1(), ~SpecDoubleImpureNaN)) {
1335                 value = m_out.select(
1336                     m_out.doubleEqual(value, value), value, m_out.constDouble(PNaN));
1337             }
1338             
1339             setJSValue(boxDouble(value));
1340             return;
1341         }
1342             
1343         case Int52RepUse: {
1344             setJSValue(strictInt52ToJSValue(lowStrictInt52(m_node->child1())));
1345             return;
1346         }
1347             
1348         default:
1349             DFG_CRASH(m_graph, m_node, "Bad use kind");
1350         }
1351     }
1352     
1353     void compileInt52Rep()
1354     {
1355         switch (m_node->child1().useKind()) {
1356         case Int32Use:
1357             setStrictInt52(m_out.signExt32To64(lowInt32(m_node->child1())));
1358             return;
1359             
1360         case AnyIntUse:
1361             setStrictInt52(
1362                 jsValueToStrictInt52(
1363                     m_node->child1(), lowJSValue(m_node->child1(), ManualOperandSpeculation)));
1364             return;
1365             
1366         case DoubleRepAnyIntUse:
1367             setStrictInt52(
1368                 doubleToStrictInt52(
1369                     m_node->child1(), lowDouble(m_node->child1())));
1370             return;
1371             
1372         default:
1373             RELEASE_ASSERT_NOT_REACHED();
1374         }
1375     }
1376     
1377     void compileValueToInt32()
1378     {
1379         switch (m_node->child1().useKind()) {
1380         case Int52RepUse:
1381             setInt32(m_out.castToInt32(lowStrictInt52(m_node->child1())));
1382             break;
1383             
1384         case DoubleRepUse:
1385             setInt32(doubleToInt32(lowDouble(m_node->child1())));
1386             break;
1387             
1388         case NumberUse:
1389         case NotCellUse: {
1390             LoweredNodeValue value = m_int32Values.get(m_node->child1().node());
1391             if (isValid(value)) {
1392                 setInt32(value.value());
1393                 break;
1394             }
1395             
1396             value = m_jsValueValues.get(m_node->child1().node());
1397             if (isValid(value)) {
1398                 setInt32(numberOrNotCellToInt32(m_node->child1(), value.value()));
1399                 break;
1400             }
1401             
1402             // We'll basically just get here for constants. But it's good to have this
1403             // catch-all since we often add new representations into the mix.
1404             setInt32(
1405                 numberOrNotCellToInt32(
1406                     m_node->child1(),
1407                     lowJSValue(m_node->child1(), ManualOperandSpeculation)));
1408             break;
1409         }
1410             
1411         default:
1412             DFG_CRASH(m_graph, m_node, "Bad use kind");
1413             break;
1414         }
1415     }
1416     
1417     void compileBooleanToNumber()
1418     {
1419         switch (m_node->child1().useKind()) {
1420         case BooleanUse: {
1421             setInt32(m_out.zeroExt(lowBoolean(m_node->child1()), Int32));
1422             return;
1423         }
1424             
1425         case UntypedUse: {
1426             LValue value = lowJSValue(m_node->child1());
1427             
1428             if (!m_interpreter.needsTypeCheck(m_node->child1(), SpecBoolInt32 | SpecBoolean)) {
1429                 setInt32(m_out.bitAnd(m_out.castToInt32(value), m_out.int32One));
1430                 return;
1431             }
1432             
1433             LBasicBlock booleanCase = m_out.newBlock();
1434             LBasicBlock continuation = m_out.newBlock();
1435             
1436             ValueFromBlock notBooleanResult = m_out.anchor(value);
1437             m_out.branch(
1438                 isBoolean(value, provenType(m_node->child1())),
1439                 unsure(booleanCase), unsure(continuation));
1440             
1441             LBasicBlock lastNext = m_out.appendTo(booleanCase, continuation);
1442             ValueFromBlock booleanResult = m_out.anchor(m_out.bitOr(
1443                 m_out.zeroExt(unboxBoolean(value), Int64), m_tagTypeNumber));
1444             m_out.jump(continuation);
1445             
1446             m_out.appendTo(continuation, lastNext);
1447             setJSValue(m_out.phi(Int64, booleanResult, notBooleanResult));
1448             return;
1449         }
1450             
1451         default:
1452             RELEASE_ASSERT_NOT_REACHED();
1453             return;
1454         }
1455     }
1456
1457     void compileExtractOSREntryLocal()
1458     {
1459         EncodedJSValue* buffer = static_cast<EncodedJSValue*>(
1460             m_ftlState.jitCode->ftlForOSREntry()->entryBuffer()->dataBuffer());
1461         setJSValue(m_out.load64(m_out.absolute(buffer + m_node->unlinkedLocal().toLocal())));
1462     }
1463     
1464     void compileGetStack()
1465     {
1466         // GetLocals arise only for captured variables and arguments. For arguments, we might have
1467         // already loaded it.
1468         if (LValue value = m_loadedArgumentValues.get(m_node)) {
1469             setJSValue(value);
1470             return;
1471         }
1472         
1473         StackAccessData* data = m_node->stackAccessData();
1474         AbstractValue& value = m_state.variables().operand(data->local);
1475         
1476         DFG_ASSERT(m_graph, m_node, isConcrete(data->format));
1477         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.
1478         
1479         if (isInt32Speculation(value.m_type))
1480             setInt32(m_out.load32(payloadFor(data->machineLocal)));
1481         else
1482             setJSValue(m_out.load64(addressFor(data->machineLocal)));
1483     }
1484     
1485     void compilePutStack()
1486     {
1487         StackAccessData* data = m_node->stackAccessData();
1488         switch (data->format) {
1489         case FlushedJSValue: {
1490             LValue value = lowJSValue(m_node->child1());
1491             m_out.store64(value, addressFor(data->machineLocal));
1492             break;
1493         }
1494             
1495         case FlushedDouble: {
1496             LValue value = lowDouble(m_node->child1());
1497             m_out.storeDouble(value, addressFor(data->machineLocal));
1498             break;
1499         }
1500             
1501         case FlushedInt32: {
1502             LValue value = lowInt32(m_node->child1());
1503             m_out.store32(value, payloadFor(data->machineLocal));
1504             break;
1505         }
1506             
1507         case FlushedInt52: {
1508             LValue value = lowInt52(m_node->child1());
1509             m_out.store64(value, addressFor(data->machineLocal));
1510             break;
1511         }
1512             
1513         case FlushedCell: {
1514             LValue value = lowCell(m_node->child1());
1515             m_out.store64(value, addressFor(data->machineLocal));
1516             break;
1517         }
1518             
1519         case FlushedBoolean: {
1520             speculateBoolean(m_node->child1());
1521             m_out.store64(
1522                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
1523                 addressFor(data->machineLocal));
1524             break;
1525         }
1526             
1527         default:
1528             DFG_CRASH(m_graph, m_node, "Bad flush format");
1529             break;
1530         }
1531     }
1532     
1533     void compileNoOp()
1534     {
1535         DFG_NODE_DO_TO_CHILDREN(m_graph, m_node, speculate);
1536     }
1537
1538     void compileCallObjectConstructor()
1539     {
1540         JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
1541         LValue value = lowJSValue(m_node->child1());
1542
1543         LBasicBlock isCellCase = m_out.newBlock();
1544         LBasicBlock slowCase = m_out.newBlock();
1545         LBasicBlock continuation = m_out.newBlock();
1546
1547         m_out.branch(isCell(value, provenType(m_node->child1())), usually(isCellCase), rarely(slowCase));
1548
1549         LBasicBlock lastNext = m_out.appendTo(isCellCase, slowCase);
1550         ValueFromBlock fastResult = m_out.anchor(value);
1551         m_out.branch(isObject(value), usually(continuation), rarely(slowCase));
1552
1553         m_out.appendTo(slowCase, continuation);
1554         ValueFromBlock slowResult = m_out.anchor(vmCall(Int64, m_out.operation(operationObjectConstructor), m_callFrame, m_out.constIntPtr(globalObject), value));
1555         m_out.jump(continuation);
1556
1557         m_out.appendTo(continuation, lastNext);
1558         setJSValue(m_out.phi(Int64, fastResult, slowResult));
1559     }
1560     
1561     void compileToThis()
1562     {
1563         LValue value = lowJSValue(m_node->child1());
1564         
1565         LBasicBlock isCellCase = m_out.newBlock();
1566         LBasicBlock slowCase = m_out.newBlock();
1567         LBasicBlock continuation = m_out.newBlock();
1568         
1569         m_out.branch(
1570             isCell(value, provenType(m_node->child1())), usually(isCellCase), rarely(slowCase));
1571         
1572         LBasicBlock lastNext = m_out.appendTo(isCellCase, slowCase);
1573         ValueFromBlock fastResult = m_out.anchor(value);
1574         m_out.branch(
1575             m_out.testIsZero32(
1576                 m_out.load8ZeroExt32(value, m_heaps.JSCell_typeInfoFlags),
1577                 m_out.constInt32(OverridesToThis)),
1578             usually(continuation), rarely(slowCase));
1579         
1580         m_out.appendTo(slowCase, continuation);
1581         J_JITOperation_EJ function;
1582         if (m_graph.isStrictModeFor(m_node->origin.semantic))
1583             function = operationToThisStrict;
1584         else
1585             function = operationToThis;
1586         ValueFromBlock slowResult = m_out.anchor(
1587             vmCall(Int64, m_out.operation(function), m_callFrame, value));
1588         m_out.jump(continuation);
1589         
1590         m_out.appendTo(continuation, lastNext);
1591         setJSValue(m_out.phi(Int64, fastResult, slowResult));
1592     }
1593
1594     void compileValueAdd()
1595     {
1596         ArithProfile* arithProfile = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic)->arithProfileForBytecodeOffset(m_node->origin.semantic.bytecodeIndex);
1597         JITAddIC* addIC = codeBlock()->addJITAddIC(arithProfile);
1598         auto repatchingFunction = operationValueAddOptimize;
1599         auto nonRepatchingFunction = operationValueAdd;
1600         compileMathIC(addIC, repatchingFunction, nonRepatchingFunction);
1601     }
1602
1603     template <typename Generator>
1604     void compileMathIC(JITUnaryMathIC<Generator>* mathIC, FunctionPtr repatchingFunction, FunctionPtr nonRepatchingFunction)
1605     {
1606         Node* node = m_node;
1607
1608         LValue operand = lowJSValue(node->child1());
1609
1610         PatchpointValue* patchpoint = m_out.patchpoint(Int64);
1611         patchpoint->appendSomeRegister(operand);
1612         patchpoint->append(m_tagMask, ValueRep::lateReg(GPRInfo::tagMaskRegister));
1613         patchpoint->append(m_tagTypeNumber, ValueRep::lateReg(GPRInfo::tagTypeNumberRegister));
1614         RefPtr<PatchpointExceptionHandle> exceptionHandle = preparePatchpointForExceptions(patchpoint);
1615         patchpoint->numGPScratchRegisters = 1;
1616         patchpoint->clobber(RegisterSet::macroScratchRegisters());
1617         State* state = &m_ftlState;
1618         patchpoint->setGenerator(
1619             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
1620                 AllowMacroScratchRegisterUsage allowScratch(jit);
1621
1622                 Box<CCallHelpers::JumpList> exceptions =
1623                     exceptionHandle->scheduleExitCreation(params)->jumps(jit);
1624
1625 #if ENABLE(MATH_IC_STATS)
1626                 auto inlineStart = jit.label();
1627 #endif
1628
1629                 Box<MathICGenerationState> mathICGenerationState = Box<MathICGenerationState>::create();
1630                 mathIC->m_generator = Generator(JSValueRegs(params[0].gpr()), JSValueRegs(params[1].gpr()), params.gpScratch(0));
1631
1632                 bool shouldEmitProfiling = false;
1633                 bool generatedInline = mathIC->generateInline(jit, *mathICGenerationState, shouldEmitProfiling);
1634
1635                 if (generatedInline) {
1636                     ASSERT(!mathICGenerationState->slowPathJumps.empty());
1637                     auto done = jit.label();
1638                     params.addLatePath([=] (CCallHelpers& jit) {
1639                         AllowMacroScratchRegisterUsage allowScratch(jit);
1640                         mathICGenerationState->slowPathJumps.link(&jit);
1641                         mathICGenerationState->slowPathStart = jit.label();
1642 #if ENABLE(MATH_IC_STATS)
1643                         auto slowPathStart = jit.label();
1644 #endif
1645
1646                         if (mathICGenerationState->shouldSlowPathRepatch) {
1647                             SlowPathCall call = callOperation(*state, params.unavailableRegisters(), jit, node->origin.semantic, exceptions.get(),
1648                                 repatchingFunction, params[0].gpr(), params[1].gpr(), CCallHelpers::TrustedImmPtr(mathIC));
1649                             mathICGenerationState->slowPathCall = call.call();
1650                         } else {
1651                             SlowPathCall call = callOperation(*state, params.unavailableRegisters(), jit, node->origin.semantic,
1652                                 exceptions.get(), nonRepatchingFunction, params[0].gpr(), params[1].gpr());
1653                             mathICGenerationState->slowPathCall = call.call();
1654                         }
1655                         jit.jump().linkTo(done, &jit);
1656
1657                         jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1658                             mathIC->finalizeInlineCode(*mathICGenerationState, linkBuffer);
1659                         });
1660
1661 #if ENABLE(MATH_IC_STATS)
1662                         auto slowPathEnd = jit.label();
1663                         jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1664                             size_t size = static_cast<char*>(linkBuffer.locationOf(slowPathEnd).executableAddress()) - static_cast<char*>(linkBuffer.locationOf(slowPathStart).executableAddress());
1665                             mathIC->m_generatedCodeSize += size;
1666                         });
1667 #endif
1668                     });
1669                 } else {
1670                     callOperation(
1671                         *state, params.unavailableRegisters(), jit, node->origin.semantic, exceptions.get(),
1672                         nonRepatchingFunction, params[0].gpr(), params[1].gpr());
1673                 }
1674
1675 #if ENABLE(MATH_IC_STATS)
1676                 auto inlineEnd = jit.label();
1677                 jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1678                     size_t size = static_cast<char*>(linkBuffer.locationOf(inlineEnd).executableAddress()) - static_cast<char*>(linkBuffer.locationOf(inlineStart).executableAddress());
1679                     mathIC->m_generatedCodeSize += size;
1680                 });
1681 #endif
1682             });
1683
1684         setJSValue(patchpoint);
1685     }
1686
1687     template <typename Generator>
1688     void compileMathIC(JITBinaryMathIC<Generator>* mathIC, FunctionPtr repatchingFunction, FunctionPtr nonRepatchingFunction)
1689     {
1690         Node* node = m_node;
1691         
1692         LValue left = lowJSValue(node->child1());
1693         LValue right = lowJSValue(node->child2());
1694
1695         SnippetOperand leftOperand(m_state.forNode(node->child1()).resultType());
1696         SnippetOperand rightOperand(m_state.forNode(node->child2()).resultType());
1697             
1698         PatchpointValue* patchpoint = m_out.patchpoint(Int64);
1699         patchpoint->appendSomeRegister(left);
1700         patchpoint->appendSomeRegister(right);
1701         patchpoint->append(m_tagMask, ValueRep::lateReg(GPRInfo::tagMaskRegister));
1702         patchpoint->append(m_tagTypeNumber, ValueRep::lateReg(GPRInfo::tagTypeNumberRegister));
1703         RefPtr<PatchpointExceptionHandle> exceptionHandle =
1704             preparePatchpointForExceptions(patchpoint);
1705         patchpoint->numGPScratchRegisters = 1;
1706         patchpoint->numFPScratchRegisters = 2;
1707         patchpoint->clobber(RegisterSet::macroScratchRegisters());
1708         State* state = &m_ftlState;
1709         patchpoint->setGenerator(
1710             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
1711                 AllowMacroScratchRegisterUsage allowScratch(jit);
1712
1713                 Box<CCallHelpers::JumpList> exceptions =
1714                     exceptionHandle->scheduleExitCreation(params)->jumps(jit);
1715
1716 #if ENABLE(MATH_IC_STATS)
1717                 auto inlineStart = jit.label();
1718 #endif
1719
1720                 Box<MathICGenerationState> mathICGenerationState = Box<MathICGenerationState>::create();
1721                 mathIC->m_generator = Generator(leftOperand, rightOperand, JSValueRegs(params[0].gpr()),
1722                     JSValueRegs(params[1].gpr()), JSValueRegs(params[2].gpr()), params.fpScratch(0),
1723                     params.fpScratch(1), params.gpScratch(0), InvalidFPRReg);
1724
1725                 bool shouldEmitProfiling = false;
1726                 bool generatedInline = mathIC->generateInline(jit, *mathICGenerationState, shouldEmitProfiling);
1727
1728                 if (generatedInline) {
1729                     ASSERT(!mathICGenerationState->slowPathJumps.empty());
1730                     auto done = jit.label();
1731                     params.addLatePath([=] (CCallHelpers& jit) {
1732                         AllowMacroScratchRegisterUsage allowScratch(jit);
1733                         mathICGenerationState->slowPathJumps.link(&jit);
1734                         mathICGenerationState->slowPathStart = jit.label();
1735 #if ENABLE(MATH_IC_STATS)
1736                         auto slowPathStart = jit.label();
1737 #endif
1738
1739                         if (mathICGenerationState->shouldSlowPathRepatch) {
1740                             SlowPathCall call = callOperation(*state, params.unavailableRegisters(), jit, node->origin.semantic, exceptions.get(),
1741                                 repatchingFunction, params[0].gpr(), params[1].gpr(), params[2].gpr(), CCallHelpers::TrustedImmPtr(mathIC));
1742                             mathICGenerationState->slowPathCall = call.call();
1743                         } else {
1744                             SlowPathCall call = callOperation(*state, params.unavailableRegisters(), jit, node->origin.semantic,
1745                                 exceptions.get(), nonRepatchingFunction, params[0].gpr(), params[1].gpr(), params[2].gpr());
1746                             mathICGenerationState->slowPathCall = call.call();
1747                         }
1748                         jit.jump().linkTo(done, &jit);
1749
1750                         jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1751                             mathIC->finalizeInlineCode(*mathICGenerationState, linkBuffer);
1752                         });
1753
1754 #if ENABLE(MATH_IC_STATS)
1755                         auto slowPathEnd = jit.label();
1756                         jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1757                             size_t size = static_cast<char*>(linkBuffer.locationOf(slowPathEnd).executableAddress()) - static_cast<char*>(linkBuffer.locationOf(slowPathStart).executableAddress());
1758                             mathIC->m_generatedCodeSize += size;
1759                         });
1760 #endif
1761                     });
1762                 } else {
1763                     callOperation(
1764                         *state, params.unavailableRegisters(), jit, node->origin.semantic, exceptions.get(),
1765                         nonRepatchingFunction, params[0].gpr(), params[1].gpr(), params[2].gpr());
1766                 }
1767
1768 #if ENABLE(MATH_IC_STATS)
1769                 auto inlineEnd = jit.label();
1770                 jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1771                     size_t size = static_cast<char*>(linkBuffer.locationOf(inlineEnd).executableAddress()) - static_cast<char*>(linkBuffer.locationOf(inlineStart).executableAddress());
1772                     mathIC->m_generatedCodeSize += size;
1773                 });
1774 #endif
1775             });
1776
1777         setJSValue(patchpoint);
1778     }
1779     
1780     void compileStrCat()
1781     {
1782         LValue result;
1783         if (m_node->child3()) {
1784             result = vmCall(
1785                 Int64, m_out.operation(operationStrCat3), m_callFrame,
1786                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
1787                 lowJSValue(m_node->child2(), ManualOperandSpeculation),
1788                 lowJSValue(m_node->child3(), ManualOperandSpeculation));
1789         } else {
1790             result = vmCall(
1791                 Int64, m_out.operation(operationStrCat2), m_callFrame,
1792                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
1793                 lowJSValue(m_node->child2(), ManualOperandSpeculation));
1794         }
1795         setJSValue(result);
1796     }
1797     
1798     void compileArithAddOrSub()
1799     {
1800         bool isSub =  m_node->op() == ArithSub;
1801         switch (m_node->binaryUseKind()) {
1802         case Int32Use: {
1803             LValue left = lowInt32(m_node->child1());
1804             LValue right = lowInt32(m_node->child2());
1805
1806             if (!shouldCheckOverflow(m_node->arithMode())) {
1807                 setInt32(isSub ? m_out.sub(left, right) : m_out.add(left, right));
1808                 break;
1809             }
1810
1811             CheckValue* result =
1812                 isSub ? m_out.speculateSub(left, right) : m_out.speculateAdd(left, right);
1813             blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);
1814             setInt32(result);
1815             break;
1816         }
1817             
1818         case Int52RepUse: {
1819             if (!abstractValue(m_node->child1()).couldBeType(SpecInt52Only)
1820                 && !abstractValue(m_node->child2()).couldBeType(SpecInt52Only)) {
1821                 Int52Kind kind;
1822                 LValue left = lowWhicheverInt52(m_node->child1(), kind);
1823                 LValue right = lowInt52(m_node->child2(), kind);
1824                 setInt52(isSub ? m_out.sub(left, right) : m_out.add(left, right), kind);
1825                 break;
1826             }
1827
1828             LValue left = lowInt52(m_node->child1());
1829             LValue right = lowInt52(m_node->child2());
1830             CheckValue* result =
1831                 isSub ? m_out.speculateSub(left, right) : m_out.speculateAdd(left, right);
1832             blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);
1833             setInt52(result);
1834             break;
1835         }
1836             
1837         case DoubleRepUse: {
1838             LValue C1 = lowDouble(m_node->child1());
1839             LValue C2 = lowDouble(m_node->child2());
1840
1841             setDouble(isSub ? m_out.doubleSub(C1, C2) : m_out.doubleAdd(C1, C2));
1842             break;
1843         }
1844
1845         case UntypedUse: {
1846             if (!isSub) {
1847                 DFG_CRASH(m_graph, m_node, "Bad use kind");
1848                 break;
1849             }
1850
1851             ArithProfile* arithProfile = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic)->arithProfileForBytecodeOffset(m_node->origin.semantic.bytecodeIndex);
1852             JITSubIC* subIC = codeBlock()->addJITSubIC(arithProfile);
1853             auto repatchingFunction = operationValueSubOptimize;
1854             auto nonRepatchingFunction = operationValueSub;
1855             compileMathIC(subIC, repatchingFunction, nonRepatchingFunction);
1856             break;
1857         }
1858
1859         default:
1860             DFG_CRASH(m_graph, m_node, "Bad use kind");
1861             break;
1862         }
1863     }
1864
1865     void compileArithClz32()
1866     {
1867         if (m_node->child1().useKind() == Int32Use || m_node->child1().useKind() == KnownInt32Use) {
1868             LValue operand = lowInt32(m_node->child1());
1869             setInt32(m_out.ctlz32(operand));
1870             return;
1871         }
1872         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
1873         LValue argument = lowJSValue(m_node->child1());
1874         LValue result = vmCall(Int32, m_out.operation(operationArithClz32), m_callFrame, argument);
1875         setInt32(result);
1876     }
1877     
1878     void compileArithMul()
1879     {
1880         switch (m_node->binaryUseKind()) {
1881         case Int32Use: {
1882             LValue left = lowInt32(m_node->child1());
1883             LValue right = lowInt32(m_node->child2());
1884             
1885             LValue result;
1886
1887             if (!shouldCheckOverflow(m_node->arithMode()))
1888                 result = m_out.mul(left, right);
1889             else {
1890                 CheckValue* speculation = m_out.speculateMul(left, right);
1891                 blessSpeculation(speculation, Overflow, noValue(), nullptr, m_origin);
1892                 result = speculation;
1893             }
1894             
1895             if (shouldCheckNegativeZero(m_node->arithMode())) {
1896                 LBasicBlock slowCase = m_out.newBlock();
1897                 LBasicBlock continuation = m_out.newBlock();
1898                 
1899                 m_out.branch(
1900                     m_out.notZero32(result), usually(continuation), rarely(slowCase));
1901                 
1902                 LBasicBlock lastNext = m_out.appendTo(slowCase, continuation);
1903                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(left, m_out.int32Zero));
1904                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(right, m_out.int32Zero));
1905                 m_out.jump(continuation);
1906                 m_out.appendTo(continuation, lastNext);
1907             }
1908             
1909             setInt32(result);
1910             break;
1911         }
1912             
1913         case Int52RepUse: {
1914             Int52Kind kind;
1915             LValue left = lowWhicheverInt52(m_node->child1(), kind);
1916             LValue right = lowInt52(m_node->child2(), opposite(kind));
1917
1918             CheckValue* result = m_out.speculateMul(left, right);
1919             blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);
1920
1921             if (shouldCheckNegativeZero(m_node->arithMode())) {
1922                 LBasicBlock slowCase = m_out.newBlock();
1923                 LBasicBlock continuation = m_out.newBlock();
1924                 
1925                 m_out.branch(
1926                     m_out.notZero64(result), usually(continuation), rarely(slowCase));
1927                 
1928                 LBasicBlock lastNext = m_out.appendTo(slowCase, continuation);
1929                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(left, m_out.int64Zero));
1930                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(right, m_out.int64Zero));
1931                 m_out.jump(continuation);
1932                 m_out.appendTo(continuation, lastNext);
1933             }
1934             
1935             setInt52(result);
1936             break;
1937         }
1938             
1939         case DoubleRepUse: {
1940             setDouble(
1941                 m_out.doubleMul(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
1942             break;
1943         }
1944
1945         case UntypedUse: {
1946             ArithProfile* arithProfile = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic)->arithProfileForBytecodeOffset(m_node->origin.semantic.bytecodeIndex);
1947             JITMulIC* mulIC = codeBlock()->addJITMulIC(arithProfile);
1948             auto repatchingFunction = operationValueMulOptimize;
1949             auto nonRepatchingFunction = operationValueMul;
1950             compileMathIC(mulIC, repatchingFunction, nonRepatchingFunction);
1951             break;
1952         }
1953
1954         default:
1955             DFG_CRASH(m_graph, m_node, "Bad use kind");
1956             break;
1957         }
1958     }
1959
1960     void compileArithDiv()
1961     {
1962         switch (m_node->binaryUseKind()) {
1963         case Int32Use: {
1964             LValue numerator = lowInt32(m_node->child1());
1965             LValue denominator = lowInt32(m_node->child2());
1966
1967             if (shouldCheckNegativeZero(m_node->arithMode())) {
1968                 LBasicBlock zeroNumerator = m_out.newBlock();
1969                 LBasicBlock numeratorContinuation = m_out.newBlock();
1970
1971                 m_out.branch(
1972                     m_out.isZero32(numerator),
1973                     rarely(zeroNumerator), usually(numeratorContinuation));
1974
1975                 LBasicBlock innerLastNext = m_out.appendTo(zeroNumerator, numeratorContinuation);
1976
1977                 speculate(
1978                     NegativeZero, noValue(), 0, m_out.lessThan(denominator, m_out.int32Zero));
1979
1980                 m_out.jump(numeratorContinuation);
1981
1982                 m_out.appendTo(numeratorContinuation, innerLastNext);
1983             }
1984             
1985             if (shouldCheckOverflow(m_node->arithMode())) {
1986                 LBasicBlock unsafeDenominator = m_out.newBlock();
1987                 LBasicBlock continuation = m_out.newBlock();
1988
1989                 LValue adjustedDenominator = m_out.add(denominator, m_out.int32One);
1990                 m_out.branch(
1991                     m_out.above(adjustedDenominator, m_out.int32One),
1992                     usually(continuation), rarely(unsafeDenominator));
1993
1994                 LBasicBlock lastNext = m_out.appendTo(unsafeDenominator, continuation);
1995                 LValue neg2ToThe31 = m_out.constInt32(-2147483647-1);
1996                 speculate(Overflow, noValue(), nullptr, m_out.isZero32(denominator));
1997                 speculate(Overflow, noValue(), nullptr, m_out.equal(numerator, neg2ToThe31));
1998                 m_out.jump(continuation);
1999
2000                 m_out.appendTo(continuation, lastNext);
2001                 LValue result = m_out.div(numerator, denominator);
2002                 speculate(
2003                     Overflow, noValue(), 0,
2004                     m_out.notEqual(m_out.mul(result, denominator), numerator));
2005                 setInt32(result);
2006             } else
2007                 setInt32(m_out.chillDiv(numerator, denominator));
2008
2009             break;
2010         }
2011             
2012         case DoubleRepUse: {
2013             setDouble(m_out.doubleDiv(
2014                 lowDouble(m_node->child1()), lowDouble(m_node->child2())));
2015             break;
2016         }
2017
2018         case UntypedUse: {
2019             emitBinarySnippet<JITDivGenerator, NeedScratchFPR>(operationValueDiv);
2020             break;
2021         }
2022
2023         default:
2024             DFG_CRASH(m_graph, m_node, "Bad use kind");
2025             break;
2026         }
2027     }
2028     
2029     void compileArithMod()
2030     {
2031         switch (m_node->binaryUseKind()) {
2032         case Int32Use: {
2033             LValue numerator = lowInt32(m_node->child1());
2034             LValue denominator = lowInt32(m_node->child2());
2035
2036             LValue remainder;
2037             if (shouldCheckOverflow(m_node->arithMode())) {
2038                 LBasicBlock unsafeDenominator = m_out.newBlock();
2039                 LBasicBlock continuation = m_out.newBlock();
2040
2041                 LValue adjustedDenominator = m_out.add(denominator, m_out.int32One);
2042                 m_out.branch(
2043                     m_out.above(adjustedDenominator, m_out.int32One),
2044                     usually(continuation), rarely(unsafeDenominator));
2045
2046                 LBasicBlock lastNext = m_out.appendTo(unsafeDenominator, continuation);
2047                 LValue neg2ToThe31 = m_out.constInt32(-2147483647-1);
2048                 speculate(Overflow, noValue(), nullptr, m_out.isZero32(denominator));
2049                 speculate(Overflow, noValue(), nullptr, m_out.equal(numerator, neg2ToThe31));
2050                 m_out.jump(continuation);
2051
2052                 m_out.appendTo(continuation, lastNext);
2053                 LValue result = m_out.mod(numerator, denominator);
2054                 remainder = result;
2055             } else
2056                 remainder = m_out.chillMod(numerator, denominator);
2057
2058             if (shouldCheckNegativeZero(m_node->arithMode())) {
2059                 LBasicBlock negativeNumerator = m_out.newBlock();
2060                 LBasicBlock numeratorContinuation = m_out.newBlock();
2061
2062                 m_out.branch(
2063                     m_out.lessThan(numerator, m_out.int32Zero),
2064                     unsure(negativeNumerator), unsure(numeratorContinuation));
2065
2066                 LBasicBlock innerLastNext = m_out.appendTo(negativeNumerator, numeratorContinuation);
2067
2068                 speculate(NegativeZero, noValue(), 0, m_out.isZero32(remainder));
2069
2070                 m_out.jump(numeratorContinuation);
2071
2072                 m_out.appendTo(numeratorContinuation, innerLastNext);
2073             }
2074
2075             setInt32(remainder);
2076             break;
2077         }
2078             
2079         case DoubleRepUse: {
2080             setDouble(
2081                 m_out.doubleMod(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
2082             break;
2083         }
2084             
2085         default:
2086             DFG_CRASH(m_graph, m_node, "Bad use kind");
2087             break;
2088         }
2089     }
2090
2091     void compileArithMinOrMax()
2092     {
2093         switch (m_node->binaryUseKind()) {
2094         case Int32Use: {
2095             LValue left = lowInt32(m_node->child1());
2096             LValue right = lowInt32(m_node->child2());
2097             
2098             setInt32(
2099                 m_out.select(
2100                     m_node->op() == ArithMin
2101                         ? m_out.lessThan(left, right)
2102                         : m_out.lessThan(right, left),
2103                     left, right));
2104             break;
2105         }
2106             
2107         case DoubleRepUse: {
2108             LValue left = lowDouble(m_node->child1());
2109             LValue right = lowDouble(m_node->child2());
2110             
2111             LBasicBlock notLessThan = m_out.newBlock();
2112             LBasicBlock continuation = m_out.newBlock();
2113             
2114             Vector<ValueFromBlock, 2> results;
2115             
2116             results.append(m_out.anchor(left));
2117             m_out.branch(
2118                 m_node->op() == ArithMin
2119                     ? m_out.doubleLessThan(left, right)
2120                     : m_out.doubleGreaterThan(left, right),
2121                 unsure(continuation), unsure(notLessThan));
2122             
2123             LBasicBlock lastNext = m_out.appendTo(notLessThan, continuation);
2124             results.append(m_out.anchor(m_out.select(
2125                 m_node->op() == ArithMin
2126                     ? m_out.doubleGreaterThanOrEqual(left, right)
2127                     : m_out.doubleLessThanOrEqual(left, right),
2128                 right, m_out.constDouble(PNaN))));
2129             m_out.jump(continuation);
2130             
2131             m_out.appendTo(continuation, lastNext);
2132             setDouble(m_out.phi(Double, results));
2133             break;
2134         }
2135             
2136         default:
2137             DFG_CRASH(m_graph, m_node, "Bad use kind");
2138             break;
2139         }
2140     }
2141     
2142     void compileArithAbs()
2143     {
2144         switch (m_node->child1().useKind()) {
2145         case Int32Use: {
2146             LValue value = lowInt32(m_node->child1());
2147
2148             LValue mask = m_out.aShr(value, m_out.constInt32(31));
2149             LValue result = m_out.bitXor(mask, m_out.add(mask, value));
2150
2151             if (shouldCheckOverflow(m_node->arithMode()))
2152                 speculate(Overflow, noValue(), 0, m_out.lessThan(result, m_out.int32Zero));
2153
2154             setInt32(result);
2155             break;
2156         }
2157             
2158         case DoubleRepUse: {
2159             setDouble(m_out.doubleAbs(lowDouble(m_node->child1())));
2160             break;
2161         }
2162             
2163         default: {
2164             DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
2165             LValue argument = lowJSValue(m_node->child1());
2166             LValue result = vmCall(Double, m_out.operation(operationArithAbs), m_callFrame, argument);
2167             setDouble(result);
2168             break;
2169         }
2170         }
2171     }
2172
2173     void compileArithSin()
2174     {
2175         if (m_node->child1().useKind() == DoubleRepUse) {
2176             setDouble(m_out.doubleSin(lowDouble(m_node->child1())));
2177             return;
2178         }
2179         LValue argument = lowJSValue(m_node->child1());
2180         LValue result = vmCall(Double, m_out.operation(operationArithSin), m_callFrame, argument);
2181         setDouble(result);
2182     }
2183
2184     void compileArithCos()
2185     {
2186         if (m_node->child1().useKind() == DoubleRepUse) {
2187             setDouble(m_out.doubleCos(lowDouble(m_node->child1())));
2188             return;
2189         }
2190         LValue argument = lowJSValue(m_node->child1());
2191         LValue result = vmCall(Double, m_out.operation(operationArithCos), m_callFrame, argument);
2192         setDouble(result);
2193     }
2194
2195     void compileArithTan()
2196     {
2197         if (m_node->child1().useKind() == DoubleRepUse) {
2198             setDouble(m_out.doubleTan(lowDouble(m_node->child1())));
2199             return;
2200         }
2201         LValue argument = lowJSValue(m_node->child1());
2202         LValue result = vmCall(Double, m_out.operation(operationArithTan), m_callFrame, argument);
2203         setDouble(result);
2204     }
2205
2206     void compileArithPow()
2207     {
2208         if (m_node->child2().useKind() == Int32Use)
2209             setDouble(m_out.doublePowi(lowDouble(m_node->child1()), lowInt32(m_node->child2())));
2210         else {
2211             LValue base = lowDouble(m_node->child1());
2212             LValue exponent = lowDouble(m_node->child2());
2213
2214             LBasicBlock integerExponentIsSmallBlock = m_out.newBlock();
2215             LBasicBlock integerExponentPowBlock = m_out.newBlock();
2216             LBasicBlock doubleExponentPowBlockEntry = m_out.newBlock();
2217             LBasicBlock nanExceptionBaseIsOne = m_out.newBlock();
2218             LBasicBlock nanExceptionExponentIsInfinity = m_out.newBlock();
2219             LBasicBlock testExponentIsOneHalf = m_out.newBlock();
2220             LBasicBlock handleBaseZeroExponentIsOneHalf = m_out.newBlock();
2221             LBasicBlock handleInfinityForExponentIsOneHalf = m_out.newBlock();
2222             LBasicBlock exponentIsOneHalfNormal = m_out.newBlock();
2223             LBasicBlock exponentIsOneHalfInfinity = m_out.newBlock();
2224             LBasicBlock testExponentIsNegativeOneHalf = m_out.newBlock();
2225             LBasicBlock testBaseZeroExponentIsNegativeOneHalf = m_out.newBlock();
2226             LBasicBlock handleBaseZeroExponentIsNegativeOneHalf = m_out.newBlock();
2227             LBasicBlock handleInfinityForExponentIsNegativeOneHalf = m_out.newBlock();
2228             LBasicBlock exponentIsNegativeOneHalfNormal = m_out.newBlock();
2229             LBasicBlock exponentIsNegativeOneHalfInfinity = m_out.newBlock();
2230             LBasicBlock powBlock = m_out.newBlock();
2231             LBasicBlock nanExceptionResultIsNaN = m_out.newBlock();
2232             LBasicBlock continuation = m_out.newBlock();
2233
2234             LValue integerExponent = m_out.doubleToInt(exponent);
2235             LValue integerExponentConvertedToDouble = m_out.intToDouble(integerExponent);
2236             LValue exponentIsInteger = m_out.doubleEqual(exponent, integerExponentConvertedToDouble);
2237             m_out.branch(exponentIsInteger, unsure(integerExponentIsSmallBlock), unsure(doubleExponentPowBlockEntry));
2238
2239             LBasicBlock lastNext = m_out.appendTo(integerExponentIsSmallBlock, integerExponentPowBlock);
2240             LValue integerExponentBelowMax = m_out.belowOrEqual(integerExponent, m_out.constInt32(maxExponentForIntegerMathPow));
2241             m_out.branch(integerExponentBelowMax, usually(integerExponentPowBlock), rarely(doubleExponentPowBlockEntry));
2242
2243             m_out.appendTo(integerExponentPowBlock, doubleExponentPowBlockEntry);
2244             ValueFromBlock powDoubleIntResult = m_out.anchor(m_out.doublePowi(base, integerExponent));
2245             m_out.jump(continuation);
2246
2247             // If y is NaN, the result is NaN.
2248             m_out.appendTo(doubleExponentPowBlockEntry, nanExceptionBaseIsOne);
2249             LValue exponentIsNaN;
2250             if (provenType(m_node->child2()) & SpecDoubleNaN)
2251                 exponentIsNaN = m_out.doubleNotEqualOrUnordered(exponent, exponent);
2252             else
2253                 exponentIsNaN = m_out.booleanFalse;
2254             m_out.branch(exponentIsNaN, rarely(nanExceptionResultIsNaN), usually(nanExceptionBaseIsOne));
2255
2256             // If abs(x) is 1 and y is +infinity, the result is NaN.
2257             // If abs(x) is 1 and y is -infinity, the result is NaN.
2258
2259             //     Test if base == 1.
2260             m_out.appendTo(nanExceptionBaseIsOne, nanExceptionExponentIsInfinity);
2261             LValue absoluteBase = m_out.doubleAbs(base);
2262             LValue absoluteBaseIsOne = m_out.doubleEqual(absoluteBase, m_out.constDouble(1));
2263             m_out.branch(absoluteBaseIsOne, rarely(nanExceptionExponentIsInfinity), usually(testExponentIsOneHalf));
2264
2265             //     Test if abs(y) == Infinity.
2266             m_out.appendTo(nanExceptionExponentIsInfinity, testExponentIsOneHalf);
2267             LValue absoluteExponent = m_out.doubleAbs(exponent);
2268             LValue absoluteExponentIsInfinity = m_out.doubleEqual(absoluteExponent, m_out.constDouble(std::numeric_limits<double>::infinity()));
2269             m_out.branch(absoluteExponentIsInfinity, rarely(nanExceptionResultIsNaN), usually(testExponentIsOneHalf));
2270
2271             // If y == 0.5 or y == -0.5, handle it through SQRT.
2272             // We have be carefuly with -0 and -Infinity.
2273
2274             //     Test if y == 0.5
2275             m_out.appendTo(testExponentIsOneHalf, handleBaseZeroExponentIsOneHalf);
2276             LValue exponentIsOneHalf = m_out.doubleEqual(exponent, m_out.constDouble(0.5));
2277             m_out.branch(exponentIsOneHalf, rarely(handleBaseZeroExponentIsOneHalf), usually(testExponentIsNegativeOneHalf));
2278
2279             //     Handle x == -0.
2280             m_out.appendTo(handleBaseZeroExponentIsOneHalf, handleInfinityForExponentIsOneHalf);
2281             LValue baseIsZeroExponentIsOneHalf = m_out.doubleEqual(base, m_out.doubleZero);
2282             ValueFromBlock zeroResultExponentIsOneHalf = m_out.anchor(m_out.doubleZero);
2283             m_out.branch(baseIsZeroExponentIsOneHalf, rarely(continuation), usually(handleInfinityForExponentIsOneHalf));
2284
2285             //     Test if abs(x) == Infinity.
2286             m_out.appendTo(handleInfinityForExponentIsOneHalf, exponentIsOneHalfNormal);
2287             LValue absoluteBaseIsInfinityOneHalf = m_out.doubleEqual(absoluteBase, m_out.constDouble(std::numeric_limits<double>::infinity()));
2288             m_out.branch(absoluteBaseIsInfinityOneHalf, rarely(exponentIsOneHalfInfinity), usually(exponentIsOneHalfNormal));
2289
2290             //     The exponent is 0.5, the base is finite or NaN, we can use SQRT.
2291             m_out.appendTo(exponentIsOneHalfNormal, exponentIsOneHalfInfinity);
2292             ValueFromBlock sqrtResult = m_out.anchor(m_out.doubleSqrt(base));
2293             m_out.jump(continuation);
2294
2295             //     The exponent is 0.5, the base is infinite, the result is always infinite.
2296             m_out.appendTo(exponentIsOneHalfInfinity, testExponentIsNegativeOneHalf);
2297             ValueFromBlock sqrtInfinityResult = m_out.anchor(m_out.constDouble(std::numeric_limits<double>::infinity()));
2298             m_out.jump(continuation);
2299
2300             //     Test if y == -0.5
2301             m_out.appendTo(testExponentIsNegativeOneHalf, testBaseZeroExponentIsNegativeOneHalf);
2302             LValue exponentIsNegativeOneHalf = m_out.doubleEqual(exponent, m_out.constDouble(-0.5));
2303             m_out.branch(exponentIsNegativeOneHalf, rarely(testBaseZeroExponentIsNegativeOneHalf), usually(powBlock));
2304
2305             //     Handle x == -0.
2306             m_out.appendTo(testBaseZeroExponentIsNegativeOneHalf, handleBaseZeroExponentIsNegativeOneHalf);
2307             LValue baseIsZeroExponentIsNegativeOneHalf = m_out.doubleEqual(base, m_out.doubleZero);
2308             m_out.branch(baseIsZeroExponentIsNegativeOneHalf, rarely(handleBaseZeroExponentIsNegativeOneHalf), usually(handleInfinityForExponentIsNegativeOneHalf));
2309
2310             m_out.appendTo(handleBaseZeroExponentIsNegativeOneHalf, handleInfinityForExponentIsNegativeOneHalf);
2311             ValueFromBlock oneOverSqrtZeroResult = m_out.anchor(m_out.constDouble(std::numeric_limits<double>::infinity()));
2312             m_out.jump(continuation);
2313
2314             //     Test if abs(x) == Infinity.
2315             m_out.appendTo(handleInfinityForExponentIsNegativeOneHalf, exponentIsNegativeOneHalfNormal);
2316             LValue absoluteBaseIsInfinityNegativeOneHalf = m_out.doubleEqual(absoluteBase, m_out.constDouble(std::numeric_limits<double>::infinity()));
2317             m_out.branch(absoluteBaseIsInfinityNegativeOneHalf, rarely(exponentIsNegativeOneHalfInfinity), usually(exponentIsNegativeOneHalfNormal));
2318
2319             //     The exponent is -0.5, the base is finite or NaN, we can use 1/SQRT.
2320             m_out.appendTo(exponentIsNegativeOneHalfNormal, exponentIsNegativeOneHalfInfinity);
2321             LValue sqrtBase = m_out.doubleSqrt(base);
2322             ValueFromBlock oneOverSqrtResult = m_out.anchor(m_out.div(m_out.constDouble(1.), sqrtBase));
2323             m_out.jump(continuation);
2324
2325             //     The exponent is -0.5, the base is infinite, the result is always zero.
2326             m_out.appendTo(exponentIsNegativeOneHalfInfinity, powBlock);
2327             ValueFromBlock oneOverSqrtInfinityResult = m_out.anchor(m_out.doubleZero);
2328             m_out.jump(continuation);
2329
2330             m_out.appendTo(powBlock, nanExceptionResultIsNaN);
2331             ValueFromBlock powResult = m_out.anchor(m_out.doublePow(base, exponent));
2332             m_out.jump(continuation);
2333
2334             m_out.appendTo(nanExceptionResultIsNaN, continuation);
2335             ValueFromBlock pureNan = m_out.anchor(m_out.constDouble(PNaN));
2336             m_out.jump(continuation);
2337
2338             m_out.appendTo(continuation, lastNext);
2339             setDouble(m_out.phi(Double, powDoubleIntResult, zeroResultExponentIsOneHalf, sqrtResult, sqrtInfinityResult, oneOverSqrtZeroResult, oneOverSqrtResult, oneOverSqrtInfinityResult, powResult, pureNan));
2340         }
2341     }
2342
2343     void compileArithRandom()
2344     {
2345         JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
2346
2347         // Inlined WeakRandom::advance().
2348         // uint64_t x = m_low;
2349         void* lowAddress = reinterpret_cast<uint8_t*>(globalObject) + JSGlobalObject::weakRandomOffset() + WeakRandom::lowOffset();
2350         LValue low = m_out.load64(m_out.absolute(lowAddress));
2351         // uint64_t y = m_high;
2352         void* highAddress = reinterpret_cast<uint8_t*>(globalObject) + JSGlobalObject::weakRandomOffset() + WeakRandom::highOffset();
2353         LValue high = m_out.load64(m_out.absolute(highAddress));
2354         // m_low = y;
2355         m_out.store64(high, m_out.absolute(lowAddress));
2356
2357         // x ^= x << 23;
2358         LValue phase1 = m_out.bitXor(m_out.shl(low, m_out.constInt64(23)), low);
2359
2360         // x ^= x >> 17;
2361         LValue phase2 = m_out.bitXor(m_out.lShr(phase1, m_out.constInt64(17)), phase1);
2362
2363         // x ^= y ^ (y >> 26);
2364         LValue phase3 = m_out.bitXor(m_out.bitXor(high, m_out.lShr(high, m_out.constInt64(26))), phase2);
2365
2366         // m_high = x;
2367         m_out.store64(phase3, m_out.absolute(highAddress));
2368
2369         // return x + y;
2370         LValue random64 = m_out.add(phase3, high);
2371
2372         // Extract random 53bit. [0, 53] bit is safe integer number ranges in double representation.
2373         LValue random53 = m_out.bitAnd(random64, m_out.constInt64((1ULL << 53) - 1));
2374
2375         LValue double53Integer = m_out.intToDouble(random53);
2376
2377         // Convert `(53bit double integer value) / (1 << 53)` to `(53bit double integer value) * (1.0 / (1 << 53))`.
2378         // In latter case, `1.0 / (1 << 53)` will become a double value represented as (mantissa = 0 & exp = 970, it means 1e-(2**54)).
2379         static const double scale = 1.0 / (1ULL << 53);
2380
2381         // Multiplying 1e-(2**54) with the double integer does not change anything of the mantissa part of the double integer.
2382         // It just reduces the exp part of the given 53bit double integer.
2383         // (Except for 0.0. This is specially handled and in this case, exp just becomes 0.)
2384         // Now we get 53bit precision random double value in [0, 1).
2385         LValue result = m_out.doubleMul(double53Integer, m_out.constDouble(scale));
2386
2387         setDouble(result);
2388     }
2389
2390     void compileArithRound()
2391     {
2392         if (m_node->child1().useKind() == DoubleRepUse) {
2393             LValue result = nullptr;
2394             if (producesInteger(m_node->arithRoundingMode()) && !shouldCheckNegativeZero(m_node->arithRoundingMode())) {
2395                 LValue value = lowDouble(m_node->child1());
2396                 result = m_out.doubleFloor(m_out.doubleAdd(value, m_out.constDouble(0.5)));
2397             } else {
2398                 LBasicBlock realPartIsMoreThanHalf = m_out.newBlock();
2399                 LBasicBlock continuation = m_out.newBlock();
2400
2401                 LValue value = lowDouble(m_node->child1());
2402                 LValue integerValue = m_out.doubleCeil(value);
2403                 ValueFromBlock integerValueResult = m_out.anchor(integerValue);
2404
2405                 LValue realPart = m_out.doubleSub(integerValue, value);
2406
2407                 m_out.branch(m_out.doubleGreaterThanOrUnordered(realPart, m_out.constDouble(0.5)), unsure(realPartIsMoreThanHalf), unsure(continuation));
2408
2409                 LBasicBlock lastNext = m_out.appendTo(realPartIsMoreThanHalf, continuation);
2410                 LValue integerValueRoundedDown = m_out.doubleSub(integerValue, m_out.constDouble(1));
2411                 ValueFromBlock integerValueRoundedDownResult = m_out.anchor(integerValueRoundedDown);
2412                 m_out.jump(continuation);
2413                 m_out.appendTo(continuation, lastNext);
2414
2415                 result = m_out.phi(Double, integerValueResult, integerValueRoundedDownResult);
2416             }
2417
2418             if (producesInteger(m_node->arithRoundingMode())) {
2419                 LValue integerValue = convertDoubleToInt32(result, shouldCheckNegativeZero(m_node->arithRoundingMode()));
2420                 setInt32(integerValue);
2421             } else
2422                 setDouble(result);
2423             return;
2424         }
2425
2426         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
2427         LValue argument = lowJSValue(m_node->child1());
2428         setJSValue(vmCall(Int64, m_out.operation(operationArithRound), m_callFrame, argument));
2429     }
2430
2431     void compileArithFloor()
2432     {
2433         if (m_node->child1().useKind() == DoubleRepUse) {
2434             LValue value = lowDouble(m_node->child1());
2435             LValue integerValue = m_out.doubleFloor(value);
2436             if (producesInteger(m_node->arithRoundingMode()))
2437                 setInt32(convertDoubleToInt32(integerValue, shouldCheckNegativeZero(m_node->arithRoundingMode())));
2438             else
2439                 setDouble(integerValue);
2440             return;
2441         }
2442         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
2443         LValue argument = lowJSValue(m_node->child1());
2444         setJSValue(vmCall(Int64, m_out.operation(operationArithFloor), m_callFrame, argument));
2445     }
2446
2447     void compileArithCeil()
2448     {
2449         if (m_node->child1().useKind() == DoubleRepUse) {
2450             LValue value = lowDouble(m_node->child1());
2451             LValue integerValue = m_out.doubleCeil(value);
2452             if (producesInteger(m_node->arithRoundingMode()))
2453                 setInt32(convertDoubleToInt32(integerValue, shouldCheckNegativeZero(m_node->arithRoundingMode())));
2454             else
2455                 setDouble(integerValue);
2456             return;
2457         }
2458         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
2459         LValue argument = lowJSValue(m_node->child1());
2460         setJSValue(vmCall(Int64, m_out.operation(operationArithCeil), m_callFrame, argument));
2461     }
2462
2463     void compileArithTrunc()
2464     {
2465         if (m_node->child1().useKind() == DoubleRepUse) {
2466             LValue value = lowDouble(m_node->child1());
2467             LValue result = m_out.doubleTrunc(value);
2468             if (producesInteger(m_node->arithRoundingMode()))
2469                 setInt32(convertDoubleToInt32(result, shouldCheckNegativeZero(m_node->arithRoundingMode())));
2470             else
2471                 setDouble(result);
2472             return;
2473         }
2474         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
2475         LValue argument = lowJSValue(m_node->child1());
2476         setJSValue(vmCall(Int64, m_out.operation(operationArithTrunc), m_callFrame, argument));
2477     }
2478
2479     void compileArithSqrt()
2480     {
2481         if (m_node->child1().useKind() == DoubleRepUse) {
2482             setDouble(m_out.doubleSqrt(lowDouble(m_node->child1())));
2483             return;
2484         }
2485         LValue argument = lowJSValue(m_node->child1());
2486         LValue result = vmCall(Double, m_out.operation(operationArithSqrt), m_callFrame, argument);
2487         setDouble(result);
2488     }
2489
2490     void compileArithLog()
2491     {
2492         if (m_node->child1().useKind() == DoubleRepUse) {
2493             setDouble(m_out.doubleLog(lowDouble(m_node->child1())));
2494             return;
2495         }
2496         LValue argument = lowJSValue(m_node->child1());
2497         LValue result = vmCall(Double, m_out.operation(operationArithLog), m_callFrame, argument);
2498         setDouble(result);
2499     }
2500     
2501     void compileArithFRound()
2502     {
2503         if (m_node->child1().useKind() == DoubleRepUse) {
2504             setDouble(m_out.fround(lowDouble(m_node->child1())));
2505             return;
2506         }
2507         LValue argument = lowJSValue(m_node->child1());
2508         LValue result = vmCall(Double, m_out.operation(operationArithFRound), m_callFrame, argument);
2509         setDouble(result);
2510     }
2511     
2512     void compileArithNegate()
2513     {
2514         switch (m_node->child1().useKind()) {
2515         case Int32Use: {
2516             LValue value = lowInt32(m_node->child1());
2517             
2518             LValue result;
2519             if (!shouldCheckOverflow(m_node->arithMode()))
2520                 result = m_out.neg(value);
2521             else if (!shouldCheckNegativeZero(m_node->arithMode())) {
2522                 CheckValue* check = m_out.speculateSub(m_out.int32Zero, value);
2523                 blessSpeculation(check, Overflow, noValue(), nullptr, m_origin);
2524                 result = check;
2525             } else {
2526                 speculate(Overflow, noValue(), 0, m_out.testIsZero32(value, m_out.constInt32(0x7fffffff)));
2527                 result = m_out.neg(value);
2528             }
2529
2530             setInt32(result);
2531             break;
2532         }
2533             
2534         case Int52RepUse: {
2535             if (!abstractValue(m_node->child1()).couldBeType(SpecInt52Only)) {
2536                 Int52Kind kind;
2537                 LValue value = lowWhicheverInt52(m_node->child1(), kind);
2538                 LValue result = m_out.neg(value);
2539                 if (shouldCheckNegativeZero(m_node->arithMode()))
2540                     speculate(NegativeZero, noValue(), 0, m_out.isZero64(result));
2541                 setInt52(result, kind);
2542                 break;
2543             }
2544             
2545             LValue value = lowInt52(m_node->child1());
2546             CheckValue* result = m_out.speculateSub(m_out.int64Zero, value);
2547             blessSpeculation(result, Int52Overflow, noValue(), nullptr, m_origin);
2548             speculate(NegativeZero, noValue(), 0, m_out.isZero64(result));
2549             setInt52(result);
2550             break;
2551         }
2552             
2553         case DoubleRepUse: {
2554             setDouble(m_out.doubleNeg(lowDouble(m_node->child1())));
2555             break;
2556         }
2557             
2558         default:
2559             DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
2560             ArithProfile* arithProfile = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic)->arithProfileForBytecodeOffset(m_node->origin.semantic.bytecodeIndex);
2561             JITNegIC* negIC = codeBlock()->addJITNegIC(arithProfile);
2562             auto repatchingFunction = operationArithNegateOptimize;
2563             auto nonRepatchingFunction = operationArithNegate;
2564             compileMathIC(negIC, repatchingFunction, nonRepatchingFunction);
2565             break;
2566         }
2567     }
2568     
2569     void compileBitAnd()
2570     {
2571         if (m_node->isBinaryUseKind(UntypedUse)) {
2572             emitBinaryBitOpSnippet<JITBitAndGenerator>(operationValueBitAnd);
2573             return;
2574         }
2575         setInt32(m_out.bitAnd(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2576     }
2577     
2578     void compileBitOr()
2579     {
2580         if (m_node->isBinaryUseKind(UntypedUse)) {
2581             emitBinaryBitOpSnippet<JITBitOrGenerator>(operationValueBitOr);
2582             return;
2583         }
2584         setInt32(m_out.bitOr(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2585     }
2586     
2587     void compileBitXor()
2588     {
2589         if (m_node->isBinaryUseKind(UntypedUse)) {
2590             emitBinaryBitOpSnippet<JITBitXorGenerator>(operationValueBitXor);
2591             return;
2592         }
2593         setInt32(m_out.bitXor(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2594     }
2595     
2596     void compileBitRShift()
2597     {
2598         if (m_node->isBinaryUseKind(UntypedUse)) {
2599             emitRightShiftSnippet(JITRightShiftGenerator::SignedShift);
2600             return;
2601         }
2602         setInt32(m_out.aShr(
2603             lowInt32(m_node->child1()),
2604             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2605     }
2606     
2607     void compileBitLShift()
2608     {
2609         if (m_node->isBinaryUseKind(UntypedUse)) {
2610             emitBinaryBitOpSnippet<JITLeftShiftGenerator>(operationValueBitLShift);
2611             return;
2612         }
2613         setInt32(m_out.shl(
2614             lowInt32(m_node->child1()),
2615             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2616     }
2617     
2618     void compileBitURShift()
2619     {
2620         if (m_node->isBinaryUseKind(UntypedUse)) {
2621             emitRightShiftSnippet(JITRightShiftGenerator::UnsignedShift);
2622             return;
2623         }
2624         setInt32(m_out.lShr(
2625             lowInt32(m_node->child1()),
2626             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2627     }
2628     
2629     void compileUInt32ToNumber()
2630     {
2631         LValue value = lowInt32(m_node->child1());
2632
2633         if (doesOverflow(m_node->arithMode())) {
2634             setStrictInt52(m_out.zeroExtPtr(value));
2635             return;
2636         }
2637
2638         speculate(Overflow, noValue(), 0, m_out.lessThan(value, m_out.int32Zero));
2639         setInt32(value);
2640     }
2641     
2642     void compileCheckStructure()
2643     {
2644         ExitKind exitKind;
2645         if (m_node->child1()->hasConstant())
2646             exitKind = BadConstantCache;
2647         else
2648             exitKind = BadCache;
2649
2650         switch (m_node->child1().useKind()) {
2651         case CellUse:
2652         case KnownCellUse: {
2653             LValue cell = lowCell(m_node->child1());
2654             
2655             checkStructure(
2656                 m_out.load32(cell, m_heaps.JSCell_structureID), jsValueValue(cell),
2657                 exitKind, m_node->structureSet(),
2658                 [&] (Structure* structure) {
2659                     return weakStructureID(structure);
2660                 });
2661             return;
2662         }
2663
2664         case CellOrOtherUse: {
2665             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
2666
2667             LBasicBlock cellCase = m_out.newBlock();
2668             LBasicBlock notCellCase = m_out.newBlock();
2669             LBasicBlock continuation = m_out.newBlock();
2670
2671             m_out.branch(
2672                 isCell(value, provenType(m_node->child1())), unsure(cellCase), unsure(notCellCase));
2673
2674             LBasicBlock lastNext = m_out.appendTo(cellCase, notCellCase);
2675             checkStructure(
2676                 m_out.load32(value, m_heaps.JSCell_structureID), jsValueValue(value),
2677                 exitKind, m_node->structureSet(),
2678                 [&] (Structure* structure) {
2679                     return weakStructureID(structure);
2680                 });
2681             m_out.jump(continuation);
2682
2683             m_out.appendTo(notCellCase, continuation);
2684             FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), SpecCell | SpecOther, isNotOther(value));
2685             m_out.jump(continuation);
2686
2687             m_out.appendTo(continuation, lastNext);
2688             return;
2689         }
2690
2691         default:
2692             DFG_CRASH(m_graph, m_node, "Bad use kind");
2693             return;
2694         }
2695     }
2696     
2697     void compileCheckCell()
2698     {
2699         LValue cell = lowCell(m_node->child1());
2700         
2701         speculate(
2702             BadCell, jsValueValue(cell), m_node->child1().node(),
2703             m_out.notEqual(cell, weakPointer(m_node->cellOperand()->cell())));
2704     }
2705     
2706     void compileCheckBadCell()
2707     {
2708         terminate(BadCell);
2709     }
2710
2711     void compileCheckNotEmpty()
2712     {
2713         speculate(TDZFailure, noValue(), nullptr, m_out.isZero64(lowJSValue(m_node->child1())));
2714     }
2715
2716     void compileCheckStringIdent()
2717     {
2718         UniquedStringImpl* uid = m_node->uidOperand();
2719         LValue stringImpl = lowStringIdent(m_node->child1());
2720         speculate(BadIdent, noValue(), nullptr, m_out.notEqual(stringImpl, m_out.constIntPtr(uid)));
2721     }
2722
2723     void compileGetExecutable()
2724     {
2725         LValue cell = lowCell(m_node->child1());
2726         speculateFunction(m_node->child1(), cell);
2727         setJSValue(m_out.loadPtr(cell, m_heaps.JSFunction_executable));
2728     }
2729     
2730     void compileArrayifyToStructure()
2731     {
2732         LValue cell = lowCell(m_node->child1());
2733         LValue property = !!m_node->child2() ? lowInt32(m_node->child2()) : 0;
2734         
2735         LBasicBlock unexpectedStructure = m_out.newBlock();
2736         LBasicBlock continuation = m_out.newBlock();
2737         
2738         LValue structureID = m_out.load32(cell, m_heaps.JSCell_structureID);
2739         
2740         m_out.branch(
2741             m_out.notEqual(structureID, weakStructureID(m_node->structure())),
2742             rarely(unexpectedStructure), usually(continuation));
2743         
2744         LBasicBlock lastNext = m_out.appendTo(unexpectedStructure, continuation);
2745         
2746         if (property) {
2747             switch (m_node->arrayMode().type()) {
2748             case Array::Int32:
2749             case Array::Double:
2750             case Array::Contiguous:
2751                 speculate(
2752                     Uncountable, noValue(), 0,
2753                     m_out.aboveOrEqual(property, m_out.constInt32(MIN_SPARSE_ARRAY_INDEX)));
2754                 break;
2755             default:
2756                 break;
2757             }
2758         }
2759         
2760         switch (m_node->arrayMode().type()) {
2761         case Array::Int32:
2762             vmCall(Void, m_out.operation(operationEnsureInt32), m_callFrame, cell);
2763             break;
2764         case Array::Double:
2765             vmCall(Void, m_out.operation(operationEnsureDouble), m_callFrame, cell);
2766             break;
2767         case Array::Contiguous:
2768             vmCall(Void, m_out.operation(operationEnsureContiguous), m_callFrame, cell);
2769             break;
2770         case Array::ArrayStorage:
2771         case Array::SlowPutArrayStorage:
2772             vmCall(Void, m_out.operation(operationEnsureArrayStorage), m_callFrame, cell);
2773             break;
2774         default:
2775             DFG_CRASH(m_graph, m_node, "Bad array type");
2776             break;
2777         }
2778         
2779         structureID = m_out.load32(cell, m_heaps.JSCell_structureID);
2780         speculate(
2781             BadIndexingType, jsValueValue(cell), 0,
2782             m_out.notEqual(structureID, weakStructureID(m_node->structure())));
2783         m_out.jump(continuation);
2784         
2785         m_out.appendTo(continuation, lastNext);
2786     }
2787     
2788     void compilePutStructure()
2789     {
2790         m_ftlState.jitCode->common.notifyCompilingStructureTransition(m_graph.m_plan, codeBlock(), m_node);
2791         
2792         Structure* oldStructure = m_node->transition()->previous;
2793         Structure* newStructure = m_node->transition()->next;
2794         ASSERT_UNUSED(oldStructure, oldStructure->indexingType() == newStructure->indexingType());
2795         ASSERT(oldStructure->typeInfo().inlineTypeFlags() == newStructure->typeInfo().inlineTypeFlags());
2796         ASSERT(oldStructure->typeInfo().type() == newStructure->typeInfo().type());
2797
2798         LValue cell = lowCell(m_node->child1()); 
2799         m_out.store32(
2800             weakStructureID(newStructure),
2801             cell, m_heaps.JSCell_structureID);
2802     }
2803     
2804     void compileGetById(AccessType type)
2805     {
2806         ASSERT(type == AccessType::Get || type == AccessType::GetPure);
2807         switch (m_node->child1().useKind()) {
2808         case CellUse: {
2809             setJSValue(getById(lowCell(m_node->child1()), type));
2810             return;
2811         }
2812             
2813         case UntypedUse: {
2814             // This is pretty weird, since we duplicate the slow path both here and in the
2815             // code generated by the IC. We should investigate making this less bad.
2816             // https://bugs.webkit.org/show_bug.cgi?id=127830
2817             LValue value = lowJSValue(m_node->child1());
2818             
2819             LBasicBlock cellCase = m_out.newBlock();
2820             LBasicBlock notCellCase = m_out.newBlock();
2821             LBasicBlock continuation = m_out.newBlock();
2822             
2823             m_out.branch(
2824                 isCell(value, provenType(m_node->child1())), unsure(cellCase), unsure(notCellCase));
2825             
2826             LBasicBlock lastNext = m_out.appendTo(cellCase, notCellCase);
2827             ValueFromBlock cellResult = m_out.anchor(getById(value, type));
2828             m_out.jump(continuation);
2829
2830             J_JITOperation_EJI getByIdFunction;
2831             if (type == AccessType::Get)
2832                 getByIdFunction = operationGetByIdGeneric;
2833             else
2834                 getByIdFunction = operationTryGetByIdGeneric;
2835
2836             m_out.appendTo(notCellCase, continuation);
2837             ValueFromBlock notCellResult = m_out.anchor(vmCall(
2838                 Int64, m_out.operation(getByIdFunction),
2839                 m_callFrame, value,
2840                 m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()])));
2841             m_out.jump(continuation);
2842             
2843             m_out.appendTo(continuation, lastNext);
2844             setJSValue(m_out.phi(Int64, cellResult, notCellResult));
2845             return;
2846         }
2847             
2848         default:
2849             DFG_CRASH(m_graph, m_node, "Bad use kind");
2850             return;
2851         }
2852     }
2853
2854     void compileGetByIdWithThis()
2855     {
2856         LValue base = lowJSValue(m_node->child1());
2857         LValue thisValue = lowJSValue(m_node->child2());
2858         LValue result = vmCall(Int64, m_out.operation(operationGetByIdWithThis), m_callFrame, base, thisValue, m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()]));
2859         setJSValue(result);
2860     }
2861
2862     void compileGetByValWithThis()
2863     {
2864         LValue base = lowJSValue(m_node->child1());
2865         LValue thisValue = lowJSValue(m_node->child2());
2866         LValue subscript = lowJSValue(m_node->child3());
2867
2868         LValue result = vmCall(Int64, m_out.operation(operationGetByValWithThis), m_callFrame, base, thisValue, subscript);
2869         setJSValue(result);
2870     }
2871
2872     void compilePutByIdWithThis()
2873     {
2874         LValue base = lowJSValue(m_node->child1());
2875         LValue thisValue = lowJSValue(m_node->child2());
2876         LValue value = lowJSValue(m_node->child3());
2877
2878         vmCall(Void, m_out.operation(m_graph.isStrictModeFor(m_node->origin.semantic) ? operationPutByIdWithThisStrict : operationPutByIdWithThis),
2879             m_callFrame, base, thisValue, value, m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()]));
2880     }
2881
2882     void compilePutByValWithThis()
2883     {
2884         LValue base = lowJSValue(m_graph.varArgChild(m_node, 0));
2885         LValue thisValue = lowJSValue(m_graph.varArgChild(m_node, 1));
2886         LValue property = lowJSValue(m_graph.varArgChild(m_node, 2));
2887         LValue value = lowJSValue(m_graph.varArgChild(m_node, 3));
2888
2889         vmCall(Void, m_out.operation(m_graph.isStrictModeFor(m_node->origin.semantic) ? operationPutByValWithThisStrict : operationPutByValWithThis),
2890             m_callFrame, base, thisValue, property, value);
2891     }
2892
2893     void compileDefineDataProperty()
2894     {
2895         LValue base = lowCell(m_graph.varArgChild(m_node, 0));
2896         LValue value  = lowJSValue(m_graph.varArgChild(m_node, 2));
2897         LValue attributes = lowInt32(m_graph.varArgChild(m_node, 3));
2898         Edge& propertyEdge = m_graph.varArgChild(m_node, 1);
2899         switch (propertyEdge.useKind()) {
2900         case StringUse: {
2901             LValue property = lowString(propertyEdge);
2902             vmCall(Void, m_out.operation(operationDefineDataPropertyString), m_callFrame, base, property, value, attributes);
2903             break;
2904         }
2905         case StringIdentUse: {
2906             LValue property = lowStringIdent(propertyEdge);
2907             vmCall(Void, m_out.operation(operationDefineDataPropertyStringIdent), m_callFrame, base, property, value, attributes);
2908             break;
2909         }
2910         case SymbolUse: {
2911             LValue property = lowSymbol(propertyEdge);
2912             vmCall(Void, m_out.operation(operationDefineDataPropertySymbol), m_callFrame, base, property, value, attributes);
2913             break;
2914         }
2915         case UntypedUse: {
2916             LValue property = lowJSValue(propertyEdge);
2917             vmCall(Void, m_out.operation(operationDefineDataProperty), m_callFrame, base, property, value, attributes);
2918             break;
2919         }
2920         default:
2921             RELEASE_ASSERT_NOT_REACHED();
2922         }
2923     }
2924
2925     void compileDefineAccessorProperty()
2926     {
2927         LValue base = lowCell(m_graph.varArgChild(m_node, 0));
2928         LValue getter = lowCell(m_graph.varArgChild(m_node, 2));
2929         LValue setter = lowCell(m_graph.varArgChild(m_node, 3));
2930         LValue attributes = lowInt32(m_graph.varArgChild(m_node, 4));
2931         Edge& propertyEdge = m_graph.varArgChild(m_node, 1);
2932         switch (propertyEdge.useKind()) {
2933         case StringUse: {
2934             LValue property = lowString(propertyEdge);
2935             vmCall(Void, m_out.operation(operationDefineAccessorPropertyString), m_callFrame, base, property, getter, setter, attributes);
2936             break;
2937         }
2938         case StringIdentUse: {
2939             LValue property = lowStringIdent(propertyEdge);
2940             vmCall(Void, m_out.operation(operationDefineAccessorPropertyStringIdent), m_callFrame, base, property, getter, setter, attributes);
2941             break;
2942         }
2943         case SymbolUse: {
2944             LValue property = lowSymbol(propertyEdge);
2945             vmCall(Void, m_out.operation(operationDefineAccessorPropertySymbol), m_callFrame, base, property, getter, setter, attributes);
2946             break;
2947         }
2948         case UntypedUse: {
2949             LValue property = lowJSValue(propertyEdge);
2950             vmCall(Void, m_out.operation(operationDefineAccessorProperty), m_callFrame, base, property, getter, setter, attributes);
2951             break;
2952         }
2953         default:
2954             RELEASE_ASSERT_NOT_REACHED();
2955         }
2956     }
2957     
2958     void compilePutById()
2959     {
2960         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == CellUse);
2961
2962         Node* node = m_node;
2963         LValue base = lowCell(node->child1());
2964         LValue value = lowJSValue(node->child2());
2965         auto uid = m_graph.identifiers()[node->identifierNumber()];
2966
2967         B3::PatchpointValue* patchpoint = m_out.patchpoint(Void);
2968         patchpoint->appendSomeRegister(base);
2969         patchpoint->appendSomeRegister(value);
2970         patchpoint->append(m_tagMask, ValueRep::reg(GPRInfo::tagMaskRegister));
2971         patchpoint->append(m_tagTypeNumber, ValueRep::reg(GPRInfo::tagTypeNumberRegister));
2972         patchpoint->clobber(RegisterSet::macroScratchRegisters());
2973
2974         // FIXME: If this is a PutByIdFlush, we might want to late-clobber volatile registers.
2975         // https://bugs.webkit.org/show_bug.cgi?id=152848
2976
2977         RefPtr<PatchpointExceptionHandle> exceptionHandle =
2978             preparePatchpointForExceptions(patchpoint);
2979
2980         State* state = &m_ftlState;
2981         ECMAMode ecmaMode = m_graph.executableFor(node->origin.semantic)->ecmaMode();
2982         
2983         patchpoint->setGenerator(
2984             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
2985                 AllowMacroScratchRegisterUsage allowScratch(jit);
2986
2987                 CallSiteIndex callSiteIndex =
2988                     state->jitCode->common.addUniqueCallSiteIndex(node->origin.semantic);
2989
2990                 Box<CCallHelpers::JumpList> exceptions =
2991                     exceptionHandle->scheduleExitCreation(params)->jumps(jit);
2992
2993                 // JS setter call ICs generated by the PutById IC will need this.
2994                 exceptionHandle->scheduleExitCreationForUnwind(params, callSiteIndex);
2995
2996                 auto generator = Box<JITPutByIdGenerator>::create(
2997                     jit.codeBlock(), node->origin.semantic, callSiteIndex,
2998                     params.unavailableRegisters(), JSValueRegs(params[0].gpr()),
2999                     JSValueRegs(params[1].gpr()), GPRInfo::patchpointScratchRegister, ecmaMode,
3000                     node->op() == PutByIdDirect ? Direct : NotDirect);
3001
3002                 generator->generateFastPath(jit);
3003                 CCallHelpers::Label done = jit.label();
3004
3005                 params.addLatePath(
3006                     [=] (CCallHelpers& jit) {
3007                         AllowMacroScratchRegisterUsage allowScratch(jit);
3008
3009                         generator->slowPathJump().link(&jit);
3010                         CCallHelpers::Label slowPathBegin = jit.label();
3011                         CCallHelpers::Call slowPathCall = callOperation(
3012                             *state, params.unavailableRegisters(), jit, node->origin.semantic,
3013                             exceptions.get(), generator->slowPathFunction(), InvalidGPRReg,
3014                             CCallHelpers::TrustedImmPtr(generator->stubInfo()), params[1].gpr(),
3015                             params[0].gpr(), CCallHelpers::TrustedImmPtr(uid)).call();
3016                         jit.jump().linkTo(done, &jit);
3017
3018                         generator->reportSlowPathCall(slowPathBegin, slowPathCall);
3019
3020                         jit.addLinkTask(
3021                             [=] (LinkBuffer& linkBuffer) {
3022                                 generator->finalize(linkBuffer);
3023                             });
3024                     });
3025             });
3026     }
3027     
3028     void compileGetButterfly()
3029     {
3030         setStorage(m_out.loadPtr(lowCell(m_node->child1()), m_heaps.JSObject_butterfly));
3031     }
3032
3033     void compileConstantStoragePointer()
3034     {
3035         setStorage(m_out.constIntPtr(m_node->storagePointer()));
3036     }
3037     
3038     void compileGetIndexedPropertyStorage()
3039     {
3040         LValue cell = lowCell(m_node->child1());
3041         
3042         if (m_node->arrayMode().type() == Array::String) {
3043             LBasicBlock slowPath = m_out.newBlock();
3044             LBasicBlock continuation = m_out.newBlock();
3045
3046             LValue fastResultValue = m_out.loadPtr(cell, m_heaps.JSString_value);
3047             ValueFromBlock fastResult = m_out.anchor(fastResultValue);
3048             
3049             m_out.branch(
3050                 m_out.notNull(fastResultValue), usually(continuation), rarely(slowPath));
3051             
3052             LBasicBlock lastNext = m_out.appendTo(slowPath, continuation);
3053             
3054             ValueFromBlock slowResult = m_out.anchor(
3055                 vmCall(pointerType(), m_out.operation(operationResolveRope), m_callFrame, cell));
3056             
3057             m_out.jump(continuation);
3058             
3059             m_out.appendTo(continuation, lastNext);
3060             
3061             setStorage(m_out.loadPtr(m_out.phi(pointerType(), fastResult, slowResult), m_heaps.StringImpl_data));
3062             return;
3063         }
3064
3065         DFG_ASSERT(m_graph, m_node, isTypedView(m_node->arrayMode().typedArrayType()));
3066         setStorage(m_out.loadPtr(cell, m_heaps.JSArrayBufferView_vector));
3067     }
3068     
3069     void compileCheckArray()
3070     {
3071         Edge edge = m_node->child1();
3072         LValue cell = lowCell(edge);
3073         
3074         if (m_node->arrayMode().alreadyChecked(m_graph, m_node, abstractValue(edge)))
3075             return;
3076         
3077         speculate(
3078             BadIndexingType, jsValueValue(cell), 0,
3079             m_out.logicalNot(isArrayType(cell, m_node->arrayMode())));
3080     }
3081
3082     void compileGetTypedArrayByteOffset()
3083     {
3084         LValue basePtr = lowCell(m_node->child1());    
3085
3086         LBasicBlock simpleCase = m_out.newBlock();
3087         LBasicBlock wastefulCase = m_out.newBlock();
3088         LBasicBlock continuation = m_out.newBlock();
3089         
3090         LValue mode = m_out.load32(basePtr, m_heaps.JSArrayBufferView_mode);
3091         m_out.branch(
3092             m_out.notEqual(mode, m_out.constInt32(WastefulTypedArray)),
3093             unsure(simpleCase), unsure(wastefulCase));
3094
3095         LBasicBlock lastNext = m_out.appendTo(simpleCase, wastefulCase);
3096
3097         ValueFromBlock simpleOut = m_out.anchor(m_out.constIntPtr(0));
3098
3099         m_out.jump(continuation);
3100
3101         m_out.appendTo(wastefulCase, continuation);
3102
3103         LValue vectorPtr = m_out.loadPtr(basePtr, m_heaps.JSArrayBufferView_vector);
3104         LValue butterflyPtr = m_out.loadPtr(basePtr, m_heaps.JSObject_butterfly);
3105         LValue arrayBufferPtr = m_out.loadPtr(butterflyPtr, m_heaps.Butterfly_arrayBuffer);
3106         LValue dataPtr = m_out.loadPtr(arrayBufferPtr, m_heaps.ArrayBuffer_data);
3107
3108         ValueFromBlock wastefulOut = m_out.anchor(m_out.sub(vectorPtr, dataPtr));
3109
3110         m_out.jump(continuation);
3111         m_out.appendTo(continuation, lastNext);
3112
3113         setInt32(m_out.castToInt32(m_out.phi(pointerType(), simpleOut, wastefulOut)));
3114     }
3115     
3116     void compileGetArrayLength()
3117     {
3118         switch (m_node->arrayMode().type()) {
3119         case Array::Undecided:
3120         case Array::Int32:
3121         case Array::Double:
3122         case Array::Contiguous: {
3123             setInt32(m_out.load32NonNegative(lowStorage(m_node->child2()), m_heaps.Butterfly_publicLength));
3124             return;
3125         }
3126             
3127         case Array::String: {
3128             LValue string = lowCell(m_node->child1());
3129             setInt32(m_out.load32NonNegative(string, m_heaps.JSString_length));
3130             return;
3131         }
3132             
3133         case Array::DirectArguments: {
3134             LValue arguments = lowCell(m_node->child1());
3135             speculate(
3136                 ExoticObjectMode, noValue(), nullptr,
3137                 m_out.notNull(m_out.loadPtr(arguments, m_heaps.DirectArguments_overrides)));
3138             setInt32(m_out.load32NonNegative(arguments, m_heaps.DirectArguments_length));
3139             return;
3140         }
3141             
3142         case Array::ScopedArguments: {
3143             LValue arguments = lowCell(m_node->child1());
3144             speculate(
3145                 ExoticObjectMode, noValue(), nullptr,
3146                 m_out.notZero32(m_out.load8ZeroExt32(arguments, m_heaps.ScopedArguments_overrodeThings)));
3147             setInt32(m_out.load32NonNegative(arguments, m_heaps.ScopedArguments_totalLength));
3148             return;
3149         }
3150             
3151         default:
3152             if (m_node->arrayMode().isSomeTypedArrayView()) {
3153                 setInt32(
3154                     m_out.load32NonNegative(lowCell(m_node->child1()), m_heaps.JSArrayBufferView_length));
3155                 return;
3156             }
3157             
3158             DFG_CRASH(m_graph, m_node, "Bad array type");
3159             return;
3160         }
3161     }
3162     
3163     void compileCheckInBounds()
3164     {
3165         speculate(
3166             OutOfBounds, noValue(), 0,
3167             m_out.aboveOrEqual(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
3168     }
3169     
3170     void compileGetByVal()
3171     {
3172         switch (m_node->arrayMode().type()) {
3173         case Array::Int32:
3174         case Array::Contiguous: {
3175             LValue index = lowInt32(m_node->child2());
3176             LValue storage = lowStorage(m_node->child3());
3177             
3178             IndexedAbstractHeap& heap = m_node->arrayMode().type() == Array::Int32 ?
3179                 m_heaps.indexedInt32Properties : m_heaps.indexedContiguousProperties;
3180             
3181             if (m_node->arrayMode().isInBounds()) {
3182                 LValue result = m_out.load64(baseIndex(heap, storage, index, m_node->child2()));
3183                 LValue isHole = m_out.isZero64(result);
3184                 if (m_node->arrayMode().isSaneChain()) {
3185                     DFG_ASSERT(
3186                         m_graph, m_node, m_node->arrayMode().type() == Array::Contiguous);
3187                     result = m_out.select(
3188                         isHole, m_out.constInt64(JSValue::encode(jsUndefined())), result);
3189                 } else
3190                     speculate(LoadFromHole, noValue(), 0, isHole);
3191                 setJSValue(result);
3192                 return;
3193             }
3194             
3195             LValue base = lowCell(m_node->child1());
3196             
3197             LBasicBlock fastCase = m_out.newBlock();
3198             LBasicBlock slowCase = m_out.newBlock();
3199             LBasicBlock continuation = m_out.newBlock();
3200             
3201             m_out.branch(
3202                 m_out.aboveOrEqual(
3203                     index, m_out.load32NonNegative(storage, m_heaps.Butterfly_publicLength)),
3204                 rarely(slowCase), usually(fastCase));
3205             
3206             LBasicBlock lastNext = m_out.appendTo(fastCase, slowCase);
3207
3208             LValue fastResultValue = m_out.load64(baseIndex(heap, storage, index, m_node->child2()));
3209             ValueFromBlock fastResult = m_out.anchor(fastResultValue);
3210             m_out.branch(
3211                 m_out.isZero64(fastResultValue), rarely(slowCase), usually(continuation));
3212             
3213             m_out.appendTo(slowCase, continuation);
3214             ValueFromBlock slowResult = m_out.anchor(
3215                 vmCall(Int64, m_out.operation(operationGetByValArrayInt), m_callFrame, base, index));
3216             m_out.jump(continuation);
3217             
3218             m_out.appendTo(continuation, lastNext);
3219             setJSValue(m_out.phi(Int64, fastResult, slowResult));
3220             return;
3221         }
3222             
3223         case Array::Double: {
3224             LValue index = lowInt32(m_node->child2());
3225             LValue storage = lowStorage(m_node->child3());
3226             
3227             IndexedAbstractHeap& heap = m_heaps.indexedDoubleProperties;
3228             
3229             if (m_node->arrayMode().isInBounds()) {
3230                 LValue result = m_out.loadDouble(
3231                     baseIndex(heap, storage, index, m_node->child2()));
3232                 
3233                 if (!m_node->arrayMode().isSaneChain()) {
3234                     speculate(
3235                         LoadFromHole, noValue(), 0,
3236                         m_out.doubleNotEqualOrUnordered(result, result));
3237                 }
3238                 setDouble(result);
3239                 break;
3240             }
3241             
3242             LValue base = lowCell(m_node->child1());
3243             
3244             LBasicBlock inBounds = m_out.newBlock();
3245             LBasicBlock boxPath = m_out.newBlock();
3246             LBasicBlock slowCase = m_out.newBlock();
3247             LBasicBlock continuation = m_out.newBlock();
3248             
3249             m_out.branch(
3250                 m_out.aboveOrEqual(
3251                     index, m_out.load32NonNegative(storage, m_heaps.Butterfly_publicLength)),
3252                 rarely(slowCase), usually(inBounds));
3253             
3254             LBasicBlock lastNext = m_out.appendTo(inBounds, boxPath);
3255             LValue doubleValue = m_out.loadDouble(
3256                 baseIndex(heap, storage, index, m_node->child2()));
3257             m_out.branch(
3258                 m_out.doubleNotEqualOrUnordered(doubleValue, doubleValue),
3259                 rarely(slowCase), usually(boxPath));
3260             
3261             m_out.appendTo(boxPath, slowCase);
3262             ValueFromBlock fastResult = m_out.anchor(boxDouble(doubleValue));
3263             m_out.jump(continuation);
3264             
3265             m_out.appendTo(slowCase, continuation);
3266             ValueFromBlock slowResult = m_out.anchor(
3267                 vmCall(Int64, m_out.operation(operationGetByValArrayInt), m_callFrame, base, index));
3268             m_out.jump(continuation);
3269             
3270             m_out.appendTo(continuation, lastNext);
3271             setJSValue(m_out.phi(Int64, fastResult, slowResult));
3272             return;
3273         }
3274
3275         case Array::Undecided: {
3276             LValue index = lowInt32(m_node->child2());
3277
3278             speculate(OutOfBounds, noValue(), m_node, m_out.lessThan(index, m_out.int32Zero));
3279             setJSValue(m_out.constInt64(ValueUndefined));
3280             return;
3281         }
3282             
3283         case Array::DirectArguments: {
3284             LValue base = lowCell(m_node->child1());
3285             LValue index = lowInt32(m_node->child2());
3286             
3287             speculate(
3288                 ExoticObjectMode, noValue(), nullptr,
3289                 m_out.notNull(m_out.loadPtr(base, m_heaps.DirectArguments_overrides)));
3290             speculate(
3291                 ExoticObjectMode, noValue(), nullptr,
3292                 m_out.aboveOrEqual(
3293                     index,
3294                     m_out.load32NonNegative(base, m_heaps.DirectArguments_length)));
3295
3296             TypedPointer address = m_out.baseIndex(
3297                 m_heaps.DirectArguments_storage, base, m_out.zeroExtPtr(index));
3298             setJSValue(m_out.load64(address));
3299             return;
3300         }
3301             
3302         case Array::ScopedArguments: {
3303             LValue base = lowCell(m_node->child1());
3304             LValue index = lowInt32(m_node->child2());
3305             
3306             speculate(
3307                 ExoticObjectMode, noValue(), nullptr,
3308                 m_out.aboveOrEqual(
3309                     index,
3310                     m_out.load32NonNegative(base, m_heaps.ScopedArguments_totalLength)));
3311             
3312             LValue table = m_out.loadPtr(base, m_heaps.ScopedArguments_table);
3313             LValue namedLength = m_out.load32(table, m_heaps.ScopedArgumentsTable_length);
3314             
3315             LBasicBlock namedCase = m_out.newBlock();
3316             LBasicBlock overflowCase = m_out.newBlock();
3317             LBasicBlock continuation = m_out.newBlock();
3318             
3319             m_out.branch(
3320                 m_out.aboveOrEqual(index, namedLength), unsure(overflowCase), unsure(namedCase));
3321             
3322             LBasicBlock lastNext = m_out.appendTo(namedCase, overflowCase);
3323             
3324             LValue scope = m_out.loadPtr(base, m_heaps.ScopedArguments_scope);
3325             LValue arguments = m_out.loadPtr(table, m_heaps.ScopedArgumentsTable_arguments);
3326             
3327             TypedPointer address = m_out.baseIndex(
3328                 m_heaps.scopedArgumentsTableArguments, arguments, m_out.zeroExtPtr(index));
3329             LValue scopeOffset = m_out.load32(address);
3330             
3331             speculate(
3332                 ExoticObjectMode, noValue(), nullptr,
3333                 m_out.equal(scopeOffset, m_out.constInt32(ScopeOffset::invalidOffset)));
3334             
3335             address = m_out.baseIndex(
3336                 m_heaps.JSEnvironmentRecord_variables, scope, m_out.zeroExtPtr(scopeOffset));
3337             ValueFromBlock namedResult = m_out.anchor(m_out.load64(address));
3338             m_out.jump(continuation);
3339             
3340             m_out.appendTo(overflowCase, continuation);
3341             
3342             address = m_out.baseIndex(
3343                 m_heaps.ScopedArguments_overflowStorage, base,
3344                 m_out.zeroExtPtr(m_out.sub(index, namedLength)));
3345             LValue overflowValue = m_out.load64(address);
3346             speculate(ExoticObjectMode, noValue(), nullptr, m_out.isZero64(overflowValue));
3347             ValueFromBlock overflowResult = m_out.anchor(overflowValue);
3348             m_out.jump(continuation);
3349             
3350             m_out.appendTo(continuation, lastNext);
3351             setJSValue(m_out.phi(Int64, namedResult, overflowResult));
3352             return;
3353         }
3354             
3355         case Array::Generic: {
3356             setJSValue(vmCall(
3357                 Int64, m_out.operation(operationGetByVal), m_callFrame,
3358                 lowJSValue(m_node->child1()), lowJSValue(m_node->child2())));
3359             return;
3360         }
3361             
3362         case Array::String: {
3363             compileStringCharAt();
3364             return;
3365         }
3366             
3367         default: {
3368             LValue index = lowInt32(m_node->child2());
3369             LValue storage = lowStorage(m_node->child3());
3370             
3371             TypedArrayType type = m_node->arrayMode().typedArrayType();
3372             
3373             if (isTypedView(type)) {
3374                 TypedPointer pointer = TypedPointer(
3375                     m_heaps.typedArrayProperties,
3376                     m_out.add(
3377                         storage,
3378                         m_out.shl(
3379                             m_out.zeroExtPtr(index),
3380                             m_out.constIntPtr(logElementSize(type)))));
3381                 
3382                 if (isInt(type)) {
3383                     LValue result;
3384                     switch (elementSize(type)) {
3385                     case 1:
3386                         result = isSigned(type) ? m_out.load8SignExt32(pointer) :  m_out.load8ZeroExt32(pointer);
3387                         break;
3388                     case 2:
3389                         result = isSigned(type) ? m_out.load16SignExt32(pointer) :  m_out.load16ZeroExt32(pointer);
3390                         break;
3391                     case 4:
3392                         result = m_out.load32(pointer);
3393                         break;
3394                     default:
3395                         DFG_CRASH(m_graph, m_node, "Bad element size");
3396                     }
3397                     
3398                     if (elementSize(type) < 4 || isSigned(type)) {
3399                         setInt32(result);
3400                         return;
3401                     }
3402
3403                     if (m_node->shouldSpeculateInt32()) {
3404                         speculate(
3405                             Overflow, noValue(), 0, m_out.lessThan(result, m_out.int32Zero));
3406                         setInt32(result);
3407                         return;
3408                     }
3409                     
3410                     if (m_node->shouldSpeculateAnyInt()) {
3411                         setStrictInt52(m_out.zeroExt(result, Int64));
3412                         return;
3413                     }
3414                     
3415                     setDouble(m_out.unsignedToDouble(result));
3416                     return;
3417                 }
3418             
3419                 ASSERT(isFloat(type));
3420                 
3421                 LValue result;
3422                 switch (type) {
3423                 case TypeFloat32:
3424                     result = m_out.floatToDouble(m_out.loadFloat(pointer));
3425                     break;
3426                 case TypeFloat64:
3427                     result = m_out.loadDouble(pointer);
3428                     break;
3429                 default:
3430                     DFG_CRASH(m_graph, m_node, "Bad typed array type");
3431                 }
3432                 
3433                 setDouble(result);
3434                 return;
3435             }
3436             
3437             DFG_CRASH(m_graph, m_node, "Bad array type");
3438             return;
3439         } }
3440     }
3441     
3442     void compileGetMyArgumentByVal()
3443     {
3444         InlineCallFrame* inlineCallFrame = m_node->child1()->origin.semantic.inlineCallFrame;
3445         
3446         LValue index = lowInt32(m_node->child2());
3447         if (m_node->numberOfArgumentsToSkip())
3448             index = m_out.add(index, m_out.constInt32(m_node->numberOfArgumentsToSkip()));
3449         
3450         LValue limit;
3451         if (inlineCallFrame && !inlineCallFrame->isVarargs())
3452             limit = m_out.constInt32(inlineCallFrame->arguments.size() - 1);
3453         else {
3454             VirtualRegister argumentCountRegister = AssemblyHelpers::argumentCount(inlineCallFrame);
3455             limit = m_out.sub(m_out.load32(payloadFor(argumentCountRegister)), m_out.int32One);
3456         }
3457         
3458         LValue isOutOfBounds = m_out.aboveOrEqual(index, limit);
3459         LBasicBlock continuation = nullptr;
3460         LBasicBlock lastNext = nullptr;
3461         ValueFromBlock slowResult;
3462         if (m_node->op() == GetMyArgumentByValOutOfBounds) {
3463             LBasicBlock normalCase = m_out.newBlock();
3464             continuation = m_out.newBlock();
3465             
3466             slowResult = m_out.anchor(m_out.constInt64(JSValue::encode(jsUndefined())));
3467             m_out.branch(isOutOfBounds, unsure(continuation), unsure(normalCase));
3468             
3469             lastNext = m_out.appendTo(normalCase, continuation);
3470         } else
3471             speculate(ExoticObjectMode, noValue(), 0, isOutOfBounds);
3472         
3473         TypedPointer base;
3474         if (inlineCallFrame) {
3475             if (inlineCallFrame->arguments.size() > 1)
3476                 base = addressFor(inlineCallFrame->arguments[1].virtualRegister());
3477         } else
3478             base = addressFor(virtualRegisterForArgument(1));
3479         
3480         LValue result;
3481         if (base) {
3482             LValue pointer = m_out.baseIndex(
3483                 base.value(), m_out.zeroExt(index, pointerType()), ScaleEight);
3484             result = m_out.load64(TypedPointer(m_heaps.variables.atAnyIndex(), pointer));
3485         } else
3486             result = m_out.constInt64(JSValue::encode(jsUndefined()));
3487         
3488         if (m_node->op() == GetMyArgumentByValOutOfBounds) {
3489             ValueFromBlock normalResult = m_out.anchor(result);
3490             m_out.jump(continuation);
3491             
3492             m_out.appendTo(continuation, lastNext);
3493             result = m_out.phi(Int64, slowResult, normalResult);
3494         }
3495         
3496         setJSValue(result);
3497     }
3498     
3499     void compilePutByVal()
3500     {
3501         Edge child1 = m_graph.varArgChild(m_node, 0);
3502         Edge child2 = m_graph.varArgChild(m_node, 1);
3503         Edge child3 = m_graph.varArgChild(m_node, 2);
3504         Edge child4 = m_graph.varArgChild(m_node, 3);
3505         Edge child5 = m_graph.varArgChild(m_node, 4);
3506         
3507         switch (m_node->arrayMode().type()) {
3508         case Array::Generic: {
3509             V_JITOperation_EJJJ operation;
3510             if (m_node->op() == PutByValDirect) {
3511                 if (m_graph.isStrictModeFor(m_node->origin.semantic))
3512                     operation = operationPutByValDirectStrict;
3513                 else
3514                     operation = operationPutByValDirectNonStrict;
3515             } else {
3516                 if (m_graph.isStrictModeFor(m_node->origin.semantic))
3517                     operation = operationPutByValStrict;
3518                 else
3519                     operation = operationPutByValNonStrict;
3520             }
3521                 
3522             vmCall(
3523                 Void, m_out.operation(operation), m_callFrame,
3524                 lowJSValue(child1), lowJSValue(child2), lowJSValue(child3));
3525             return;
3526         }
3527             
3528         default:
3529             break;
3530         }
3531
3532         LValue base = lowCell(child1);
3533         LValue index = lowInt32(child2);
3534         LValue storage = lowStorage(child4);
3535         
3536         switch (m_node->arrayMode().type()) {
3537         case Array::Int32:
3538         case Array::Double:
3539         case Array::Contiguous: {
3540             LBasicBlock continuation = m_out.newBlock();
3541             LBasicBlock outerLastNext = m_out.appendTo(m_out.m_block, continuation);
3542             
3543             switch (m_node->arrayMode().type()) {
3544             case Array::Int32:
3545             case Array::Contiguous: {
3546                 LValue value = lowJSValue(child3, ManualOperandSpeculation);
3547                 
3548                 if (m_node->arrayMode().type() == Array::Int32)
3549                     FTL_TYPE_CHECK(jsValueValue(value), child3, SpecInt32Only, isNotInt32(value));
3550                 
3551                 TypedPointer elementPointer = m_out.baseIndex(
3552                     m_node->arrayMode().type() == Array::Int32 ?
3553                     m_heaps.indexedInt32Properties : m_heaps.indexedContiguousProperties,
3554                     storage, m_out.zeroExtPtr(index), provenValue(child2));
3555                 
3556                 if (m_node->op() == PutByValAlias) {
3557                     m_out.store64(value, elementPointer);
3558                     break;
3559                 }
3560                 
3561                 contiguousPutByValOutOfBounds(
3562                     codeBlock()->isStrictMode()
3563                     ? operationPutByValBeyondArrayBoundsStrict
3564                     : operationPutByValBeyondArrayBoundsNonStrict,
3565                     base, storage, index, value, continuation);
3566                 
3567                 m_out.store64(value, elementPointer);
3568                 break;
3569             }
3570                 
3571             case Array::Double: {
3572                 LValue value = lowDouble(child3);
3573                 
3574                 FTL_TYPE_CHECK(
3575                     doubleValue(value), child3, SpecDoubleReal,
3576                     m_out.doubleNotEqualOrUnordered(value, value));
3577                 
3578                 TypedPointer elementPointer = m_out.baseIndex(
3579                     m_heaps.indexedDoubleProperties, storage, m_out.zeroExtPtr(index),
3580                     provenValue(child2));
3581                 
3582                 if (m_node->op() == PutByValAlias) {
3583                     m_out.storeDouble(value, elementPointer);
3584                     break;
3585                 }
3586                 
3587                 contiguousPutByValOutOfBounds(
3588                     codeBlock()->isStrictMode()
3589