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