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