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