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