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