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