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