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