13113c6e01d5cf3e607a1a2287df0cbf96a47e7b
[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
912         case PhantomLocal:
913         case LoopHint:
914         case MovHint:
915         case ZombieHint:
916         case ExitOK:
917         case PhantomNewObject:
918         case PhantomNewFunction:
919         case PhantomNewGeneratorFunction:
920         case PhantomCreateActivation:
921         case PhantomDirectArguments:
922         case PhantomClonedArguments:
923         case PutHint:
924         case BottomValue:
925         case KillStack:
926             break;
927         default:
928             DFG_CRASH(m_graph, m_node, "Unrecognized node in FTL backend");
929             break;
930         }
931         
932         if (m_node->isTerminal())
933             return false;
934         
935         if (!m_state.isValid()) {
936             safelyInvalidateAfterTermination();
937             return false;
938         }
939
940         m_availabilityCalculator.executeNode(m_node);
941         m_interpreter.executeEffects(nodeIndex);
942         
943         return true;
944     }
945
946     void compileUpsilon()
947     {
948         LValue upsilonValue = nullptr;
949         switch (m_node->child1().useKind()) {
950         case DoubleRepUse:
951             upsilonValue = lowDouble(m_node->child1());
952             break;
953         case Int32Use:
954         case KnownInt32Use:
955             upsilonValue = lowInt32(m_node->child1());
956             break;
957         case Int52RepUse:
958             upsilonValue = lowInt52(m_node->child1());
959             break;
960         case BooleanUse:
961         case KnownBooleanUse:
962             upsilonValue = lowBoolean(m_node->child1());
963             break;
964         case CellUse:
965         case KnownCellUse:
966             upsilonValue = lowCell(m_node->child1());
967             break;
968         case UntypedUse:
969             upsilonValue = lowJSValue(m_node->child1());
970             break;
971         default:
972             DFG_CRASH(m_graph, m_node, "Bad use kind");
973             break;
974         }
975         ValueFromBlock upsilon = m_out.anchor(upsilonValue);
976         LValue phiNode = m_phis.get(m_node->phi());
977         m_out.addIncomingToPhi(phiNode, upsilon);
978     }
979     
980     void compilePhi()
981     {
982         LValue phi = m_phis.get(m_node);
983         m_out.m_block->append(phi);
984
985         switch (m_node->flags() & NodeResultMask) {
986         case NodeResultDouble:
987             setDouble(phi);
988             break;
989         case NodeResultInt32:
990             setInt32(phi);
991             break;
992         case NodeResultInt52:
993             setInt52(phi);
994             break;
995         case NodeResultBoolean:
996             setBoolean(phi);
997             break;
998         case NodeResultJS:
999             setJSValue(phi);
1000             break;
1001         default:
1002             DFG_CRASH(m_graph, m_node, "Bad use kind");
1003             break;
1004         }
1005     }
1006     
1007     void compileDoubleConstant()
1008     {
1009         setDouble(m_out.constDouble(m_node->asNumber()));
1010     }
1011     
1012     void compileInt52Constant()
1013     {
1014         int64_t value = m_node->asMachineInt();
1015         
1016         setInt52(m_out.constInt64(value << JSValue::int52ShiftAmount));
1017         setStrictInt52(m_out.constInt64(value));
1018     }
1019
1020     void compileDoubleRep()
1021     {
1022         switch (m_node->child1().useKind()) {
1023         case RealNumberUse: {
1024             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
1025             
1026             LValue doubleValue = unboxDouble(value);
1027             
1028             LBasicBlock intCase = FTL_NEW_BLOCK(m_out, ("DoubleRep RealNumberUse int case"));
1029             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("DoubleRep continuation"));
1030             
1031             ValueFromBlock fastResult = m_out.anchor(doubleValue);
1032             m_out.branch(
1033                 m_out.doubleEqual(doubleValue, doubleValue),
1034                 usually(continuation), rarely(intCase));
1035             
1036             LBasicBlock lastNext = m_out.appendTo(intCase, continuation);
1037             
1038             FTL_TYPE_CHECK(
1039                 jsValueValue(value), m_node->child1(), SpecBytecodeRealNumber,
1040                 isNotInt32(value, provenType(m_node->child1()) & ~SpecFullDouble));
1041             ValueFromBlock slowResult = m_out.anchor(m_out.intToDouble(unboxInt32(value)));
1042             m_out.jump(continuation);
1043             
1044             m_out.appendTo(continuation, lastNext);
1045             
1046             setDouble(m_out.phi(m_out.doubleType, fastResult, slowResult));
1047             return;
1048         }
1049             
1050         case NotCellUse:
1051         case NumberUse: {
1052             bool shouldConvertNonNumber = m_node->child1().useKind() == NotCellUse;
1053             
1054             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
1055
1056             LBasicBlock intCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble unboxing int case"));
1057             LBasicBlock doubleTesting = FTL_NEW_BLOCK(m_out, ("jsValueToDouble testing double case"));
1058             LBasicBlock doubleCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble unboxing double case"));
1059             LBasicBlock nonDoubleCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble testing undefined case"));
1060             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("jsValueToDouble unboxing continuation"));
1061             
1062             m_out.branch(
1063                 isNotInt32(value, provenType(m_node->child1())),
1064                 unsure(doubleTesting), unsure(intCase));
1065             
1066             LBasicBlock lastNext = m_out.appendTo(intCase, doubleTesting);
1067             
1068             ValueFromBlock intToDouble = m_out.anchor(
1069                 m_out.intToDouble(unboxInt32(value)));
1070             m_out.jump(continuation);
1071             
1072             m_out.appendTo(doubleTesting, doubleCase);
1073             LValue valueIsNumber = isNumber(value, provenType(m_node->child1()));
1074             m_out.branch(valueIsNumber, usually(doubleCase), rarely(nonDoubleCase));
1075
1076             m_out.appendTo(doubleCase, nonDoubleCase);
1077             ValueFromBlock unboxedDouble = m_out.anchor(unboxDouble(value));
1078             m_out.jump(continuation);
1079
1080             if (shouldConvertNonNumber) {
1081                 LBasicBlock undefinedCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble converting undefined case"));
1082                 LBasicBlock testNullCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble testing null case"));
1083                 LBasicBlock nullCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble converting null case"));
1084                 LBasicBlock testBooleanTrueCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble testing boolean true case"));
1085                 LBasicBlock convertBooleanTrueCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble convert boolean true case"));
1086                 LBasicBlock convertBooleanFalseCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble convert boolean false case"));
1087
1088                 m_out.appendTo(nonDoubleCase, undefinedCase);
1089                 LValue valueIsUndefined = m_out.equal(value, m_out.constInt64(ValueUndefined));
1090                 m_out.branch(valueIsUndefined, unsure(undefinedCase), unsure(testNullCase));
1091
1092                 m_out.appendTo(undefinedCase, testNullCase);
1093                 ValueFromBlock convertedUndefined = m_out.anchor(m_out.constDouble(PNaN));
1094                 m_out.jump(continuation);
1095
1096                 m_out.appendTo(testNullCase, nullCase);
1097                 LValue valueIsNull = m_out.equal(value, m_out.constInt64(ValueNull));
1098                 m_out.branch(valueIsNull, unsure(nullCase), unsure(testBooleanTrueCase));
1099
1100                 m_out.appendTo(nullCase, testBooleanTrueCase);
1101                 ValueFromBlock convertedNull = m_out.anchor(m_out.constDouble(0));
1102                 m_out.jump(continuation);
1103
1104                 m_out.appendTo(testBooleanTrueCase, convertBooleanTrueCase);
1105                 LValue valueIsBooleanTrue = m_out.equal(value, m_out.constInt64(ValueTrue));
1106                 m_out.branch(valueIsBooleanTrue, unsure(convertBooleanTrueCase), unsure(convertBooleanFalseCase));
1107
1108                 m_out.appendTo(convertBooleanTrueCase, convertBooleanFalseCase);
1109                 ValueFromBlock convertedTrue = m_out.anchor(m_out.constDouble(1));
1110                 m_out.jump(continuation);
1111
1112                 m_out.appendTo(convertBooleanFalseCase, continuation);
1113
1114                 LValue valueIsNotBooleanFalse = m_out.notEqual(value, m_out.constInt64(ValueFalse));
1115                 FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), ~SpecCell, valueIsNotBooleanFalse);
1116                 ValueFromBlock convertedFalse = m_out.anchor(m_out.constDouble(0));
1117                 m_out.jump(continuation);
1118
1119                 m_out.appendTo(continuation, lastNext);
1120                 setDouble(m_out.phi(m_out.doubleType, intToDouble, unboxedDouble, convertedUndefined, convertedNull, convertedTrue, convertedFalse));
1121                 return;
1122             }
1123             m_out.appendTo(nonDoubleCase, continuation);
1124             FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), SpecBytecodeNumber, m_out.booleanTrue);
1125             m_out.unreachable();
1126
1127             m_out.appendTo(continuation, lastNext);
1128
1129             setDouble(m_out.phi(m_out.doubleType, intToDouble, unboxedDouble));
1130             return;
1131         }
1132             
1133         case Int52RepUse: {
1134             setDouble(strictInt52ToDouble(lowStrictInt52(m_node->child1())));
1135             return;
1136         }
1137             
1138         default:
1139             DFG_CRASH(m_graph, m_node, "Bad use kind");
1140         }
1141     }
1142
1143     void compileDoubleAsInt32()
1144     {
1145         LValue integerValue = convertDoubleToInt32(lowDouble(m_node->child1()), shouldCheckNegativeZero(m_node->arithMode()));
1146         setInt32(integerValue);
1147     }
1148
1149     void compileValueRep()
1150     {
1151         switch (m_node->child1().useKind()) {
1152         case DoubleRepUse: {
1153             LValue value = lowDouble(m_node->child1());
1154             
1155             if (m_interpreter.needsTypeCheck(m_node->child1(), ~SpecDoubleImpureNaN)) {
1156                 value = m_out.select(
1157                     m_out.doubleEqual(value, value), value, m_out.constDouble(PNaN));
1158             }
1159             
1160             setJSValue(boxDouble(value));
1161             return;
1162         }
1163             
1164         case Int52RepUse: {
1165             setJSValue(strictInt52ToJSValue(lowStrictInt52(m_node->child1())));
1166             return;
1167         }
1168             
1169         default:
1170             DFG_CRASH(m_graph, m_node, "Bad use kind");
1171         }
1172     }
1173     
1174     void compileInt52Rep()
1175     {
1176         switch (m_node->child1().useKind()) {
1177         case Int32Use:
1178             setStrictInt52(m_out.signExt32To64(lowInt32(m_node->child1())));
1179             return;
1180             
1181         case MachineIntUse:
1182             setStrictInt52(
1183                 jsValueToStrictInt52(
1184                     m_node->child1(), lowJSValue(m_node->child1(), ManualOperandSpeculation)));
1185             return;
1186             
1187         case DoubleRepMachineIntUse:
1188             setStrictInt52(
1189                 doubleToStrictInt52(
1190                     m_node->child1(), lowDouble(m_node->child1())));
1191             return;
1192             
1193         default:
1194             RELEASE_ASSERT_NOT_REACHED();
1195         }
1196     }
1197     
1198     void compileValueToInt32()
1199     {
1200         switch (m_node->child1().useKind()) {
1201         case Int52RepUse:
1202             setInt32(m_out.castToInt32(lowStrictInt52(m_node->child1())));
1203             break;
1204             
1205         case DoubleRepUse:
1206             setInt32(doubleToInt32(lowDouble(m_node->child1())));
1207             break;
1208             
1209         case NumberUse:
1210         case NotCellUse: {
1211             LoweredNodeValue value = m_int32Values.get(m_node->child1().node());
1212             if (isValid(value)) {
1213                 setInt32(value.value());
1214                 break;
1215             }
1216             
1217             value = m_jsValueValues.get(m_node->child1().node());
1218             if (isValid(value)) {
1219                 setInt32(numberOrNotCellToInt32(m_node->child1(), value.value()));
1220                 break;
1221             }
1222             
1223             // We'll basically just get here for constants. But it's good to have this
1224             // catch-all since we often add new representations into the mix.
1225             setInt32(
1226                 numberOrNotCellToInt32(
1227                     m_node->child1(),
1228                     lowJSValue(m_node->child1(), ManualOperandSpeculation)));
1229             break;
1230         }
1231             
1232         default:
1233             DFG_CRASH(m_graph, m_node, "Bad use kind");
1234             break;
1235         }
1236     }
1237     
1238     void compileBooleanToNumber()
1239     {
1240         switch (m_node->child1().useKind()) {
1241         case BooleanUse: {
1242             setInt32(m_out.zeroExt(lowBoolean(m_node->child1()), m_out.int32));
1243             return;
1244         }
1245             
1246         case UntypedUse: {
1247             LValue value = lowJSValue(m_node->child1());
1248             
1249             if (!m_interpreter.needsTypeCheck(m_node->child1(), SpecBoolInt32 | SpecBoolean)) {
1250                 setInt32(m_out.bitAnd(m_out.castToInt32(value), m_out.int32One));
1251                 return;
1252             }
1253             
1254             LBasicBlock booleanCase = FTL_NEW_BLOCK(m_out, ("BooleanToNumber boolean case"));
1255             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("BooleanToNumber continuation"));
1256             
1257             ValueFromBlock notBooleanResult = m_out.anchor(value);
1258             m_out.branch(
1259                 isBoolean(value, provenType(m_node->child1())),
1260                 unsure(booleanCase), unsure(continuation));
1261             
1262             LBasicBlock lastNext = m_out.appendTo(booleanCase, continuation);
1263             ValueFromBlock booleanResult = m_out.anchor(m_out.bitOr(
1264                 m_out.zeroExt(unboxBoolean(value), m_out.int64), m_tagTypeNumber));
1265             m_out.jump(continuation);
1266             
1267             m_out.appendTo(continuation, lastNext);
1268             setJSValue(m_out.phi(m_out.int64, booleanResult, notBooleanResult));
1269             return;
1270         }
1271             
1272         default:
1273             RELEASE_ASSERT_NOT_REACHED();
1274             return;
1275         }
1276     }
1277
1278     void compileExtractOSREntryLocal()
1279     {
1280         EncodedJSValue* buffer = static_cast<EncodedJSValue*>(
1281             m_ftlState.jitCode->ftlForOSREntry()->entryBuffer()->dataBuffer());
1282         setJSValue(m_out.load64(m_out.absolute(buffer + m_node->unlinkedLocal().toLocal())));
1283     }
1284     
1285     void compileGetStack()
1286     {
1287         // GetLocals arise only for captured variables and arguments. For arguments, we might have
1288         // already loaded it.
1289         if (LValue value = m_loadedArgumentValues.get(m_node)) {
1290             setJSValue(value);
1291             return;
1292         }
1293         
1294         StackAccessData* data = m_node->stackAccessData();
1295         AbstractValue& value = m_state.variables().operand(data->local);
1296         
1297         DFG_ASSERT(m_graph, m_node, isConcrete(data->format));
1298         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.
1299         
1300         if (isInt32Speculation(value.m_type))
1301             setInt32(m_out.load32(payloadFor(data->machineLocal)));
1302         else
1303             setJSValue(m_out.load64(addressFor(data->machineLocal)));
1304     }
1305     
1306     void compilePutStack()
1307     {
1308         StackAccessData* data = m_node->stackAccessData();
1309         switch (data->format) {
1310         case FlushedJSValue: {
1311             LValue value = lowJSValue(m_node->child1());
1312             m_out.store64(value, addressFor(data->machineLocal));
1313             break;
1314         }
1315             
1316         case FlushedDouble: {
1317             LValue value = lowDouble(m_node->child1());
1318             m_out.storeDouble(value, addressFor(data->machineLocal));
1319             break;
1320         }
1321             
1322         case FlushedInt32: {
1323             LValue value = lowInt32(m_node->child1());
1324             m_out.store32(value, payloadFor(data->machineLocal));
1325             break;
1326         }
1327             
1328         case FlushedInt52: {
1329             LValue value = lowInt52(m_node->child1());
1330             m_out.store64(value, addressFor(data->machineLocal));
1331             break;
1332         }
1333             
1334         case FlushedCell: {
1335             LValue value = lowCell(m_node->child1());
1336             m_out.store64(value, addressFor(data->machineLocal));
1337             break;
1338         }
1339             
1340         case FlushedBoolean: {
1341             speculateBoolean(m_node->child1());
1342             m_out.store64(
1343                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
1344                 addressFor(data->machineLocal));
1345             break;
1346         }
1347             
1348         default:
1349             DFG_CRASH(m_graph, m_node, "Bad flush format");
1350             break;
1351         }
1352     }
1353     
1354     void compileNoOp()
1355     {
1356         DFG_NODE_DO_TO_CHILDREN(m_graph, m_node, speculate);
1357     }
1358     
1359     void compileToThis()
1360     {
1361         LValue value = lowJSValue(m_node->child1());
1362         
1363         LBasicBlock isCellCase = FTL_NEW_BLOCK(m_out, ("ToThis is cell case"));
1364         LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("ToThis slow case"));
1365         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ToThis continuation"));
1366         
1367         m_out.branch(
1368             isCell(value, provenType(m_node->child1())), usually(isCellCase), rarely(slowCase));
1369         
1370         LBasicBlock lastNext = m_out.appendTo(isCellCase, slowCase);
1371         ValueFromBlock fastResult = m_out.anchor(value);
1372         m_out.branch(isType(value, FinalObjectType), usually(continuation), rarely(slowCase));
1373         
1374         m_out.appendTo(slowCase, continuation);
1375         J_JITOperation_EJ function;
1376         if (m_graph.isStrictModeFor(m_node->origin.semantic))
1377             function = operationToThisStrict;
1378         else
1379             function = operationToThis;
1380         ValueFromBlock slowResult = m_out.anchor(
1381             vmCall(m_out.int64, m_out.operation(function), m_callFrame, value));
1382         m_out.jump(continuation);
1383         
1384         m_out.appendTo(continuation, lastNext);
1385         setJSValue(m_out.phi(m_out.int64, fastResult, slowResult));
1386     }
1387     
1388     void compileValueAdd()
1389     {
1390         emitBinarySnippet<JITAddGenerator>(operationValueAdd);
1391     }
1392     
1393     void compileStrCat()
1394     {
1395         LValue result;
1396         if (m_node->child3()) {
1397             result = vmCall(
1398                 m_out.int64, m_out.operation(operationStrCat3), m_callFrame,
1399                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
1400                 lowJSValue(m_node->child2(), ManualOperandSpeculation),
1401                 lowJSValue(m_node->child3(), ManualOperandSpeculation));
1402         } else {
1403             result = vmCall(
1404                 m_out.int64, m_out.operation(operationStrCat2), m_callFrame,
1405                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
1406                 lowJSValue(m_node->child2(), ManualOperandSpeculation));
1407         }
1408         setJSValue(result);
1409     }
1410     
1411     void compileArithAddOrSub()
1412     {
1413         bool isSub =  m_node->op() == ArithSub;
1414         switch (m_node->binaryUseKind()) {
1415         case Int32Use: {
1416             LValue left = lowInt32(m_node->child1());
1417             LValue right = lowInt32(m_node->child2());
1418
1419             if (!shouldCheckOverflow(m_node->arithMode())) {
1420                 setInt32(isSub ? m_out.sub(left, right) : m_out.add(left, right));
1421                 break;
1422             }
1423
1424             CheckValue* result =
1425                 isSub ? m_out.speculateSub(left, right) : m_out.speculateAdd(left, right);
1426             blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);
1427             setInt32(result);
1428             break;
1429         }
1430             
1431         case Int52RepUse: {
1432             if (!abstractValue(m_node->child1()).couldBeType(SpecInt52)
1433                 && !abstractValue(m_node->child2()).couldBeType(SpecInt52)) {
1434                 Int52Kind kind;
1435                 LValue left = lowWhicheverInt52(m_node->child1(), kind);
1436                 LValue right = lowInt52(m_node->child2(), kind);
1437                 setInt52(isSub ? m_out.sub(left, right) : m_out.add(left, right), kind);
1438                 break;
1439             }
1440
1441             LValue left = lowInt52(m_node->child1());
1442             LValue right = lowInt52(m_node->child2());
1443             CheckValue* result =
1444                 isSub ? m_out.speculateSub(left, right) : m_out.speculateAdd(left, right);
1445             blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);
1446             setInt52(result);
1447             break;
1448         }
1449             
1450         case DoubleRepUse: {
1451             LValue C1 = lowDouble(m_node->child1());
1452             LValue C2 = lowDouble(m_node->child2());
1453
1454             setDouble(isSub ? m_out.doubleSub(C1, C2) : m_out.doubleAdd(C1, C2));
1455             break;
1456         }
1457
1458         case UntypedUse: {
1459             if (!isSub) {
1460                 DFG_CRASH(m_graph, m_node, "Bad use kind");
1461                 break;
1462             }
1463
1464             emitBinarySnippet<JITSubGenerator>(operationValueSub);
1465             break;
1466         }
1467
1468         default:
1469             DFG_CRASH(m_graph, m_node, "Bad use kind");
1470             break;
1471         }
1472     }
1473
1474     void compileArithClz32()
1475     {
1476         LValue operand = lowInt32(m_node->child1());
1477         setInt32(m_out.ctlz32(operand));
1478     }
1479     
1480     void compileArithMul()
1481     {
1482         switch (m_node->binaryUseKind()) {
1483         case Int32Use: {
1484             LValue left = lowInt32(m_node->child1());
1485             LValue right = lowInt32(m_node->child2());
1486             
1487             LValue result;
1488
1489             if (!shouldCheckOverflow(m_node->arithMode()))
1490                 result = m_out.mul(left, right);
1491             else {
1492                 CheckValue* speculation = m_out.speculateMul(left, right);
1493                 blessSpeculation(speculation, Overflow, noValue(), nullptr, m_origin);
1494                 result = speculation;
1495             }
1496             
1497             if (shouldCheckNegativeZero(m_node->arithMode())) {
1498                 LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("ArithMul slow case"));
1499                 LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithMul continuation"));
1500                 
1501                 m_out.branch(
1502                     m_out.notZero32(result), usually(continuation), rarely(slowCase));
1503                 
1504                 LBasicBlock lastNext = m_out.appendTo(slowCase, continuation);
1505                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(left, m_out.int32Zero));
1506                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(right, m_out.int32Zero));
1507                 m_out.jump(continuation);
1508                 m_out.appendTo(continuation, lastNext);
1509             }
1510             
1511             setInt32(result);
1512             break;
1513         }
1514             
1515         case Int52RepUse: {
1516             Int52Kind kind;
1517             LValue left = lowWhicheverInt52(m_node->child1(), kind);
1518             LValue right = lowInt52(m_node->child2(), opposite(kind));
1519
1520             CheckValue* result = m_out.speculateMul(left, right);
1521             blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);
1522
1523             if (shouldCheckNegativeZero(m_node->arithMode())) {
1524                 LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("ArithMul slow case"));
1525                 LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithMul continuation"));
1526                 
1527                 m_out.branch(
1528                     m_out.notZero64(result), usually(continuation), rarely(slowCase));
1529                 
1530                 LBasicBlock lastNext = m_out.appendTo(slowCase, continuation);
1531                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(left, m_out.int64Zero));
1532                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(right, m_out.int64Zero));
1533                 m_out.jump(continuation);
1534                 m_out.appendTo(continuation, lastNext);
1535             }
1536             
1537             setInt52(result);
1538             break;
1539         }
1540             
1541         case DoubleRepUse: {
1542             setDouble(
1543                 m_out.doubleMul(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
1544             break;
1545         }
1546
1547         case UntypedUse: {
1548             emitBinarySnippet<JITMulGenerator>(operationValueMul);
1549             break;
1550         }
1551
1552         default:
1553             DFG_CRASH(m_graph, m_node, "Bad use kind");
1554             break;
1555         }
1556     }
1557
1558     void compileArithDiv()
1559     {
1560         switch (m_node->binaryUseKind()) {
1561         case Int32Use: {
1562             LValue numerator = lowInt32(m_node->child1());
1563             LValue denominator = lowInt32(m_node->child2());
1564
1565             if (shouldCheckNegativeZero(m_node->arithMode())) {
1566                 LBasicBlock zeroNumerator = FTL_NEW_BLOCK(m_out, ("ArithDiv zero numerator"));
1567                 LBasicBlock numeratorContinuation = FTL_NEW_BLOCK(m_out, ("ArithDiv numerator continuation"));
1568
1569                 m_out.branch(
1570                     m_out.isZero32(numerator),
1571                     rarely(zeroNumerator), usually(numeratorContinuation));
1572
1573                 LBasicBlock innerLastNext = m_out.appendTo(zeroNumerator, numeratorContinuation);
1574
1575                 speculate(
1576                     NegativeZero, noValue(), 0, m_out.lessThan(denominator, m_out.int32Zero));
1577
1578                 m_out.jump(numeratorContinuation);
1579
1580                 m_out.appendTo(numeratorContinuation, innerLastNext);
1581             }
1582             
1583             if (shouldCheckOverflow(m_node->arithMode())) {
1584                 LBasicBlock unsafeDenominator = FTL_NEW_BLOCK(m_out, ("ArithDiv unsafe denominator"));
1585                 LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithDiv continuation"));
1586
1587                 LValue adjustedDenominator = m_out.add(denominator, m_out.int32One);
1588                 m_out.branch(
1589                     m_out.above(adjustedDenominator, m_out.int32One),
1590                     usually(continuation), rarely(unsafeDenominator));
1591
1592                 LBasicBlock lastNext = m_out.appendTo(unsafeDenominator, continuation);
1593                 LValue neg2ToThe31 = m_out.constInt32(-2147483647-1);
1594                 speculate(Overflow, noValue(), nullptr, m_out.isZero32(denominator));
1595                 speculate(Overflow, noValue(), nullptr, m_out.equal(numerator, neg2ToThe31));
1596                 m_out.jump(continuation);
1597
1598                 m_out.appendTo(continuation, lastNext);
1599                 LValue result = m_out.div(numerator, denominator);
1600                 speculate(
1601                     Overflow, noValue(), 0,
1602                     m_out.notEqual(m_out.mul(result, denominator), numerator));
1603                 setInt32(result);
1604             } else
1605                 setInt32(m_out.chillDiv(numerator, denominator));
1606
1607             break;
1608         }
1609             
1610         case DoubleRepUse: {
1611             setDouble(m_out.doubleDiv(
1612                 lowDouble(m_node->child1()), lowDouble(m_node->child2())));
1613             break;
1614         }
1615
1616         case UntypedUse: {
1617             emitBinarySnippet<JITDivGenerator, NeedScratchFPR>(operationValueDiv);
1618             break;
1619         }
1620
1621         default:
1622             DFG_CRASH(m_graph, m_node, "Bad use kind");
1623             break;
1624         }
1625     }
1626     
1627     void compileArithMod()
1628     {
1629         switch (m_node->binaryUseKind()) {
1630         case Int32Use: {
1631             LValue numerator = lowInt32(m_node->child1());
1632             LValue denominator = lowInt32(m_node->child2());
1633
1634             LValue remainder;
1635             if (shouldCheckOverflow(m_node->arithMode())) {
1636                 LBasicBlock unsafeDenominator = FTL_NEW_BLOCK(m_out, ("ArithMod unsafe denominator"));
1637                 LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithMod continuation"));
1638
1639                 LValue adjustedDenominator = m_out.add(denominator, m_out.int32One);
1640                 m_out.branch(
1641                     m_out.above(adjustedDenominator, m_out.int32One),
1642                     usually(continuation), rarely(unsafeDenominator));
1643
1644                 LBasicBlock lastNext = m_out.appendTo(unsafeDenominator, continuation);
1645                 LValue neg2ToThe31 = m_out.constInt32(-2147483647-1);
1646                 speculate(Overflow, noValue(), nullptr, m_out.isZero32(denominator));
1647                 speculate(Overflow, noValue(), nullptr, m_out.equal(numerator, neg2ToThe31));
1648                 m_out.jump(continuation);
1649
1650                 m_out.appendTo(continuation, lastNext);
1651                 LValue result = m_out.mod(numerator, denominator);
1652                 remainder = result;
1653             } else
1654                 remainder = m_out.chillMod(numerator, denominator);
1655
1656             if (shouldCheckNegativeZero(m_node->arithMode())) {
1657                 LBasicBlock negativeNumerator = FTL_NEW_BLOCK(m_out, ("ArithMod negative numerator"));
1658                 LBasicBlock numeratorContinuation = FTL_NEW_BLOCK(m_out, ("ArithMod numerator continuation"));
1659
1660                 m_out.branch(
1661                     m_out.lessThan(numerator, m_out.int32Zero),
1662                     unsure(negativeNumerator), unsure(numeratorContinuation));
1663
1664                 LBasicBlock innerLastNext = m_out.appendTo(negativeNumerator, numeratorContinuation);
1665
1666                 speculate(NegativeZero, noValue(), 0, m_out.isZero32(remainder));
1667
1668                 m_out.jump(numeratorContinuation);
1669
1670                 m_out.appendTo(numeratorContinuation, innerLastNext);
1671             }
1672
1673             setInt32(remainder);
1674             break;
1675         }
1676             
1677         case DoubleRepUse: {
1678             setDouble(
1679                 m_out.doubleMod(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
1680             break;
1681         }
1682             
1683         default:
1684             DFG_CRASH(m_graph, m_node, "Bad use kind");
1685             break;
1686         }
1687     }
1688
1689     void compileArithMinOrMax()
1690     {
1691         switch (m_node->binaryUseKind()) {
1692         case Int32Use: {
1693             LValue left = lowInt32(m_node->child1());
1694             LValue right = lowInt32(m_node->child2());
1695             
1696             setInt32(
1697                 m_out.select(
1698                     m_node->op() == ArithMin
1699                         ? m_out.lessThan(left, right)
1700                         : m_out.lessThan(right, left),
1701                     left, right));
1702             break;
1703         }
1704             
1705         case DoubleRepUse: {
1706             LValue left = lowDouble(m_node->child1());
1707             LValue right = lowDouble(m_node->child2());
1708             
1709             LBasicBlock notLessThan = FTL_NEW_BLOCK(m_out, ("ArithMin/ArithMax not less than"));
1710             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithMin/ArithMax continuation"));
1711             
1712             Vector<ValueFromBlock, 2> results;
1713             
1714             results.append(m_out.anchor(left));
1715             m_out.branch(
1716                 m_node->op() == ArithMin
1717                     ? m_out.doubleLessThan(left, right)
1718                     : m_out.doubleGreaterThan(left, right),
1719                 unsure(continuation), unsure(notLessThan));
1720             
1721             LBasicBlock lastNext = m_out.appendTo(notLessThan, continuation);
1722             results.append(m_out.anchor(m_out.select(
1723                 m_node->op() == ArithMin
1724                     ? m_out.doubleGreaterThanOrEqual(left, right)
1725                     : m_out.doubleLessThanOrEqual(left, right),
1726                 right, m_out.constDouble(PNaN))));
1727             m_out.jump(continuation);
1728             
1729             m_out.appendTo(continuation, lastNext);
1730             setDouble(m_out.phi(m_out.doubleType, results));
1731             break;
1732         }
1733             
1734         default:
1735             DFG_CRASH(m_graph, m_node, "Bad use kind");
1736             break;
1737         }
1738     }
1739     
1740     void compileArithAbs()
1741     {
1742         switch (m_node->child1().useKind()) {
1743         case Int32Use: {
1744             LValue value = lowInt32(m_node->child1());
1745
1746             LValue mask = m_out.aShr(value, m_out.constInt32(31));
1747             LValue result = m_out.bitXor(mask, m_out.add(mask, value));
1748
1749             if (shouldCheckOverflow(m_node->arithMode()))
1750                 speculate(Overflow, noValue(), 0, m_out.equal(result, m_out.constInt32(1 << 31)));
1751
1752             setInt32(result);
1753             break;
1754         }
1755             
1756         case DoubleRepUse: {
1757             setDouble(m_out.doubleAbs(lowDouble(m_node->child1())));
1758             break;
1759         }
1760             
1761         default:
1762             DFG_CRASH(m_graph, m_node, "Bad use kind");
1763             break;
1764         }
1765     }
1766
1767     void compileArithSin() { setDouble(m_out.doubleSin(lowDouble(m_node->child1()))); }
1768
1769     void compileArithCos() { setDouble(m_out.doubleCos(lowDouble(m_node->child1()))); }
1770
1771     void compileArithPow()
1772     {
1773         if (m_node->child2().useKind() == Int32Use)
1774             setDouble(m_out.doublePowi(lowDouble(m_node->child1()), lowInt32(m_node->child2())));
1775         else {
1776             LValue base = lowDouble(m_node->child1());
1777             LValue exponent = lowDouble(m_node->child2());
1778
1779             LBasicBlock integerExponentIsSmallBlock = FTL_NEW_BLOCK(m_out, ("ArithPow test integer exponent is small."));
1780             LBasicBlock integerExponentPowBlock = FTL_NEW_BLOCK(m_out, ("ArithPow pow(double, (int)double)."));
1781             LBasicBlock doubleExponentPowBlockEntry = FTL_NEW_BLOCK(m_out, ("ArithPow pow(double, double)."));
1782             LBasicBlock nanExceptionExponentIsInfinity = FTL_NEW_BLOCK(m_out, ("ArithPow NaN Exception, check exponent is infinity."));
1783             LBasicBlock nanExceptionBaseIsOne = FTL_NEW_BLOCK(m_out, ("ArithPow NaN Exception, check base is one."));
1784             LBasicBlock powBlock = FTL_NEW_BLOCK(m_out, ("ArithPow regular pow"));
1785             LBasicBlock nanExceptionResultIsNaN = FTL_NEW_BLOCK(m_out, ("ArithPow NaN Exception, result is NaN."));
1786             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithPow continuation"));
1787
1788             LValue integerExponent = m_out.doubleToInt(exponent);
1789             LValue integerExponentConvertedToDouble = m_out.intToDouble(integerExponent);
1790             LValue exponentIsInteger = m_out.doubleEqual(exponent, integerExponentConvertedToDouble);
1791             m_out.branch(exponentIsInteger, unsure(integerExponentIsSmallBlock), unsure(doubleExponentPowBlockEntry));
1792
1793             LBasicBlock lastNext = m_out.appendTo(integerExponentIsSmallBlock, integerExponentPowBlock);
1794             LValue integerExponentBelow1000 = m_out.below(integerExponent, m_out.constInt32(1000));
1795             m_out.branch(integerExponentBelow1000, usually(integerExponentPowBlock), rarely(doubleExponentPowBlockEntry));
1796
1797             m_out.appendTo(integerExponentPowBlock, doubleExponentPowBlockEntry);
1798             ValueFromBlock powDoubleIntResult = m_out.anchor(m_out.doublePowi(base, integerExponent));
1799             m_out.jump(continuation);
1800
1801             // If y is NaN, the result is NaN.
1802             m_out.appendTo(doubleExponentPowBlockEntry, nanExceptionExponentIsInfinity);
1803             LValue exponentIsNaN;
1804             if (provenType(m_node->child2()) & SpecDoubleNaN)
1805                 exponentIsNaN = m_out.doubleNotEqualOrUnordered(exponent, exponent);
1806             else
1807                 exponentIsNaN = m_out.booleanFalse;
1808             m_out.branch(exponentIsNaN, rarely(nanExceptionResultIsNaN), usually(nanExceptionExponentIsInfinity));
1809
1810             // If abs(x) is 1 and y is +infinity, the result is NaN.
1811             // If abs(x) is 1 and y is -infinity, the result is NaN.
1812             m_out.appendTo(nanExceptionExponentIsInfinity, nanExceptionBaseIsOne);
1813             LValue absoluteExponent = m_out.doubleAbs(exponent);
1814             LValue absoluteExponentIsInfinity = m_out.doubleEqual(absoluteExponent, m_out.constDouble(std::numeric_limits<double>::infinity()));
1815             m_out.branch(absoluteExponentIsInfinity, rarely(nanExceptionBaseIsOne), usually(powBlock));
1816
1817             m_out.appendTo(nanExceptionBaseIsOne, powBlock);
1818             LValue absoluteBase = m_out.doubleAbs(base);
1819             LValue absoluteBaseIsOne = m_out.doubleEqual(absoluteBase, m_out.constDouble(1));
1820             m_out.branch(absoluteBaseIsOne, unsure(nanExceptionResultIsNaN), unsure(powBlock));
1821
1822             m_out.appendTo(powBlock, nanExceptionResultIsNaN);
1823             ValueFromBlock powResult = m_out.anchor(m_out.doublePow(base, exponent));
1824             m_out.jump(continuation);
1825
1826             m_out.appendTo(nanExceptionResultIsNaN, continuation);
1827             ValueFromBlock pureNan = m_out.anchor(m_out.constDouble(PNaN));
1828             m_out.jump(continuation);
1829
1830             m_out.appendTo(continuation, lastNext);
1831             setDouble(m_out.phi(m_out.doubleType, powDoubleIntResult, powResult, pureNan));
1832         }
1833     }
1834
1835     void compileArithRandom()
1836     {
1837         JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
1838
1839         // Inlined WeakRandom::advance().
1840         // uint64_t x = m_low;
1841         void* lowAddress = reinterpret_cast<uint8_t*>(globalObject) + JSGlobalObject::weakRandomOffset() + WeakRandom::lowOffset();
1842         LValue low = m_out.load64(m_out.absolute(lowAddress));
1843         // uint64_t y = m_high;
1844         void* highAddress = reinterpret_cast<uint8_t*>(globalObject) + JSGlobalObject::weakRandomOffset() + WeakRandom::highOffset();
1845         LValue high = m_out.load64(m_out.absolute(highAddress));
1846         // m_low = y;
1847         m_out.store64(high, m_out.absolute(lowAddress));
1848
1849         // x ^= x << 23;
1850         LValue phase1 = m_out.bitXor(m_out.shl(low, m_out.constInt64(23)), low);
1851
1852         // x ^= x >> 17;
1853         LValue phase2 = m_out.bitXor(m_out.lShr(phase1, m_out.constInt64(17)), phase1);
1854
1855         // x ^= y ^ (y >> 26);
1856         LValue phase3 = m_out.bitXor(m_out.bitXor(high, m_out.lShr(high, m_out.constInt64(26))), phase2);
1857
1858         // m_high = x;
1859         m_out.store64(phase3, m_out.absolute(highAddress));
1860
1861         // return x + y;
1862         LValue random64 = m_out.add(phase3, high);
1863
1864         // Extract random 53bit. [0, 53] bit is safe integer number ranges in double representation.
1865         LValue random53 = m_out.bitAnd(random64, m_out.constInt64((1ULL << 53) - 1));
1866
1867         LValue double53Integer = m_out.intToDouble(random53);
1868
1869         // Convert `(53bit double integer value) / (1 << 53)` to `(53bit double integer value) * (1.0 / (1 << 53))`.
1870         // In latter case, `1.0 / (1 << 53)` will become a double value represented as (mantissa = 0 & exp = 970, it means 1e-(2**54)).
1871         static const double scale = 1.0 / (1ULL << 53);
1872
1873         // Multiplying 1e-(2**54) with the double integer does not change anything of the mantissa part of the double integer.
1874         // It just reduces the exp part of the given 53bit double integer.
1875         // (Except for 0.0. This is specially handled and in this case, exp just becomes 0.)
1876         // Now we get 53bit precision random double value in [0, 1).
1877         LValue result = m_out.doubleMul(double53Integer, m_out.constDouble(scale));
1878
1879         setDouble(result);
1880     }
1881
1882     void compileArithRound()
1883     {
1884         LBasicBlock realPartIsMoreThanHalf = FTL_NEW_BLOCK(m_out, ("ArithRound should round down"));
1885         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithRound continuation"));
1886
1887         LValue value = lowDouble(m_node->child1());
1888         LValue integerValue = m_out.doubleCeil(value);
1889         ValueFromBlock integerValueResult = m_out.anchor(integerValue);
1890
1891         LValue realPart = m_out.doubleSub(integerValue, value);
1892
1893         m_out.branch(m_out.doubleGreaterThanOrUnordered(realPart, m_out.constDouble(0.5)), unsure(realPartIsMoreThanHalf), unsure(continuation));
1894
1895         LBasicBlock lastNext = m_out.appendTo(realPartIsMoreThanHalf, continuation);
1896         LValue integerValueRoundedDown = m_out.doubleSub(integerValue, m_out.constDouble(1));
1897         ValueFromBlock integerValueRoundedDownResult = m_out.anchor(integerValueRoundedDown);
1898         m_out.jump(continuation);
1899         m_out.appendTo(continuation, lastNext);
1900
1901         LValue result = m_out.phi(m_out.doubleType, integerValueResult, integerValueRoundedDownResult);
1902
1903         if (producesInteger(m_node->arithRoundingMode())) {
1904             LValue integerValue = convertDoubleToInt32(result, shouldCheckNegativeZero(m_node->arithRoundingMode()));
1905             setInt32(integerValue);
1906         } else
1907             setDouble(result);
1908     }
1909
1910     void compileArithSqrt() { setDouble(m_out.doubleSqrt(lowDouble(m_node->child1()))); }
1911
1912     void compileArithLog() { setDouble(m_out.doubleLog(lowDouble(m_node->child1()))); }
1913     
1914     void compileArithFRound()
1915     {
1916         setDouble(m_out.fround(lowDouble(m_node->child1())));
1917     }
1918     
1919     void compileArithNegate()
1920     {
1921         switch (m_node->child1().useKind()) {
1922         case Int32Use: {
1923             LValue value = lowInt32(m_node->child1());
1924             
1925             LValue result;
1926             if (!shouldCheckOverflow(m_node->arithMode()))
1927                 result = m_out.neg(value);
1928             else if (!shouldCheckNegativeZero(m_node->arithMode())) {
1929                 CheckValue* check = m_out.speculateSub(m_out.int32Zero, value);
1930                 blessSpeculation(check, Overflow, noValue(), nullptr, m_origin);
1931                 result = check;
1932             } else {
1933                 speculate(Overflow, noValue(), 0, m_out.testIsZero32(value, m_out.constInt32(0x7fffffff)));
1934                 result = m_out.neg(value);
1935             }
1936
1937             setInt32(result);
1938             break;
1939         }
1940             
1941         case Int52RepUse: {
1942             if (!abstractValue(m_node->child1()).couldBeType(SpecInt52)) {
1943                 Int52Kind kind;
1944                 LValue value = lowWhicheverInt52(m_node->child1(), kind);
1945                 LValue result = m_out.neg(value);
1946                 if (shouldCheckNegativeZero(m_node->arithMode()))
1947                     speculate(NegativeZero, noValue(), 0, m_out.isZero64(result));
1948                 setInt52(result, kind);
1949                 break;
1950             }
1951             
1952             LValue value = lowInt52(m_node->child1());
1953             CheckValue* result = m_out.speculateSub(m_out.int64Zero, value);
1954             blessSpeculation(result, Int52Overflow, noValue(), nullptr, m_origin);
1955             speculate(NegativeZero, noValue(), 0, m_out.isZero64(result));
1956             setInt52(result);
1957             break;
1958         }
1959             
1960         case DoubleRepUse: {
1961             setDouble(m_out.doubleNeg(lowDouble(m_node->child1())));
1962             break;
1963         }
1964             
1965         default:
1966             DFG_CRASH(m_graph, m_node, "Bad use kind");
1967             break;
1968         }
1969     }
1970     
1971     void compileBitAnd()
1972     {
1973         if (m_node->isBinaryUseKind(UntypedUse)) {
1974             emitBinaryBitOpSnippet<JITBitAndGenerator>(operationValueBitAnd);
1975             return;
1976         }
1977         setInt32(m_out.bitAnd(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
1978     }
1979     
1980     void compileBitOr()
1981     {
1982         if (m_node->isBinaryUseKind(UntypedUse)) {
1983             emitBinaryBitOpSnippet<JITBitOrGenerator>(operationValueBitOr);
1984             return;
1985         }
1986         setInt32(m_out.bitOr(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
1987     }
1988     
1989     void compileBitXor()
1990     {
1991         if (m_node->isBinaryUseKind(UntypedUse)) {
1992             emitBinaryBitOpSnippet<JITBitXorGenerator>(operationValueBitXor);
1993             return;
1994         }
1995         setInt32(m_out.bitXor(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
1996     }
1997     
1998     void compileBitRShift()
1999     {
2000         if (m_node->isBinaryUseKind(UntypedUse)) {
2001             emitRightShiftSnippet(JITRightShiftGenerator::SignedShift);
2002             return;
2003         }
2004         setInt32(m_out.aShr(
2005             lowInt32(m_node->child1()),
2006             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2007     }
2008     
2009     void compileBitLShift()
2010     {
2011         if (m_node->isBinaryUseKind(UntypedUse)) {
2012             emitBinaryBitOpSnippet<JITLeftShiftGenerator>(operationValueBitLShift);
2013             return;
2014         }
2015         setInt32(m_out.shl(
2016             lowInt32(m_node->child1()),
2017             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2018     }
2019     
2020     void compileBitURShift()
2021     {
2022         if (m_node->isBinaryUseKind(UntypedUse)) {
2023             emitRightShiftSnippet(JITRightShiftGenerator::UnsignedShift);
2024             return;
2025         }
2026         setInt32(m_out.lShr(
2027             lowInt32(m_node->child1()),
2028             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2029     }
2030     
2031     void compileUInt32ToNumber()
2032     {
2033         LValue value = lowInt32(m_node->child1());
2034
2035         if (doesOverflow(m_node->arithMode())) {
2036             setDouble(m_out.unsignedToDouble(value));
2037             return;
2038         }
2039         
2040         speculate(Overflow, noValue(), 0, m_out.lessThan(value, m_out.int32Zero));
2041         setInt32(value);
2042     }
2043     
2044     void compileCheckStructure()
2045     {
2046         ExitKind exitKind;
2047         if (m_node->child1()->hasConstant())
2048             exitKind = BadConstantCache;
2049         else
2050             exitKind = BadCache;
2051
2052         switch (m_node->child1().useKind()) {
2053         case CellUse:
2054         case KnownCellUse: {
2055             LValue cell = lowCell(m_node->child1());
2056             
2057             checkStructure(
2058                 m_out.load32(cell, m_heaps.JSCell_structureID), jsValueValue(cell),
2059                 exitKind, m_node->structureSet(),
2060                 [&] (Structure* structure) {
2061                     return weakStructureID(structure);
2062                 });
2063             return;
2064         }
2065
2066         case CellOrOtherUse: {
2067             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
2068
2069             LBasicBlock cellCase = FTL_NEW_BLOCK(m_out, ("CheckStructure CellOrOtherUse cell case"));
2070             LBasicBlock notCellCase = FTL_NEW_BLOCK(m_out, ("CheckStructure CellOrOtherUse not cell case"));
2071             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("CheckStructure CellOrOtherUse continuation"));
2072
2073             m_out.branch(
2074                 isCell(value, provenType(m_node->child1())), unsure(cellCase), unsure(notCellCase));
2075
2076             LBasicBlock lastNext = m_out.appendTo(cellCase, notCellCase);
2077             checkStructure(
2078                 m_out.load32(value, m_heaps.JSCell_structureID), jsValueValue(value),
2079                 exitKind, m_node->structureSet(),
2080                 [&] (Structure* structure) {
2081                     return weakStructureID(structure);
2082                 });
2083             m_out.jump(continuation);
2084
2085             m_out.appendTo(notCellCase, continuation);
2086             FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), SpecCell | SpecOther, isNotOther(value));
2087             m_out.jump(continuation);
2088
2089             m_out.appendTo(continuation, lastNext);
2090             return;
2091         }
2092
2093         default:
2094             DFG_CRASH(m_graph, m_node, "Bad use kind");
2095             return;
2096         }
2097     }
2098     
2099     void compileCheckCell()
2100     {
2101         LValue cell = lowCell(m_node->child1());
2102         
2103         speculate(
2104             BadCell, jsValueValue(cell), m_node->child1().node(),
2105             m_out.notEqual(cell, weakPointer(m_node->cellOperand()->cell())));
2106     }
2107     
2108     void compileCheckBadCell()
2109     {
2110         terminate(BadCell);
2111     }
2112
2113     void compileCheckNotEmpty()
2114     {
2115         speculate(TDZFailure, noValue(), nullptr, m_out.isZero64(lowJSValue(m_node->child1())));
2116     }
2117
2118     void compileCheckIdent()
2119     {
2120         UniquedStringImpl* uid = m_node->uidOperand();
2121         if (uid->isSymbol()) {
2122             LValue symbol = lowSymbol(m_node->child1());
2123             LValue stringImpl = m_out.loadPtr(symbol, m_heaps.Symbol_privateName);
2124             speculate(BadIdent, noValue(), nullptr, m_out.notEqual(stringImpl, m_out.constIntPtr(uid)));
2125         } else {
2126             LValue string = lowStringIdent(m_node->child1());
2127             LValue stringImpl = m_out.loadPtr(string, m_heaps.JSString_value);
2128             speculate(BadIdent, noValue(), nullptr, m_out.notEqual(stringImpl, m_out.constIntPtr(uid)));
2129         }
2130     }
2131
2132     void compileGetExecutable()
2133     {
2134         LValue cell = lowCell(m_node->child1());
2135         speculateFunction(m_node->child1(), cell);
2136         setJSValue(m_out.loadPtr(cell, m_heaps.JSFunction_executable));
2137     }
2138     
2139     void compileArrayifyToStructure()
2140     {
2141         LValue cell = lowCell(m_node->child1());
2142         LValue property = !!m_node->child2() ? lowInt32(m_node->child2()) : 0;
2143         
2144         LBasicBlock unexpectedStructure = FTL_NEW_BLOCK(m_out, ("ArrayifyToStructure unexpected structure"));
2145         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArrayifyToStructure continuation"));
2146         
2147         LValue structureID = m_out.load32(cell, m_heaps.JSCell_structureID);
2148         
2149         m_out.branch(
2150             m_out.notEqual(structureID, weakStructureID(m_node->structure())),
2151             rarely(unexpectedStructure), usually(continuation));
2152         
2153         LBasicBlock lastNext = m_out.appendTo(unexpectedStructure, continuation);
2154         
2155         if (property) {
2156             switch (m_node->arrayMode().type()) {
2157             case Array::Int32:
2158             case Array::Double:
2159             case Array::Contiguous:
2160                 speculate(
2161                     Uncountable, noValue(), 0,
2162                     m_out.aboveOrEqual(property, m_out.constInt32(MIN_SPARSE_ARRAY_INDEX)));
2163                 break;
2164             default:
2165                 break;
2166             }
2167         }
2168         
2169         switch (m_node->arrayMode().type()) {
2170         case Array::Int32:
2171             vmCall(m_out.voidType, m_out.operation(operationEnsureInt32), m_callFrame, cell);
2172             break;
2173         case Array::Double:
2174             vmCall(m_out.voidType, m_out.operation(operationEnsureDouble), m_callFrame, cell);
2175             break;
2176         case Array::Contiguous:
2177             vmCall(m_out.voidType, m_out.operation(operationEnsureContiguous), m_callFrame, cell);
2178             break;
2179         case Array::ArrayStorage:
2180         case Array::SlowPutArrayStorage:
2181             vmCall(m_out.voidType, m_out.operation(operationEnsureArrayStorage), m_callFrame, cell);
2182             break;
2183         default:
2184             DFG_CRASH(m_graph, m_node, "Bad array type");
2185             break;
2186         }
2187         
2188         structureID = m_out.load32(cell, m_heaps.JSCell_structureID);
2189         speculate(
2190             BadIndexingType, jsValueValue(cell), 0,
2191             m_out.notEqual(structureID, weakStructureID(m_node->structure())));
2192         m_out.jump(continuation);
2193         
2194         m_out.appendTo(continuation, lastNext);
2195     }
2196     
2197     void compilePutStructure()
2198     {
2199         m_ftlState.jitCode->common.notifyCompilingStructureTransition(m_graph.m_plan, codeBlock(), m_node);
2200
2201         Structure* oldStructure = m_node->transition()->previous;
2202         Structure* newStructure = m_node->transition()->next;
2203         ASSERT_UNUSED(oldStructure, oldStructure->indexingType() == newStructure->indexingType());
2204         ASSERT(oldStructure->typeInfo().inlineTypeFlags() == newStructure->typeInfo().inlineTypeFlags());
2205         ASSERT(oldStructure->typeInfo().type() == newStructure->typeInfo().type());
2206
2207         LValue cell = lowCell(m_node->child1()); 
2208         m_out.store32(
2209             weakStructureID(newStructure),
2210             cell, m_heaps.JSCell_structureID);
2211     }
2212     
2213     void compileGetById()
2214     {
2215         switch (m_node->child1().useKind()) {
2216         case CellUse: {
2217             setJSValue(getById(lowCell(m_node->child1())));
2218             return;
2219         }
2220             
2221         case UntypedUse: {
2222             // This is pretty weird, since we duplicate the slow path both here and in the
2223             // code generated by the IC. We should investigate making this less bad.
2224             // https://bugs.webkit.org/show_bug.cgi?id=127830
2225             LValue value = lowJSValue(m_node->child1());
2226             
2227             LBasicBlock cellCase = FTL_NEW_BLOCK(m_out, ("GetById untyped cell case"));
2228             LBasicBlock notCellCase = FTL_NEW_BLOCK(m_out, ("GetById untyped not cell case"));
2229             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetById untyped continuation"));
2230             
2231             m_out.branch(
2232                 isCell(value, provenType(m_node->child1())), unsure(cellCase), unsure(notCellCase));
2233             
2234             LBasicBlock lastNext = m_out.appendTo(cellCase, notCellCase);
2235             ValueFromBlock cellResult = m_out.anchor(getById(value));
2236             m_out.jump(continuation);
2237             
2238             m_out.appendTo(notCellCase, continuation);
2239             ValueFromBlock notCellResult = m_out.anchor(vmCall(
2240                 m_out.int64, m_out.operation(operationGetByIdGeneric),
2241                 m_callFrame, value,
2242                 m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()])));
2243             m_out.jump(continuation);
2244             
2245             m_out.appendTo(continuation, lastNext);
2246             setJSValue(m_out.phi(m_out.int64, cellResult, notCellResult));
2247             return;
2248         }
2249             
2250         default:
2251             DFG_CRASH(m_graph, m_node, "Bad use kind");
2252             return;
2253         }
2254     }
2255     
2256     void compilePutById()
2257     {
2258         Node* node = m_node;
2259         
2260         // See above; CellUse is easier so we do only that for now.
2261         ASSERT(node->child1().useKind() == CellUse);
2262
2263         LValue base = lowCell(node->child1());
2264         LValue value = lowJSValue(node->child2());
2265         auto uid = m_graph.identifiers()[node->identifierNumber()];
2266
2267         B3::PatchpointValue* patchpoint = m_out.patchpoint(Void);
2268         patchpoint->appendSomeRegister(base);
2269         patchpoint->appendSomeRegister(value);
2270         patchpoint->clobber(RegisterSet::macroScratchRegisters());
2271
2272         // FIXME: If this is a PutByIdFlush, we might want to late-clobber volatile registers.
2273         // https://bugs.webkit.org/show_bug.cgi?id=152848
2274
2275         RefPtr<PatchpointExceptionHandle> exceptionHandle =
2276             preparePatchpointForExceptions(patchpoint);
2277
2278         State* state = &m_ftlState;
2279         ECMAMode ecmaMode = m_graph.executableFor(node->origin.semantic)->ecmaMode();
2280         
2281         patchpoint->setGenerator(
2282             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
2283                 AllowMacroScratchRegisterUsage allowScratch(jit);
2284
2285                 CallSiteIndex callSiteIndex =
2286                     state->jitCode->common.addUniqueCallSiteIndex(node->origin.semantic);
2287
2288                 Box<CCallHelpers::JumpList> exceptions =
2289                     exceptionHandle->scheduleExitCreation(params)->jumps(jit);
2290
2291                 // JS setter call ICs generated by the PutById IC will need this.
2292                 exceptionHandle->scheduleExitCreationForUnwind(params, callSiteIndex);
2293
2294                 auto generator = Box<JITPutByIdGenerator>::create(
2295                     jit.codeBlock(), node->origin.semantic, callSiteIndex,
2296                     params.unavailableRegisters(), JSValueRegs(params[0].gpr()),
2297                     JSValueRegs(params[1].gpr()), GPRInfo::patchpointScratchRegister, ecmaMode,
2298                     node->op() == PutByIdDirect ? Direct : NotDirect);
2299
2300                 generator->generateFastPath(jit);
2301                 CCallHelpers::Label done = jit.label();
2302
2303                 params.addLatePath(
2304                     [=] (CCallHelpers& jit) {
2305                         AllowMacroScratchRegisterUsage allowScratch(jit);
2306
2307                         generator->slowPathJump().link(&jit);
2308                         CCallHelpers::Label slowPathBegin = jit.label();
2309                         CCallHelpers::Call slowPathCall = callOperation(
2310                             *state, params.unavailableRegisters(), jit, node->origin.semantic,
2311                             exceptions.get(), generator->slowPathFunction(), InvalidGPRReg,
2312                             CCallHelpers::TrustedImmPtr(generator->stubInfo()), params[1].gpr(),
2313                             params[0].gpr(), CCallHelpers::TrustedImmPtr(uid)).call();
2314                         jit.jump().linkTo(done, &jit);
2315
2316                         generator->reportSlowPathCall(slowPathBegin, slowPathCall);
2317
2318                         jit.addLinkTask(
2319                             [=] (LinkBuffer& linkBuffer) {
2320                                 generator->finalize(linkBuffer);
2321                             });
2322                     });
2323             });
2324     }
2325     
2326     void compileGetButterfly()
2327     {
2328         setStorage(loadButterflyWithBarrier(lowCell(m_node->child1())));
2329     }
2330
2331     void compileGetButterflyReadOnly()
2332     {
2333         setStorage(loadButterflyReadOnly(lowCell(m_node->child1())));
2334     }
2335     
2336     void compileConstantStoragePointer()
2337     {
2338         setStorage(m_out.constIntPtr(m_node->storagePointer()));
2339     }
2340     
2341     void compileGetIndexedPropertyStorage()
2342     {
2343         LValue cell = lowCell(m_node->child1());
2344         
2345         if (m_node->arrayMode().type() == Array::String) {
2346             LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("GetIndexedPropertyStorage String slow case"));
2347             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetIndexedPropertyStorage String continuation"));
2348
2349             LValue fastResultValue = m_out.loadPtr(cell, m_heaps.JSString_value);
2350             ValueFromBlock fastResult = m_out.anchor(fastResultValue);
2351             
2352             m_out.branch(
2353                 m_out.notNull(fastResultValue), usually(continuation), rarely(slowPath));
2354             
2355             LBasicBlock lastNext = m_out.appendTo(slowPath, continuation);
2356             
2357             ValueFromBlock slowResult = m_out.anchor(
2358                 vmCall(m_out.intPtr, m_out.operation(operationResolveRope), m_callFrame, cell));
2359             
2360             m_out.jump(continuation);
2361             
2362             m_out.appendTo(continuation, lastNext);
2363             
2364             setStorage(m_out.loadPtr(m_out.phi(m_out.intPtr, fastResult, slowResult), m_heaps.StringImpl_data));
2365             return;
2366         }
2367         
2368         setStorage(loadVectorWithBarrier(cell));
2369     }
2370     
2371     void compileCheckArray()
2372     {
2373         Edge edge = m_node->child1();
2374         LValue cell = lowCell(edge);
2375         
2376         if (m_node->arrayMode().alreadyChecked(m_graph, m_node, abstractValue(edge)))
2377             return;
2378         
2379         speculate(
2380             BadIndexingType, jsValueValue(cell), 0,
2381             m_out.logicalNot(isArrayType(cell, m_node->arrayMode())));
2382     }
2383
2384     void compileGetTypedArrayByteOffset()
2385     {
2386         LValue basePtr = lowCell(m_node->child1());    
2387
2388         LBasicBlock simpleCase = FTL_NEW_BLOCK(m_out, ("GetTypedArrayByteOffset wasteless typed array"));
2389         LBasicBlock wastefulCase = FTL_NEW_BLOCK(m_out, ("GetTypedArrayByteOffset wasteful typed array"));
2390         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetTypedArrayByteOffset continuation"));
2391         
2392         LValue mode = m_out.load32(basePtr, m_heaps.JSArrayBufferView_mode);
2393         m_out.branch(
2394             m_out.notEqual(mode, m_out.constInt32(WastefulTypedArray)),
2395             unsure(simpleCase), unsure(wastefulCase));
2396
2397         LBasicBlock lastNext = m_out.appendTo(simpleCase, wastefulCase);
2398
2399         ValueFromBlock simpleOut = m_out.anchor(m_out.constIntPtr(0));
2400
2401         m_out.jump(continuation);
2402
2403         m_out.appendTo(wastefulCase, continuation);
2404
2405         LValue vectorPtr = loadVectorReadOnly(basePtr);
2406         LValue butterflyPtr = loadButterflyReadOnly(basePtr);
2407         LValue arrayBufferPtr = m_out.loadPtr(butterflyPtr, m_heaps.Butterfly_arrayBuffer);
2408         LValue dataPtr = m_out.loadPtr(arrayBufferPtr, m_heaps.ArrayBuffer_data);
2409
2410         ValueFromBlock wastefulOut = m_out.anchor(m_out.sub(vectorPtr, dataPtr));
2411
2412         m_out.jump(continuation);
2413         m_out.appendTo(continuation, lastNext);
2414
2415         setInt32(m_out.castToInt32(m_out.phi(m_out.intPtr, simpleOut, wastefulOut)));
2416     }
2417     
2418     void compileGetArrayLength()
2419     {
2420         switch (m_node->arrayMode().type()) {
2421         case Array::Int32:
2422         case Array::Double:
2423         case Array::Contiguous: {
2424             setInt32(m_out.load32NonNegative(lowStorage(m_node->child2()), m_heaps.Butterfly_publicLength));
2425             return;
2426         }
2427             
2428         case Array::String: {
2429             LValue string = lowCell(m_node->child1());
2430             setInt32(m_out.load32NonNegative(string, m_heaps.JSString_length));
2431             return;
2432         }
2433             
2434         case Array::DirectArguments: {
2435             LValue arguments = lowCell(m_node->child1());
2436             speculate(
2437                 ExoticObjectMode, noValue(), nullptr,
2438                 m_out.notNull(m_out.loadPtr(arguments, m_heaps.DirectArguments_overrides)));
2439             setInt32(m_out.load32NonNegative(arguments, m_heaps.DirectArguments_length));
2440             return;
2441         }
2442             
2443         case Array::ScopedArguments: {
2444             LValue arguments = lowCell(m_node->child1());
2445             speculate(
2446                 ExoticObjectMode, noValue(), nullptr,
2447                 m_out.notZero32(m_out.load8ZeroExt32(arguments, m_heaps.ScopedArguments_overrodeThings)));
2448             setInt32(m_out.load32NonNegative(arguments, m_heaps.ScopedArguments_totalLength));
2449             return;
2450         }
2451             
2452         default:
2453             if (m_node->arrayMode().isSomeTypedArrayView()) {
2454                 setInt32(
2455                     m_out.load32NonNegative(lowCell(m_node->child1()), m_heaps.JSArrayBufferView_length));
2456                 return;
2457             }
2458             
2459             DFG_CRASH(m_graph, m_node, "Bad array type");
2460             return;
2461         }
2462     }
2463     
2464     void compileCheckInBounds()
2465     {
2466         speculate(
2467             OutOfBounds, noValue(), 0,
2468             m_out.aboveOrEqual(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2469     }
2470     
2471     void compileGetByVal()
2472     {
2473         switch (m_node->arrayMode().type()) {
2474         case Array::Int32:
2475         case Array::Contiguous: {
2476             LValue index = lowInt32(m_node->child2());
2477             LValue storage = lowStorage(m_node->child3());
2478             
2479             IndexedAbstractHeap& heap = m_node->arrayMode().type() == Array::Int32 ?
2480                 m_heaps.indexedInt32Properties : m_heaps.indexedContiguousProperties;
2481             
2482             if (m_node->arrayMode().isInBounds()) {
2483                 LValue result = m_out.load64(baseIndex(heap, storage, index, m_node->child2()));
2484                 LValue isHole = m_out.isZero64(result);
2485                 if (m_node->arrayMode().isSaneChain()) {
2486                     DFG_ASSERT(
2487                         m_graph, m_node, m_node->arrayMode().type() == Array::Contiguous);
2488                     result = m_out.select(
2489                         isHole, m_out.constInt64(JSValue::encode(jsUndefined())), result);
2490                 } else
2491                     speculate(LoadFromHole, noValue(), 0, isHole);
2492                 setJSValue(result);
2493                 return;
2494             }
2495             
2496             LValue base = lowCell(m_node->child1());
2497             
2498             LBasicBlock fastCase = FTL_NEW_BLOCK(m_out, ("GetByVal int/contiguous fast case"));
2499             LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("GetByVal int/contiguous slow case"));
2500             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetByVal int/contiguous continuation"));
2501             
2502             m_out.branch(
2503                 m_out.aboveOrEqual(
2504                     index, m_out.load32NonNegative(storage, m_heaps.Butterfly_publicLength)),
2505                 rarely(slowCase), usually(fastCase));
2506             
2507             LBasicBlock lastNext = m_out.appendTo(fastCase, slowCase);
2508
2509             LValue fastResultValue = m_out.load64(baseIndex(heap, storage, index, m_node->child2()));
2510             ValueFromBlock fastResult = m_out.anchor(fastResultValue);
2511             m_out.branch(
2512                 m_out.isZero64(fastResultValue), rarely(slowCase), usually(continuation));
2513             
2514             m_out.appendTo(slowCase, continuation);
2515             ValueFromBlock slowResult = m_out.anchor(
2516                 vmCall(m_out.int64, m_out.operation(operationGetByValArrayInt), m_callFrame, base, index));
2517             m_out.jump(continuation);
2518             
2519             m_out.appendTo(continuation, lastNext);
2520             setJSValue(m_out.phi(m_out.int64, fastResult, slowResult));
2521             return;
2522         }
2523             
2524         case Array::Double: {
2525             LValue index = lowInt32(m_node->child2());
2526             LValue storage = lowStorage(m_node->child3());
2527             
2528             IndexedAbstractHeap& heap = m_heaps.indexedDoubleProperties;
2529             
2530             if (m_node->arrayMode().isInBounds()) {
2531                 LValue result = m_out.loadDouble(
2532                     baseIndex(heap, storage, index, m_node->child2()));
2533                 
2534                 if (!m_node->arrayMode().isSaneChain()) {
2535                     speculate(
2536                         LoadFromHole, noValue(), 0,
2537                         m_out.doubleNotEqualOrUnordered(result, result));
2538                 }
2539                 setDouble(result);
2540                 break;
2541             }
2542             
2543             LValue base = lowCell(m_node->child1());
2544             
2545             LBasicBlock inBounds = FTL_NEW_BLOCK(m_out, ("GetByVal double in bounds"));
2546             LBasicBlock boxPath = FTL_NEW_BLOCK(m_out, ("GetByVal double boxing"));
2547             LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("GetByVal double slow case"));
2548             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetByVal double continuation"));
2549             
2550             m_out.branch(
2551                 m_out.aboveOrEqual(
2552                     index, m_out.load32NonNegative(storage, m_heaps.Butterfly_publicLength)),
2553                 rarely(slowCase), usually(inBounds));
2554             
2555             LBasicBlock lastNext = m_out.appendTo(inBounds, boxPath);
2556             LValue doubleValue = m_out.loadDouble(
2557                 baseIndex(heap, storage, index, m_node->child2()));
2558             m_out.branch(
2559                 m_out.doubleNotEqualOrUnordered(doubleValue, doubleValue),
2560                 rarely(slowCase), usually(boxPath));
2561             
2562             m_out.appendTo(boxPath, slowCase);
2563             ValueFromBlock fastResult = m_out.anchor(boxDouble(doubleValue));
2564             m_out.jump(continuation);
2565             
2566             m_out.appendTo(slowCase, continuation);
2567             ValueFromBlock slowResult = m_out.anchor(
2568                 vmCall(m_out.int64, m_out.operation(operationGetByValArrayInt), m_callFrame, base, index));
2569             m_out.jump(continuation);
2570             
2571             m_out.appendTo(continuation, lastNext);
2572             setJSValue(m_out.phi(m_out.int64, fastResult, slowResult));
2573             return;
2574         }
2575
2576         case Array::Undecided: {
2577             LValue index = lowInt32(m_node->child2());
2578
2579             speculate(OutOfBounds, noValue(), m_node, m_out.lessThan(index, m_out.int32Zero));
2580             setJSValue(m_out.constInt64(ValueUndefined));
2581             return;
2582         }
2583             
2584         case Array::DirectArguments: {
2585             LValue base = lowCell(m_node->child1());
2586             LValue index = lowInt32(m_node->child2());
2587             
2588             speculate(
2589                 ExoticObjectMode, noValue(), nullptr,
2590                 m_out.notNull(m_out.loadPtr(base, m_heaps.DirectArguments_overrides)));
2591             speculate(
2592                 ExoticObjectMode, noValue(), nullptr,
2593                 m_out.aboveOrEqual(
2594                     index,
2595                     m_out.load32NonNegative(base, m_heaps.DirectArguments_length)));
2596
2597             TypedPointer address = m_out.baseIndex(
2598                 m_heaps.DirectArguments_storage, base, m_out.zeroExtPtr(index));
2599             setJSValue(m_out.load64(address));
2600             return;
2601         }
2602             
2603         case Array::ScopedArguments: {
2604             LValue base = lowCell(m_node->child1());
2605             LValue index = lowInt32(m_node->child2());
2606             
2607             speculate(
2608                 ExoticObjectMode, noValue(), nullptr,
2609                 m_out.aboveOrEqual(
2610                     index,
2611                     m_out.load32NonNegative(base, m_heaps.ScopedArguments_totalLength)));
2612             
2613             LValue table = m_out.loadPtr(base, m_heaps.ScopedArguments_table);
2614             LValue namedLength = m_out.load32(table, m_heaps.ScopedArgumentsTable_length);
2615             
2616             LBasicBlock namedCase = FTL_NEW_BLOCK(m_out, ("GetByVal ScopedArguments named case"));
2617             LBasicBlock overflowCase = FTL_NEW_BLOCK(m_out, ("GetByVal ScopedArguments overflow case"));
2618             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetByVal ScopedArguments continuation"));
2619             
2620             m_out.branch(
2621                 m_out.aboveOrEqual(index, namedLength), unsure(overflowCase), unsure(namedCase));
2622             
2623             LBasicBlock lastNext = m_out.appendTo(namedCase, overflowCase);
2624             
2625             LValue scope = m_out.loadPtr(base, m_heaps.ScopedArguments_scope);
2626             LValue arguments = m_out.loadPtr(table, m_heaps.ScopedArgumentsTable_arguments);
2627             
2628             TypedPointer address = m_out.baseIndex(
2629                 m_heaps.scopedArgumentsTableArguments, arguments, m_out.zeroExtPtr(index));
2630             LValue scopeOffset = m_out.load32(address);
2631             
2632             speculate(
2633                 ExoticObjectMode, noValue(), nullptr,
2634                 m_out.equal(scopeOffset, m_out.constInt32(ScopeOffset::invalidOffset)));
2635             
2636             address = m_out.baseIndex(
2637                 m_heaps.JSEnvironmentRecord_variables, scope, m_out.zeroExtPtr(scopeOffset));
2638             ValueFromBlock namedResult = m_out.anchor(m_out.load64(address));
2639             m_out.jump(continuation);
2640             
2641             m_out.appendTo(overflowCase, continuation);
2642             
2643             address = m_out.baseIndex(
2644                 m_heaps.ScopedArguments_overflowStorage, base,
2645                 m_out.zeroExtPtr(m_out.sub(index, namedLength)));
2646             LValue overflowValue = m_out.load64(address);
2647             speculate(ExoticObjectMode, noValue(), nullptr, m_out.isZero64(overflowValue));
2648             ValueFromBlock overflowResult = m_out.anchor(overflowValue);
2649             m_out.jump(continuation);
2650             
2651             m_out.appendTo(continuation, lastNext);
2652             setJSValue(m_out.phi(m_out.int64, namedResult, overflowResult));
2653             return;
2654         }
2655             
2656         case Array::Generic: {
2657             setJSValue(vmCall(
2658                 m_out.int64, m_out.operation(operationGetByVal), m_callFrame,
2659                 lowJSValue(m_node->child1()), lowJSValue(m_node->child2())));
2660             return;
2661         }
2662             
2663         case Array::String: {
2664             compileStringCharAt();
2665             return;
2666         }
2667             
2668         default: {
2669             LValue index = lowInt32(m_node->child2());
2670             LValue storage = lowStorage(m_node->child3());
2671             
2672             TypedArrayType type = m_node->arrayMode().typedArrayType();
2673             
2674             if (isTypedView(type)) {
2675                 TypedPointer pointer = TypedPointer(
2676                     m_heaps.typedArrayProperties,
2677                     m_out.add(
2678                         storage,
2679                         m_out.shl(
2680                             m_out.zeroExtPtr(index),
2681                             m_out.constIntPtr(logElementSize(type)))));
2682                 
2683                 if (isInt(type)) {
2684                     LValue result;
2685                     switch (elementSize(type)) {
2686                     case 1:
2687                         result = isSigned(type) ? m_out.load8SignExt32(pointer) :  m_out.load8ZeroExt32(pointer);
2688                         break;
2689                     case 2:
2690                         result = isSigned(type) ? m_out.load16SignExt32(pointer) :  m_out.load16ZeroExt32(pointer);
2691                         break;
2692                     case 4:
2693                         result = m_out.load32(pointer);
2694                         break;
2695                     default:
2696                         DFG_CRASH(m_graph, m_node, "Bad element size");
2697                     }
2698                     
2699                     if (elementSize(type) < 4 || isSigned(type)) {
2700                         setInt32(result);
2701                         return;
2702                     }
2703
2704                     if (m_node->shouldSpeculateInt32()) {
2705                         speculate(
2706                             Overflow, noValue(), 0, m_out.lessThan(result, m_out.int32Zero));
2707                         setInt32(result);
2708                         return;
2709                     }
2710                     
2711                     if (m_node->shouldSpeculateMachineInt()) {
2712                         setStrictInt52(m_out.zeroExt(result, m_out.int64));
2713                         return;
2714                     }
2715                     
2716                     setDouble(m_out.unsignedToDouble(result));
2717                     return;
2718                 }
2719             
2720                 ASSERT(isFloat(type));
2721                 
2722                 LValue result;
2723                 switch (type) {
2724                 case TypeFloat32:
2725                     result = m_out.floatToDouble(m_out.loadFloat(pointer));
2726                     break;
2727                 case TypeFloat64:
2728                     result = m_out.loadDouble(pointer);
2729                     break;
2730                 default:
2731                     DFG_CRASH(m_graph, m_node, "Bad typed array type");
2732                 }
2733                 
2734                 setDouble(result);
2735                 return;
2736             }
2737             
2738             DFG_CRASH(m_graph, m_node, "Bad array type");
2739             return;
2740         } }
2741     }
2742     
2743     void compileGetMyArgumentByVal()
2744     {
2745         InlineCallFrame* inlineCallFrame = m_node->child1()->origin.semantic.inlineCallFrame;
2746         
2747         LValue index = lowInt32(m_node->child2());
2748         
2749         LValue limit;
2750         if (inlineCallFrame && !inlineCallFrame->isVarargs())
2751             limit = m_out.constInt32(inlineCallFrame->arguments.size() - 1);
2752         else {
2753             VirtualRegister argumentCountRegister;
2754             if (!inlineCallFrame)
2755                 argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
2756             else
2757                 argumentCountRegister = inlineCallFrame->argumentCountRegister;
2758             limit = m_out.sub(m_out.load32(payloadFor(argumentCountRegister)), m_out.int32One);
2759         }
2760         
2761         speculate(ExoticObjectMode, noValue(), 0, m_out.aboveOrEqual(index, limit));
2762         
2763         TypedPointer base;
2764         if (inlineCallFrame) {
2765             if (inlineCallFrame->arguments.size() <= 1) {
2766                 // We should have already exited due to the bounds check, above. Just tell the
2767                 // compiler that anything dominated by this instruction is not reachable, so
2768                 // that we don't waste time generating such code. This will also plant some
2769                 // kind of crashing instruction so that if by some fluke the bounds check didn't
2770                 // work, we'll crash in an easy-to-see way.
2771                 didAlreadyTerminate();
2772                 return;
2773             }
2774             base = addressFor(inlineCallFrame->arguments[1].virtualRegister());
2775         } else
2776             base = addressFor(virtualRegisterForArgument(1));
2777         
2778         LValue pointer = m_out.baseIndex(
2779             base.value(), m_out.zeroExt(index, m_out.intPtr), ScaleEight);
2780         setJSValue(m_out.load64(TypedPointer(m_heaps.variables.atAnyIndex(), pointer)));
2781     }
2782     
2783     void compilePutByVal()
2784     {
2785         Edge child1 = m_graph.varArgChild(m_node, 0);
2786         Edge child2 = m_graph.varArgChild(m_node, 1);
2787         Edge child3 = m_graph.varArgChild(m_node, 2);
2788         Edge child4 = m_graph.varArgChild(m_node, 3);
2789         Edge child5 = m_graph.varArgChild(m_node, 4);
2790         
2791         switch (m_node->arrayMode().type()) {
2792         case Array::Generic: {
2793             V_JITOperation_EJJJ operation;
2794             if (m_node->op() == PutByValDirect) {
2795                 if (m_graph.isStrictModeFor(m_node->origin.semantic))
2796                     operation = operationPutByValDirectStrict;
2797                 else
2798                     operation = operationPutByValDirectNonStrict;
2799             } else {
2800                 if (m_graph.isStrictModeFor(m_node->origin.semantic))
2801                     operation = operationPutByValStrict;
2802                 else
2803                     operation = operationPutByValNonStrict;
2804             }
2805                 
2806             vmCall(
2807                 m_out.voidType, m_out.operation(operation), m_callFrame,
2808                 lowJSValue(child1), lowJSValue(child2), lowJSValue(child3));
2809             return;
2810         }
2811             
2812         default:
2813             break;
2814         }
2815
2816         LValue base = lowCell(child1);
2817         LValue index = lowInt32(child2);
2818         LValue storage = lowStorage(child4);
2819         
2820         switch (m_node->arrayMode().type()) {
2821         case Array::Int32:
2822         case Array::Double:
2823         case Array::Contiguous: {
2824             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("PutByVal continuation"));
2825             LBasicBlock outerLastNext = m_out.appendTo(m_out.m_block, continuation);
2826             
2827             switch (m_node->arrayMode().type()) {
2828             case Array::Int32:
2829             case Array::Contiguous: {
2830                 LValue value = lowJSValue(child3, ManualOperandSpeculation);
2831                 
2832                 if (m_node->arrayMode().type() == Array::Int32)
2833                     FTL_TYPE_CHECK(jsValueValue(value), child3, SpecInt32, isNotInt32(value));
2834                 
2835                 TypedPointer elementPointer = m_out.baseIndex(
2836                     m_node->arrayMode().type() == Array::Int32 ?
2837                     m_heaps.indexedInt32Properties : m_heaps.indexedContiguousProperties,
2838                     storage, m_out.zeroExtPtr(index), provenValue(child2));
2839                 
2840                 if (m_node->op() == PutByValAlias) {
2841                     m_out.store64(value, elementPointer);
2842                     break;
2843                 }
2844                 
2845                 contiguousPutByValOutOfBounds(
2846                     codeBlock()->isStrictMode()
2847                     ? operationPutByValBeyondArrayBoundsStrict
2848                     : operationPutByValBeyondArrayBoundsNonStrict,
2849                     base, storage, index, value, continuation);
2850                 
2851                 m_out.store64(value, elementPointer);
2852                 break;
2853             }
2854                 
2855             case Array::Double: {
2856                 LValue value = lowDouble(child3);
2857                 
2858                 FTL_TYPE_CHECK(
2859                     doubleValue(value), child3, SpecDoubleReal,
2860                     m_out.doubleNotEqualOrUnordered(value, value));
2861                 
2862                 TypedPointer elementPointer = m_out.baseIndex(
2863                     m_heaps.indexedDoubleProperties, storage, m_out.zeroExtPtr(index),
2864                     provenValue(child2));
2865                 
2866                 if (m_node->op() == PutByValAlias) {
2867                     m_out.storeDouble(value, elementPointer);
2868                     break;
2869                 }
2870                 
2871                 contiguousPutByValOutOfBounds(
2872                     codeBlock()->isStrictMode()
2873                     ? operationPutDoubleByValBeyondArrayBoundsStrict
2874                     : operationPutDoubleByValBeyondArrayBoundsNonStrict,
2875                     base, storage, index, value, continuation);
2876                 
2877                 m_out.storeDouble(value, elementPointer);
2878                 break;
2879             }
2880                 
2881             default:
2882                 DFG_CRASH(m_graph, m_node, "Bad array type");
2883             }
2884
2885             m_out.jump(continuation);
2886             m_out.appendTo(continuation, outerLastNext);
2887             return;
2888         }
2889             
2890         default:
2891             TypedArrayType type = m_node->arrayMode().typedArrayType();
2892             
2893             if (isTypedView(type)) {
2894                 TypedPointer pointer = TypedPointer(
2895                     m_heaps.typedArrayProperties,
2896                     m_out.add(
2897                         storage,
2898                         m_out.shl(
2899                             m_out.zeroExt(index, m_out.intPtr),
2900                             m_out.constIntPtr(logElementSize(type)))));
2901                 
2902                 Output::StoreType storeType;
2903                 LValue valueToStore;
2904                 
2905                 if (isInt(type)) {
2906                     LValue intValue;
2907                     switch (child3.useKind()) {
2908                     case Int52RepUse:
2909                     case Int32Use: {
2910                         if (child3.useKind() == Int32Use)
2911                             intValue = lowInt32(child3);
2912                         else
2913                             intValue = m_out.castToInt32(lowStrictInt52(child3));
2914
2915                         if (isClamped(type)) {
2916                             ASSERT(elementSize(type) == 1);
2917                             
2918                             LBasicBlock atLeastZero = FTL_NEW_BLOCK(m_out, ("PutByVal int clamp atLeastZero"));
2919                             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("PutByVal int clamp continuation"));
2920                             
2921                             Vector<ValueFromBlock, 2> intValues;
2922                             intValues.append(m_out.anchor(m_out.int32Zero));
2923                             m_out.branch(
2924                                 m_out.lessThan(intValue, m_out.int32Zero),
2925                                 unsure(continuation), unsure(atLeastZero));
2926                             
2927                             LBasicBlock lastNext = m_out.appendTo(atLeastZero, continuation);
2928                             
2929                             intValues.append(m_out.anchor(m_out.select(
2930                                 m_out.greaterThan(intValue, m_out.constInt32(255)),
2931                                 m_out.constInt32(255),
2932                                 intValue)));
2933                             m_out.jump(continuation);
2934                             
2935                             m_out.appendTo(continuation, lastNext);
2936                             intValue = m_out.phi(m_out.int32, intValues);
2937                         }
2938                         break;
2939                     }
2940                         
2941                     case DoubleRepUse: {
2942                         LValue doubleValue = lowDouble(child3);
2943                         
2944                         if (isClamped(type)) {
2945                             ASSERT(elementSize(type) == 1);
2946                             
2947                             LBasicBlock atLeastZero = FTL_NEW_BLOCK(m_out, ("PutByVal double clamp atLeastZero"));
2948                             LBasicBlock withinRange = FTL_NEW_BLOCK(m_out, ("PutByVal double clamp withinRange"));
2949                             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("PutByVal double clamp continuation"));
2950                             
2951                             Vector<ValueFromBlock, 3> intValues;
2952                             intValues.append(m_out.anchor(m_out.int32Zero));
2953                             m_out.branch(
2954                                 m_out.doubleLessThanOrUnordered(doubleValue, m_out.doubleZero),
2955                                 unsure(continuation), unsure(atLeastZero));
2956                             
2957                             LBasicBlock lastNext = m_out.appendTo(atLeastZero, withinRange);
2958                             intValues.append(m_out.anchor(m_out.constInt32(255)));
2959                             m_out.branch(
2960                                 m_out.doubleGreaterThan(doubleValue, m_out.constDouble(255)),
2961                                 unsure(continuation), unsure(withinRange));
2962                             
2963                             m_out.appendTo(withinRange, continuation);
2964                             intValues.append(m_out.anchor(m_out.doubleToInt(doubleValue)));
2965                             m_out.jump(continuation);
2966                             
2967                             m_out.appendTo(continuation, lastNext);
2968                             intValue = m_out.phi(m_out.int32, intValues);
2969                         } else
2970                             intValue = doubleToInt32(doubleValue);
2971                         break;
2972                     }
2973                         
2974                     default:
2975                         DFG_CRASH(m_graph, m_node, "Bad use kind");
2976                     }
2977
2978                     valueToStore = intValue;
2979                     switch (elementSize(type)) {
2980                     case 1:
2981                         storeType = Output::Store32As8;
2982                         break;
2983                     case 2:
2984                         storeType = Output::Store32As16;
2985                         break;
2986                     case 4:
2987                         storeType = Output::Store32;
2988                         break;
2989                     default:
2990                         DFG_CRASH(m_graph, m_node, "Bad element size");
2991                     }
2992                 } else /* !isInt(type) */ {
2993                     LValue value = lowDouble(child3);
2994                     switch (type) {
2995                     case TypeFloat32:
2996                         valueToStore = m_out.doubleToFloat(value);
2997                         storeType = Output::StoreFloat;
2998                         break;
2999                     case TypeFloat64:
3000                         valueToStore = value;
3001                         storeType = Output::StoreDouble;
3002                         break;
3003                     default:
3004                         DFG_CRASH(m_graph, m_node, "Bad typed array type");
3005                     }
3006                 }
3007                 
3008                 if (m_node->arrayMode().isInBounds() || m_node->op() == PutByValAlias)
3009                     m_out.store(valueToStore, pointer, storeType);
3010                 else {
3011                     LBasicBlock isInBounds = FTL_NEW_BLOCK(m_out, ("PutByVal typed array in bounds case"));
3012                     LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("PutByVal typed array continuation"));
3013                     
3014                     m_out.branch(
3015                         m_out.aboveOrEqual(index, lowInt32(child5)),
3016                         unsure(continuation), unsure(isInBounds));
3017                     
3018                     LBasicBlock lastNext = m_out.appendTo(isInBounds, continuation);
3019                     m_out.store(valueToStore, pointer, storeType);
3020                     m_out.jump(continuation);
3021                     
3022                     m_out.appendTo(continuation, lastNext);
3023                 }
3024                 
3025                 return;
3026             }
3027             
3028             DFG_CRASH(m_graph, m_node, "Bad array type");
3029             break;
3030         }
3031     }
3032
3033     void compilePutAccessorById()
3034     {
3035         LValue base = lowCell(m_node->child1());
3036         LValue accessor = lowCell(m_node->child2());
3037         auto uid = m_graph.identifiers()[m_node->identifierNumber()];
3038         vmCall(
3039             m_out.voidType,
3040             m_out.operation(m_node->op() == PutGetterById ? operationPutGetterById : operationPutSetterById),
3041             m_callFrame, base, m_out.constIntPtr(uid), m_out.constInt32(m_node->accessorAttributes()), accessor);
3042     }
3043
3044     void compilePutGetterSetterById()
3045     {
3046         LValue base = lowCell(m_node->child1());
3047         LValue getter = lowJSValue(m_node->child2());
3048         LValue setter = lowJSValue(m_node->child3());
3049         auto uid = m_graph.identifiers()[m_node->identifierNumber()];
3050         vmCall(
3051             m_out.voidType, m_out.operation(operationPutGetterSetter),
3052             m_callFrame, base, m_out.constIntPtr(uid), m_out.constInt32(m_node->accessorAttributes()), getter, setter);
3053
3054     }
3055
3056     void compilePutAccessorByVal()
3057     {
3058         LValue base = lowCell(m_node->child1());
3059         LValue subscript = lowJSValue(m_node->child2());
3060         LValue accessor = lowCell(m_node->child3());
3061         vmCall(
3062             m_out.voidType,
3063             m_out.operation(m_node->op() == PutGetterByVal ? operationPutGetterByVal : operationPutSetterByVal),
3064             m_callFrame, base, subscript, m_out.constInt32(m_node->accessorAttributes()), accessor);
3065     }
3066     
3067     void compileArrayPush()
3068     {
3069         LValue base = lowCell(m_node->child1());
3070         LValue storage = lowStorage(m_node->child3());
3071         
3072         switch (m_node->arrayMode().type()) {
3073         case Array::Int32:
3074         case Array::Contiguous:
3075         case Array::Double: {
3076             LValue value;
3077             Output::StoreType storeType;
3078             
3079             if (m_node->arrayMode().type() != Array::Double) {
3080                 value = lowJSValue(m_node->child2(), ManualOperandSpeculation);
3081                 if (m_node->arrayMode().type() == Array::Int32) {
3082                     FTL_TYPE_CHECK(
3083                         jsValueValue(value), m_node->child2(), SpecInt32, isNotInt32(value));
3084                 }
3085                 storeType = Output::Store64;
3086             } else {
3087                 value = lowDouble(m_node->child2());
3088                 FTL_TYPE_CHECK(
3089                     doubleValue(value), m_node->child2(), SpecDoubleReal,
3090                     m_out.doubleNotEqualOrUnordered(value, value));
3091                 storeType = Output::StoreDouble;
3092             }
3093             
3094             IndexedAbstractHeap& heap = m_heaps.forArrayType(m_node->arrayMode().type());
3095
3096             LValue prevLength = m_out.load32(storage, m_heaps.Butterfly_publicLength);
3097             
3098             LBasicBlock fastPath = FTL_NEW_BLOCK(m_out, ("ArrayPush fast path"));
3099             LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("ArrayPush slow path"));
3100             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArrayPush continuation"));
3101             
3102             m_out.branch(
3103                 m_out.aboveOrEqual(
3104                     prevLength, m_out.load32(storage, m_heaps.Butterfly_vectorLength)),
3105                 unsure(slowPath), unsure(fastPath));
3106             
3107             LBasicBlock lastNext = m_out.appendTo(fastPath, slowPath);
3108             m_out.store(
3109                 value, m_out.baseIndex(heap, storage, m_out.zeroExtPtr(prevLength)), storeType);
3110             LValue newLength = m_out.add(prevLength, m_out.int32One);
3111             m_out.store32(newLength, storage, m_heaps.Butterfly_publicLength);
3112             
3113             ValueFromBlock fastResult = m_out.anchor(boxInt32(newLength));
3114             m_out.jump(continuation);
3115             
3116             m_out.appendTo(slowPath, continuation);
3117             LValue operation;
3118             if (m_node->arrayMode().type() != Array::Double)
3119                 operation = m_out.operation(operationArrayPush);
3120             else
3121                 operation = m_out.operation(operationArrayPushDouble);
3122             ValueFromBlock slowResult = m_out.anchor(
3123                 vmCall(m_out.int64, operation, m_callFrame, value, base));
3124             m_out.jump(continuation);
3125             
3126             m_out.appendTo(continuation, lastNext);
3127             setJSValue(m_out.phi(m_out.int64, fastResult, slowResult));
3128             return;
3129         }
3130             
3131         default:
3132             DFG_CRASH(m_graph, m_node, "Bad array type");
3133             return;
3134         }
3135     }
3136     
3137     void compileArrayPop()
3138     {
3139         LValue base = lowCell(m_node->child1());
3140         LValue storage = lowStorage(m_node->child2());
3141         
3142         switch (m_node->arrayMode().type()) {
3143         case Array::Int32:
3144         case Array::Double:
3145         case Array::Contiguous: {
3146             IndexedAbstractHeap& heap = m_heaps.forArrayType(m_node->arrayMode().type());
3147             
3148             LBasicBlock fastCase = FTL_NEW_BLOCK(m_out, ("ArrayPop fast case"));
3149             LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("ArrayPop slow case"));
3150             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArrayPop continuation"));
3151             
3152             LValue prevLength = m_out.load32(storage, m_heaps.Butterfly_publicLength);
3153             
3154             Vector<ValueFromBlock, 3> results;
3155             results.append(m_out.anchor(m_out.constInt64(JSValue::encode(jsUndefined()))));
3156             m_out.branch(
3157                 m_out.isZero32(prevLength), rarely(continuation), usually(fastCase));
3158             
3159             LBasicBlock lastNext = m_out.appendTo(fastCase, slowCase);
3160             LValue newLength = m_out.sub(prevLength, m_out.int32One);
3161             m_out.store32(newLength, storage, m_heaps.Butterfly_publicLength);
3162             TypedPointer pointer = m_out.baseIndex(heap, storage, m_out.zeroExtPtr(newLength));
3163             if (m_node->arrayMode().type() != Array::Double) {
3164                 LValue result = m_out.load64(pointer);
3165                 m_out.store64(m_out.int64Zero, pointer);
3166                 results.append(m_out.anchor(result));
3167                 m_out.branch(
3168                     m_out.notZero64(result), usually(continuation), rarely(slowCase));
3169             } else {
3170                 LValue result = m_out.loadDouble(pointer);
3171                 m_out.store64(m_out.constInt64(bitwise_cast<int64_t>(PNaN)), pointer);
3172                 results.append(m_out.anchor(boxDouble(result)));
3173                 m_out.branch(
3174                     m_out.doubleEqual(result, result),
3175                     usually(continuation), rarely(slowCase));
3176             }
3177             
3178             m_out.appendTo(slowCase, continuation);
3179             results.append(m_out.anchor(vmCall(
3180                 m_out.int64, m_out.operation(operationArrayPopAndRecoverLength), m_callFrame, base)));
3181             m_out.jump(continuation);
3182             
3183             m_out.appendTo(continuation, lastNext);
3184             setJSValue(m_out.phi(m_out.int64, results));
3185             return;
3186         }
3187
3188         default:
3189             DFG_CRASH(m_graph, m_node, "Bad array type");
3190             return;
3191         }
3192     }
3193     
3194     void compileCreateActivation()
3195     {
3196         LValue scope = lowCell(m_node->child1());
3197         SymbolTable* table = m_node->castOperand<SymbolTable*>();
3198         Structure* structure = m_graph.globalObjectFor(m_node->origin.semantic)->activationStructure();
3199         JSValue initializationValue = m_node->initializationValueForActivation();
3200         ASSERT(initializationValue.isUndefined() || initializationValue == jsTDZValue());
3201         if (table->singletonScope()->isStillValid()) {
3202             LValue callResult = vmCall(
3203                 m_out.int64,
3204                 m_out.operation(operationCreateActivationDirect), m_callFrame, weakPointer(structure),
3205                 scope, weakPointer(table), m_out.constInt64(JSValue::encode(initializationValue)));
3206             setJSValue(callResult);
3207             return;
3208         }
3209         
3210         LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("CreateActivation slow path"));
3211         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("CreateActivation continuation"));
3212         
3213         LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath);
3214         
3215         LValue fastObject = allocateObject<JSLexicalEnvironment>(
3216             JSLexicalEnvironment::allocationSize(table), structure, m_out.intPtrZero, slowPath);
3217         
3218         // We don't need memory barriers since we just fast-created the activation, so the
3219         // activation must be young.
3220         m_out.storePtr(scope, fastObject, m_heaps.JSScope_next);
3221         m_out.storePtr(weakPointer(table), fastObject, m_heaps.JSSymbolTableObject_symbolTable);
3222         
3223         for (unsigned i = 0; i < table->scopeSize(); ++i) {
3224             m_out.store64(
3225                 m_out.constInt64(JSValue::encode(initializationValue)),
3226                 fastObject, m_heaps.JSEnvironmentRecord_variables[i]);
3227         }
3228         
3229         ValueFromBlock fastResult = m_out.anchor(fastObject);
3230         m_out.jump(continuation);
3231         
3232         m_out.appendTo(slowPath, continuation);
3233         LValue callResult = lazySlowPath(
3234             [=] (const Vector<Location>& locations) -> RefPtr<LazySlowPath::Generator> {
3235                 return createLazyCallGenerator(
3236                     operationCreateActivationDirect, locations[0].directGPR(),
3237                     CCallHelpers::TrustedImmPtr(structure), locations[1].directGPR(),
3238                     CCallHelpers::TrustedImmPtr(table),
3239                     CCallHelpers::TrustedImm64(JSValue::encode(initializationValue)));
3240             },
3241             scope);
3242         ValueFromBlock slowResult = m_out.anchor(callResult);
3243         m_out.jump(continuation);
3244         
3245         m_out.appendTo(continuation, lastNext);
3246         setJSValue(m_out.phi(m_out.intPtr, fastResult, slowResult));
3247     }
3248     
3249     void compileNewFunction()
3250     {
3251         ASSERT(m_node->op() == NewFunction || m_node->op() == NewArrowFunction || m_node->op() == NewGeneratorFunction);
3252         bool isGeneratorFunction = m_node->op() == NewGeneratorFunction;
3253         
3254         LValue scope = lowCell(m_node->child1());
3255         
3256         FunctionExecutable* executable = m_node->castOperand<FunctionExecutable*>();
3257         if (executable->singletonFunction()->isStillValid()) {
3258             LValue callResult =
3259                 isGeneratorFunction ? vmCall(m_out.int64, m_out.operation(operationNewGeneratorFunction), m_callFrame, scope, weakPointer(executable)) :
3260                 vmCall(m_out.int64, m_out.operation(operationNewFunction), m_callFrame, scope, weakPointer(executable));
3261             setJSValue(callResult);
3262             return;
3263         }
3264         
3265         Structure* structure =
3266             isGeneratorFunction ? m_graph.globalObjectFor(m_node->origin.semantic)->generatorFunctionStructure() :
3267             m_graph.globalObjectFor(m_node->origin.semantic)->functionStructure();
3268         
3269         LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("NewFunction slow path"));
3270         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("NewFunction continuation"));
3271         
3272         LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath);
3273         
3274         LValue fastObject =
3275             isGeneratorFunction ? allocateObject<JSGeneratorFunction>(structure, m_out.intPtrZero, slowPath) :
3276             allocateObject<JSFunction>(structure, m_out.intPtrZero, slowPath);
3277         
3278         
3279         // We don't need memory barriers since we just fast-created the function, so it
3280         // must be young.
3281         m_out.storePtr(scope, fastObject, m_heaps.JSFunction_scope);
3282         m_out.storePtr(weakPointer(executable), fastObject, m_heaps.JSFunction_executable);
3283         m_out.storePtr(m_out.intPtrZero, fastObject, m_heaps.JSFunction_rareData);
3284         
3285         ValueFromBlock fastResult = m_out.anchor(fastObject);
3286         m_out.jump(continuation);
3287         
3288         m_out.appendTo(slowPath, continuation);
3289
3290         Vector<LValue> slowPathArguments;
3291         slowPathArguments.append(scope);
3292         LValue callResult = lazySlowPath(
3293             [=] (const Vector<Location>& locations) -> RefPtr<LazySlowPath::Generator> {
3294                 if (isGeneratorFunction) {
3295                     return createLazyCallGenerator(
3296                         operationNewGeneratorFunctionWithInvalidatedReallocationWatchpoint,
3297                         locations[0].directGPR(), locations[1].directGPR(),
3298                         CCallHelpers::TrustedImmPtr(executable));
3299                 }
3300                 return createLazyCallGenerator(
3301                     operationNewFunctionWithInvalidatedReallocationWatchpoint,
3302                     locations[0].directGPR(), locations[1].directGPR(),
3303                     CCallHelpers::TrustedImmPtr(executable));
3304             },
3305             slowPathArguments);
3306         ValueFromBlock slowResult = m_out.anchor(callResult);
3307         m_out.jump(continuation);
3308         
3309         m_out.appendTo(continuation, lastNext);
3310         setJSValue(m_out.phi(m_out.intPtr, fastResult, slowResult));
3311     }
3312     
3313     void compileCreateDirectArguments()
3314     {
3315         // FIXME: A more effective way of dealing with the argument count and callee is to have
3316         // them be explicit arguments to this node.
3317         // https://bugs.webkit.org/show_bug.cgi?id=142207
3318         
3319         Structure* structure =
3320             m_graph.globalObjectFor(m_node->origin.semantic)->directArgumentsStructure();
3321         
3322         unsigned minCapacity = m_graph.baselineCodeBlockFor(m_node->origin.semantic)->numParameters() - 1;
3323         
3324         LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("CreateDirectArguments slow path"));
3325         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("CreateDirectArguments continuation"));
3326         
3327         LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath);
3328         
3329         ArgumentsLength length = getArgumentsLength();
3330         
3331         LValue fastObject;
3332         if (length.isKnown) {
3333             fastObject = allocateObject<DirectArguments>(
3334                 DirectArguments::allocationSize(std::max(length.known, minCapacity)), structure,
3335                 m_out.intPtrZero, slowPath);
3336         } else {
3337             LValue size = m_out.add(
3338                 m_out.shl(length.value, m_out.constInt32(3)),
3339                 m_out.constInt32(DirectArguments::storageOffset()));
3340             
3341             size = m_out.select(
3342                 m_out.aboveOrEqual(length.value, m_out.constInt32(minCapacity)),
3343                 size, m_out.constInt32(DirectArguments::allocationSize(minCapacity)));
3344             
3345             fastObject = allocateVariableSizedObject<DirectArguments>(
3346                 size, structure, m_out.intPtrZero, slowPath);
3347         }
3348         
3349         m_out.store32(length.value, fastObject, m_heaps.DirectArguments_length);
3350         m_out.store32(m_out.constInt32(minCapacity), fastObject, m_heaps.DirectArguments_minCapacity);
3351         m_out.storePtr(m_out.intPtrZero, fastObject, m_heaps.DirectArguments_overrides);
3352         
3353         ValueFromBlock fastResult = m_out.anchor(fastObject);
3354         m_out.jump(continuation);
3355         
3356         m_out.appendTo(slowPath, continuation);
3357         LValue callResult = lazySlowPath(
3358             [=] (const Vector<Location>& locations) -> RefPtr<LazySlowPath::Generator> {
3359                 return createLazyCallGenerator(
3360                     operationCreateDirectArguments, locations[0].directGPR(),
3361                     CCallHelpers::TrustedImmPtr(structure), locations[1].directGPR(),
3362                     CCallHelpers::TrustedImm32(minCapacity));
3363             }, length.value);
3364         ValueFromBlock slowResult = m_out.anchor(callResult);
3365         m_out.jump(continuation);
3366         
3367         m_out.appendTo(continuation, lastNext);
3368         LValue result = m_out.phi(m_out.intPtr, fastResult, slowResult);
3369
3370         m_out.storePtr(getCurrentCallee(), result, m_heaps.DirectArguments_callee);
3371         
3372         if (length.isKnown) {
3373             VirtualRegister start = AssemblyHelpers::argumentsStart(m_node->origin.semantic);
3374             for (unsigned i = 0; i < std::max(length.known, minCapacity); ++i) {
3375                 m_out.store64(
3376                     m_out.load64(addressFor(start + i)),
3377                     result, m_heaps.DirectArguments_storage[i]);
3378             }
3379         } else {
3380             LValue stackBase = getArgumentsStart();
3381             
3382             LBasicBlock loop = FTL_NEW_BLOCK(m_out, ("CreateDirectArguments loop body"));
3383             LBasicBlock end = FTL_NEW_BLOCK(m_out, ("CreateDirectArguments loop end"));
3384
3385             ValueFromBlock originalLength;
3386             if (minCapacity) {
3387                 LValue capacity = m_out.select(
3388                     m_out.aboveOrEqual(length.value, m_out.constInt32(minCapacity)),
3389                     length.value,
3390                     m_out.constInt32(minCapacity));
3391                 LValue originalLengthValue = m_out.zeroExtPtr(capacity);
3392                 originalLength = m_out.anchor(originalLengthValue);
3393                 m_out.jump(loop);
3394             } else {
3395                 LValue originalLengthValue = m_out.zeroExtPtr(length.value);
3396                 originalLength = m_out.anchor(originalLengthValue);
3397                 m_out.branch(m_out.isNull(originalLengthValue), unsure(end), unsure(loop));
3398             }
3399             
3400             lastNext = m_out.appendTo(loop, end);
3401             LValue previousIndex = m_out.phi(m_out.intPtr, originalLength);
3402             LValue index = m_out.sub(previousIndex, m_out.intPtrOne);
3403             m_out.store64(
3404                 m_out.load64(m_out.baseIndex(m_heaps.variables, stackBase, index)),
3405                 m_out.baseIndex(m_heaps.DirectArguments_storage, result, index));
3406             ValueFromBlock nextIndex = m_out.anchor(index);
3407             m_out.addIncomingToPhi(previousIndex, nextIndex);
3408             m_out.branch(m_out.isNull(index), unsure(end), unsure(loop));
3409             
3410             m_out.appendTo(end, lastNext);
3411         }
3412         
3413         setJSValue(result);
3414     }
3415     
3416     void compileCreateScopedArguments()
3417     {
3418         LValue scope = lowCell(m_node->child1());
3419         
3420         LValue result = vmCall(
3421             m_out.int64, m_out.operation(operationCreateScopedArguments), m_callFrame,
3422             weakPointer(
3423                 m_graph.globalObjectFor(m_node->origin.semantic)->scopedArgumentsStructure()),
3424             getArgumentsStart(), getArgumentsLength().value, getCurrentCallee(), scope);
3425         
3426         setJSValue(result);
3427     }
3428     
3429     void compileCreateClonedArguments()
3430     {
3431         LValue result = vmCall(
3432             m_out.int64, m_out.operation(operationCreateClonedArguments), m_callFrame,
3433             weakPointer(
3434                 m_graph.globalObjectFor(m_node->origin.semantic)->outOfBandArgumentsStructure()),
3435             getArgumentsStart(), getArgumentsLength().value, getCurrentCallee());
3436         
3437         setJSValue(result);
3438     }
3439
3440     void compileCopyRest()
3441     {            
3442         LBasicBlock doCopyRest = FTL_NEW_BLOCK(m_out, ("CopyRest C call"));
3443         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("FillRestParameter continuation"));
3444
3445         LValue arrayLength = lowInt32(m_node->child2());
3446
3447         m_out.branch(
3448             m_out.equal(arrayLength, m_out.constInt32(0)),
3449             unsure(continuation), unsure(doCopyRest));
3450             
3451         LBasicBlock lastNext = m_out.appendTo(doCopyRest, continuation);
3452         // Arguments: 0:exec, 1:JSCell* array, 2:arguments start, 3:number of arguments to skip, 4:array length
3453         LValue numberOfArgumentsToSkip = m_out.constInt32(m_node->numberOfArgumentsToSkip());
3454         vmCall(
3455             m_out.voidType,m_out.operation(operationCopyRest), m_callFrame, lowCell(m_node->child1()),
3456             getArgumentsStart(), numberOfArgumentsToSkip, arrayLength);
3457         m_out.jump(continuation);
3458
3459         m_out.appendTo(continuation, lastNext);
3460     }
3461
3462     void compileGetRestLength()
3463     {
3464         LBasicBlock nonZeroLength = FTL_NEW_BLOCK(m_out, ("GetRestLength non zero"));
3465         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetRestLength continuation"));
3466         
3467         ValueFromBlock zeroLengthResult = m_out.anchor(m_out.constInt32(0));
3468
3469         LValue numberOfArgumentsToSkip = m_out.constInt32(m_node->numberOfArgumentsToSkip());
3470         LValue argumentsLength = getArgumentsLength().value;
3471         m_out.branch(m_out.above(argumentsLength, numberOfArgumentsToSkip),
3472             unsure(nonZeroLength), unsure(continuation));
3473         
3474         LBasicBlock lastNext = m_out.appendTo(nonZeroLength, continuation);
3475         ValueFromBlock nonZeroLengthResult = m_out.anchor(m_out.sub(argumentsLength, numberOfArgumentsToSkip));
3476         m_out.jump(continuation);
3477         
3478         m_out.appendTo(continuation, lastNext);
3479         setInt32(m_out.phi(m_out.int32, zeroLengthResult, nonZeroLengthResult));
3480     }
3481     
3482     void compileNewObject()
3483     {
3484         setJSValue(allocateObject(m_node->structure()));
3485     }
3486     
3487     void compileNewArray()
3488     {
3489         // First speculate appropriately on all of the children. Do this unconditionally up here
3490         // because some of the slow paths may otherwise forget to do it. It's sort of arguable
3491         // that doing the speculations up here might be unprofitable for RA - so we can consider
3492         // sinking this to below the allocation fast path if we find that this has a lot of
3493         // register pressure.
3494         for (unsigned operandIndex = 0; operandIndex < m_node->numChildren(); ++operandIndex)
3495             speculate(m_graph.varArgChild(m_node, operandIndex));
3496         
3497         JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
3498         Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(
3499             m_node->indexingType());
3500
3501         if (!globalObject->isHavingABadTime() && !hasAnyArrayStorage(m_node->indexingType())) {
3502             unsigned numElements = m_node->numChildren();
3503             
3504             ArrayValues arrayValues = allocateJSArray(structure, numElements);
3505             
3506             for (unsigned operandIndex = 0; operandIndex < m_node->numChildren(); ++operandIndex) {
3507                 Edge edge = m_graph.varArgChild(m_node, operandIndex);
3508                 
3509                 switch (m_node->indexingType()) {
3510                 case ALL_BLANK_INDEXING_TYPES:
3511                 case ALL_UNDECIDED_INDEXING_TYPES:
3512                     DFG_CRASH(m_graph, m_node, "Bad indexing type");
3513                     break;
3514                     
3515                 case ALL_DOUBLE_INDEXING_TYPES:
3516                     m_out.storeDouble(
3517                         lowDouble(edge),
3518                         arrayValues.butterfly, m_heaps.indexedDoubleProperties[operandIndex]);
3519                     break;
3520                     
3521                 case ALL_INT32_INDEXING_TYPES:
3522                 case ALL_CONTIGUOUS_INDEXING_TYPES:
3523                     m_out.store64(
3524                         lowJSValue(edge, ManualOperandSpeculation),
3525                         arrayValues.butterfly,
3526                         m_heaps.forIndexingType(m_node->indexingType())->at(operandIndex));
3527                     break;
3528                     
3529                 default:
3530                     DFG_CRASH(m_graph, m_node, "Corrupt indexing type");
3531                     break;
3532                 }
3533             }
3534             
3535             setJSValue(arrayValues.array);
3536             return;
3537         }
3538         
3539         if (!m_node->numChildren()) {
3540             setJSValue(vmCall(
3541                 m_out.int64, m_out.operation(operationNewEmptyArray), m_callFrame,
3542                 m_out.constIntPtr(structure)));
3543             return;
3544         }
3545         
3546         size_t scratchSize = sizeof(EncodedJSValue) * m_node->numChildren();
3547         ASSERT(scratchSize);
3548         ScratchBuffer* scratchBuffer = vm().scratchBufferForSize(scratchSize);
3549         EncodedJSValue* buffer = static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer());
3550         
3551         for (unsigned operandIndex = 0; operandIndex < m_node->numChildren(); ++operandIndex) {
3552             Edge edge = m_graph.varArgChild(m_node, operandIndex);
3553             m_out.store64(
3554                 lowJSValue(edge, ManualOperandSpeculation),
3555                 m_out.absolute(buffer + operandIndex));
3556         }
3557         
3558         m_out.storePtr(