[JSC] Make the rounding-related nodes support any type
[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 IsJSArray:
903             compileIsJSArray();
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 IsRegExpObject:
927             compileIsRegExpObject();
928             break;
929         case IsTypedArrayView:
930             compileIsTypedArrayView();
931             break;
932         case TypeOf:
933             compileTypeOf();
934             break;
935         case CheckTypeInfoFlags:
936             compileCheckTypeInfoFlags();
937             break;
938         case OverridesHasInstance:
939             compileOverridesHasInstance();
940             break;
941         case InstanceOf:
942             compileInstanceOf();
943             break;
944         case InstanceOfCustom:
945             compileInstanceOfCustom();
946             break;
947         case CountExecution:
948             compileCountExecution();
949             break;
950         case StoreBarrier:
951             compileStoreBarrier();
952             break;
953         case HasIndexedProperty:
954             compileHasIndexedProperty();
955             break;
956         case HasGenericProperty:
957             compileHasGenericProperty();
958             break;
959         case HasStructureProperty:
960             compileHasStructureProperty();
961             break;
962         case GetDirectPname:
963             compileGetDirectPname();
964             break;
965         case GetEnumerableLength:
966             compileGetEnumerableLength();
967             break;
968         case GetPropertyEnumerator:
969             compileGetPropertyEnumerator();
970             break;
971         case GetEnumeratorStructurePname:
972             compileGetEnumeratorStructurePname();
973             break;
974         case GetEnumeratorGenericPname:
975             compileGetEnumeratorGenericPname();
976             break;
977         case ToIndexString:
978             compileToIndexString();
979             break;
980         case CheckStructureImmediate:
981             compileCheckStructureImmediate();
982             break;
983         case MaterializeNewObject:
984             compileMaterializeNewObject();
985             break;
986         case MaterializeCreateActivation:
987             compileMaterializeCreateActivation();
988             break;
989         case CheckWatchdogTimer:
990             compileCheckWatchdogTimer();
991             break;
992         case CreateRest:
993             compileCreateRest();
994             break;
995         case GetRestLength:
996             compileGetRestLength();
997             break;
998         case RegExpExec:
999             compileRegExpExec();
1000             break;
1001         case RegExpTest:
1002             compileRegExpTest();
1003             break;
1004         case NewRegexp:
1005             compileNewRegexp();
1006             break;
1007         case SetFunctionName:
1008             compileSetFunctionName();
1009             break;
1010         case StringReplace:
1011         case StringReplaceRegExp:
1012             compileStringReplace();
1013             break;
1014         case GetRegExpObjectLastIndex:
1015             compileGetRegExpObjectLastIndex();
1016             break;
1017         case SetRegExpObjectLastIndex:
1018             compileSetRegExpObjectLastIndex();
1019             break;
1020         case LogShadowChickenPrologue:
1021             compileLogShadowChickenPrologue();
1022             break;
1023         case LogShadowChickenTail:
1024             compileLogShadowChickenTail();
1025             break;
1026         case RecordRegExpCachedResult:
1027             compileRecordRegExpCachedResult();
1028             break;
1029         case ResolveScope:
1030             compileResolveScope();
1031             break;
1032         case GetDynamicVar:
1033             compileGetDynamicVar();
1034             break;
1035         case PutDynamicVar:
1036             compilePutDynamicVar();
1037             break;
1038         case Unreachable:
1039             compileUnreachable();
1040             break;
1041
1042         case PhantomLocal:
1043         case LoopHint:
1044         case MovHint:
1045         case ZombieHint:
1046         case ExitOK:
1047         case PhantomNewObject:
1048         case PhantomNewFunction:
1049         case PhantomNewGeneratorFunction:
1050         case PhantomCreateActivation:
1051         case PhantomDirectArguments:
1052         case PhantomClonedArguments:
1053         case PutHint:
1054         case BottomValue:
1055         case KillStack:
1056             break;
1057         default:
1058             DFG_CRASH(m_graph, m_node, "Unrecognized node in FTL backend");
1059             break;
1060         }
1061         
1062         if (m_node->isTerminal())
1063             return false;
1064         
1065         if (!m_state.isValid()) {
1066             safelyInvalidateAfterTermination();
1067             return false;
1068         }
1069
1070         m_availabilityCalculator.executeNode(m_node);
1071         m_interpreter.executeEffects(nodeIndex);
1072         
1073         return true;
1074     }
1075
1076     void compileUpsilon()
1077     {
1078         LValue upsilonValue = nullptr;
1079         switch (m_node->child1().useKind()) {
1080         case DoubleRepUse:
1081             upsilonValue = lowDouble(m_node->child1());
1082             break;
1083         case Int32Use:
1084         case KnownInt32Use:
1085             upsilonValue = lowInt32(m_node->child1());
1086             break;
1087         case Int52RepUse:
1088             upsilonValue = lowInt52(m_node->child1());
1089             break;
1090         case BooleanUse:
1091         case KnownBooleanUse:
1092             upsilonValue = lowBoolean(m_node->child1());
1093             break;
1094         case CellUse:
1095         case KnownCellUse:
1096             upsilonValue = lowCell(m_node->child1());
1097             break;
1098         case UntypedUse:
1099             upsilonValue = lowJSValue(m_node->child1());
1100             break;
1101         default:
1102             DFG_CRASH(m_graph, m_node, "Bad use kind");
1103             break;
1104         }
1105         ValueFromBlock upsilon = m_out.anchor(upsilonValue);
1106         LValue phiNode = m_phis.get(m_node->phi());
1107         m_out.addIncomingToPhi(phiNode, upsilon);
1108     }
1109     
1110     void compilePhi()
1111     {
1112         LValue phi = m_phis.get(m_node);
1113         m_out.m_block->append(phi);
1114
1115         switch (m_node->flags() & NodeResultMask) {
1116         case NodeResultDouble:
1117             setDouble(phi);
1118             break;
1119         case NodeResultInt32:
1120             setInt32(phi);
1121             break;
1122         case NodeResultInt52:
1123             setInt52(phi);
1124             break;
1125         case NodeResultBoolean:
1126             setBoolean(phi);
1127             break;
1128         case NodeResultJS:
1129             setJSValue(phi);
1130             break;
1131         default:
1132             DFG_CRASH(m_graph, m_node, "Bad use kind");
1133             break;
1134         }
1135     }
1136     
1137     void compileDoubleConstant()
1138     {
1139         setDouble(m_out.constDouble(m_node->asNumber()));
1140     }
1141     
1142     void compileInt52Constant()
1143     {
1144         int64_t value = m_node->asAnyInt();
1145         
1146         setInt52(m_out.constInt64(value << JSValue::int52ShiftAmount));
1147         setStrictInt52(m_out.constInt64(value));
1148     }
1149
1150     void compileLazyJSConstant()
1151     {
1152         PatchpointValue* patchpoint = m_out.patchpoint(Int64);
1153         LazyJSValue value = m_node->lazyJSValue();
1154         patchpoint->setGenerator(
1155             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
1156                 value.emit(jit, JSValueRegs(params[0].gpr()));
1157             });
1158         patchpoint->effects = Effects::none();
1159         setJSValue(patchpoint);
1160     }
1161
1162     void compileDoubleRep()
1163     {
1164         switch (m_node->child1().useKind()) {
1165         case RealNumberUse: {
1166             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
1167             
1168             LValue doubleValue = unboxDouble(value);
1169             
1170             LBasicBlock intCase = m_out.newBlock();
1171             LBasicBlock continuation = m_out.newBlock();
1172             
1173             ValueFromBlock fastResult = m_out.anchor(doubleValue);
1174             m_out.branch(
1175                 m_out.doubleEqual(doubleValue, doubleValue),
1176                 usually(continuation), rarely(intCase));
1177             
1178             LBasicBlock lastNext = m_out.appendTo(intCase, continuation);
1179
1180             FTL_TYPE_CHECK(
1181                 jsValueValue(value), m_node->child1(), SpecBytecodeRealNumber,
1182                 isNotInt32(value, provenType(m_node->child1()) & ~SpecDoubleReal));
1183             ValueFromBlock slowResult = m_out.anchor(m_out.intToDouble(unboxInt32(value)));
1184             m_out.jump(continuation);
1185             
1186             m_out.appendTo(continuation, lastNext);
1187             
1188             setDouble(m_out.phi(Double, fastResult, slowResult));
1189             return;
1190         }
1191             
1192         case NotCellUse:
1193         case NumberUse: {
1194             bool shouldConvertNonNumber = m_node->child1().useKind() == NotCellUse;
1195             
1196             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
1197
1198             LBasicBlock intCase = m_out.newBlock();
1199             LBasicBlock doubleTesting = m_out.newBlock();
1200             LBasicBlock doubleCase = m_out.newBlock();
1201             LBasicBlock nonDoubleCase = m_out.newBlock();
1202             LBasicBlock continuation = m_out.newBlock();
1203             
1204             m_out.branch(
1205                 isNotInt32(value, provenType(m_node->child1())),
1206                 unsure(doubleTesting), unsure(intCase));
1207             
1208             LBasicBlock lastNext = m_out.appendTo(intCase, doubleTesting);
1209             
1210             ValueFromBlock intToDouble = m_out.anchor(
1211                 m_out.intToDouble(unboxInt32(value)));
1212             m_out.jump(continuation);
1213             
1214             m_out.appendTo(doubleTesting, doubleCase);
1215             LValue valueIsNumber = isNumber(value, provenType(m_node->child1()));
1216             m_out.branch(valueIsNumber, usually(doubleCase), rarely(nonDoubleCase));
1217
1218             m_out.appendTo(doubleCase, nonDoubleCase);
1219             ValueFromBlock unboxedDouble = m_out.anchor(unboxDouble(value));
1220             m_out.jump(continuation);
1221
1222             if (shouldConvertNonNumber) {
1223                 LBasicBlock undefinedCase = m_out.newBlock();
1224                 LBasicBlock testNullCase = m_out.newBlock();
1225                 LBasicBlock nullCase = m_out.newBlock();
1226                 LBasicBlock testBooleanTrueCase = m_out.newBlock();
1227                 LBasicBlock convertBooleanTrueCase = m_out.newBlock();
1228                 LBasicBlock convertBooleanFalseCase = m_out.newBlock();
1229
1230                 m_out.appendTo(nonDoubleCase, undefinedCase);
1231                 LValue valueIsUndefined = m_out.equal(value, m_out.constInt64(ValueUndefined));
1232                 m_out.branch(valueIsUndefined, unsure(undefinedCase), unsure(testNullCase));
1233
1234                 m_out.appendTo(undefinedCase, testNullCase);
1235                 ValueFromBlock convertedUndefined = m_out.anchor(m_out.constDouble(PNaN));
1236                 m_out.jump(continuation);
1237
1238                 m_out.appendTo(testNullCase, nullCase);
1239                 LValue valueIsNull = m_out.equal(value, m_out.constInt64(ValueNull));
1240                 m_out.branch(valueIsNull, unsure(nullCase), unsure(testBooleanTrueCase));
1241
1242                 m_out.appendTo(nullCase, testBooleanTrueCase);
1243                 ValueFromBlock convertedNull = m_out.anchor(m_out.constDouble(0));
1244                 m_out.jump(continuation);
1245
1246                 m_out.appendTo(testBooleanTrueCase, convertBooleanTrueCase);
1247                 LValue valueIsBooleanTrue = m_out.equal(value, m_out.constInt64(ValueTrue));
1248                 m_out.branch(valueIsBooleanTrue, unsure(convertBooleanTrueCase), unsure(convertBooleanFalseCase));
1249
1250                 m_out.appendTo(convertBooleanTrueCase, convertBooleanFalseCase);
1251                 ValueFromBlock convertedTrue = m_out.anchor(m_out.constDouble(1));
1252                 m_out.jump(continuation);
1253
1254                 m_out.appendTo(convertBooleanFalseCase, continuation);
1255
1256                 LValue valueIsNotBooleanFalse = m_out.notEqual(value, m_out.constInt64(ValueFalse));
1257                 FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), ~SpecCell, valueIsNotBooleanFalse);
1258                 ValueFromBlock convertedFalse = m_out.anchor(m_out.constDouble(0));
1259                 m_out.jump(continuation);
1260
1261                 m_out.appendTo(continuation, lastNext);
1262                 setDouble(m_out.phi(Double, intToDouble, unboxedDouble, convertedUndefined, convertedNull, convertedTrue, convertedFalse));
1263                 return;
1264             }
1265             m_out.appendTo(nonDoubleCase, continuation);
1266             FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), SpecBytecodeNumber, m_out.booleanTrue);
1267             m_out.unreachable();
1268
1269             m_out.appendTo(continuation, lastNext);
1270
1271             setDouble(m_out.phi(Double, intToDouble, unboxedDouble));
1272             return;
1273         }
1274             
1275         case Int52RepUse: {
1276             setDouble(strictInt52ToDouble(lowStrictInt52(m_node->child1())));
1277             return;
1278         }
1279             
1280         default:
1281             DFG_CRASH(m_graph, m_node, "Bad use kind");
1282         }
1283     }
1284
1285     void compileDoubleAsInt32()
1286     {
1287         LValue integerValue = convertDoubleToInt32(lowDouble(m_node->child1()), shouldCheckNegativeZero(m_node->arithMode()));
1288         setInt32(integerValue);
1289     }
1290
1291     void compileValueRep()
1292     {
1293         switch (m_node->child1().useKind()) {
1294         case DoubleRepUse: {
1295             LValue value = lowDouble(m_node->child1());
1296             
1297             if (m_interpreter.needsTypeCheck(m_node->child1(), ~SpecDoubleImpureNaN)) {
1298                 value = m_out.select(
1299                     m_out.doubleEqual(value, value), value, m_out.constDouble(PNaN));
1300             }
1301             
1302             setJSValue(boxDouble(value));
1303             return;
1304         }
1305             
1306         case Int52RepUse: {
1307             setJSValue(strictInt52ToJSValue(lowStrictInt52(m_node->child1())));
1308             return;
1309         }
1310             
1311         default:
1312             DFG_CRASH(m_graph, m_node, "Bad use kind");
1313         }
1314     }
1315     
1316     void compileInt52Rep()
1317     {
1318         switch (m_node->child1().useKind()) {
1319         case Int32Use:
1320             setStrictInt52(m_out.signExt32To64(lowInt32(m_node->child1())));
1321             return;
1322             
1323         case AnyIntUse:
1324             setStrictInt52(
1325                 jsValueToStrictInt52(
1326                     m_node->child1(), lowJSValue(m_node->child1(), ManualOperandSpeculation)));
1327             return;
1328             
1329         case DoubleRepAnyIntUse:
1330             setStrictInt52(
1331                 doubleToStrictInt52(
1332                     m_node->child1(), lowDouble(m_node->child1())));
1333             return;
1334             
1335         default:
1336             RELEASE_ASSERT_NOT_REACHED();
1337         }
1338     }
1339     
1340     void compileValueToInt32()
1341     {
1342         switch (m_node->child1().useKind()) {
1343         case Int52RepUse:
1344             setInt32(m_out.castToInt32(lowStrictInt52(m_node->child1())));
1345             break;
1346             
1347         case DoubleRepUse:
1348             setInt32(doubleToInt32(lowDouble(m_node->child1())));
1349             break;
1350             
1351         case NumberUse:
1352         case NotCellUse: {
1353             LoweredNodeValue value = m_int32Values.get(m_node->child1().node());
1354             if (isValid(value)) {
1355                 setInt32(value.value());
1356                 break;
1357             }
1358             
1359             value = m_jsValueValues.get(m_node->child1().node());
1360             if (isValid(value)) {
1361                 setInt32(numberOrNotCellToInt32(m_node->child1(), value.value()));
1362                 break;
1363             }
1364             
1365             // We'll basically just get here for constants. But it's good to have this
1366             // catch-all since we often add new representations into the mix.
1367             setInt32(
1368                 numberOrNotCellToInt32(
1369                     m_node->child1(),
1370                     lowJSValue(m_node->child1(), ManualOperandSpeculation)));
1371             break;
1372         }
1373             
1374         default:
1375             DFG_CRASH(m_graph, m_node, "Bad use kind");
1376             break;
1377         }
1378     }
1379     
1380     void compileBooleanToNumber()
1381     {
1382         switch (m_node->child1().useKind()) {
1383         case BooleanUse: {
1384             setInt32(m_out.zeroExt(lowBoolean(m_node->child1()), Int32));
1385             return;
1386         }
1387             
1388         case UntypedUse: {
1389             LValue value = lowJSValue(m_node->child1());
1390             
1391             if (!m_interpreter.needsTypeCheck(m_node->child1(), SpecBoolInt32 | SpecBoolean)) {
1392                 setInt32(m_out.bitAnd(m_out.castToInt32(value), m_out.int32One));
1393                 return;
1394             }
1395             
1396             LBasicBlock booleanCase = m_out.newBlock();
1397             LBasicBlock continuation = m_out.newBlock();
1398             
1399             ValueFromBlock notBooleanResult = m_out.anchor(value);
1400             m_out.branch(
1401                 isBoolean(value, provenType(m_node->child1())),
1402                 unsure(booleanCase), unsure(continuation));
1403             
1404             LBasicBlock lastNext = m_out.appendTo(booleanCase, continuation);
1405             ValueFromBlock booleanResult = m_out.anchor(m_out.bitOr(
1406                 m_out.zeroExt(unboxBoolean(value), Int64), m_tagTypeNumber));
1407             m_out.jump(continuation);
1408             
1409             m_out.appendTo(continuation, lastNext);
1410             setJSValue(m_out.phi(Int64, booleanResult, notBooleanResult));
1411             return;
1412         }
1413             
1414         default:
1415             RELEASE_ASSERT_NOT_REACHED();
1416             return;
1417         }
1418     }
1419
1420     void compileExtractOSREntryLocal()
1421     {
1422         EncodedJSValue* buffer = static_cast<EncodedJSValue*>(
1423             m_ftlState.jitCode->ftlForOSREntry()->entryBuffer()->dataBuffer());
1424         setJSValue(m_out.load64(m_out.absolute(buffer + m_node->unlinkedLocal().toLocal())));
1425     }
1426     
1427     void compileGetStack()
1428     {
1429         // GetLocals arise only for captured variables and arguments. For arguments, we might have
1430         // already loaded it.
1431         if (LValue value = m_loadedArgumentValues.get(m_node)) {
1432             setJSValue(value);
1433             return;
1434         }
1435         
1436         StackAccessData* data = m_node->stackAccessData();
1437         AbstractValue& value = m_state.variables().operand(data->local);
1438         
1439         DFG_ASSERT(m_graph, m_node, isConcrete(data->format));
1440         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.
1441         
1442         if (isInt32Speculation(value.m_type))
1443             setInt32(m_out.load32(payloadFor(data->machineLocal)));
1444         else
1445             setJSValue(m_out.load64(addressFor(data->machineLocal)));
1446     }
1447     
1448     void compilePutStack()
1449     {
1450         StackAccessData* data = m_node->stackAccessData();
1451         switch (data->format) {
1452         case FlushedJSValue: {
1453             LValue value = lowJSValue(m_node->child1());
1454             m_out.store64(value, addressFor(data->machineLocal));
1455             break;
1456         }
1457             
1458         case FlushedDouble: {
1459             LValue value = lowDouble(m_node->child1());
1460             m_out.storeDouble(value, addressFor(data->machineLocal));
1461             break;
1462         }
1463             
1464         case FlushedInt32: {
1465             LValue value = lowInt32(m_node->child1());
1466             m_out.store32(value, payloadFor(data->machineLocal));
1467             break;
1468         }
1469             
1470         case FlushedInt52: {
1471             LValue value = lowInt52(m_node->child1());
1472             m_out.store64(value, addressFor(data->machineLocal));
1473             break;
1474         }
1475             
1476         case FlushedCell: {
1477             LValue value = lowCell(m_node->child1());
1478             m_out.store64(value, addressFor(data->machineLocal));
1479             break;
1480         }
1481             
1482         case FlushedBoolean: {
1483             speculateBoolean(m_node->child1());
1484             m_out.store64(
1485                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
1486                 addressFor(data->machineLocal));
1487             break;
1488         }
1489             
1490         default:
1491             DFG_CRASH(m_graph, m_node, "Bad flush format");
1492             break;
1493         }
1494     }
1495     
1496     void compileNoOp()
1497     {
1498         DFG_NODE_DO_TO_CHILDREN(m_graph, m_node, speculate);
1499     }
1500
1501     void compileCallObjectConstructor()
1502     {
1503         JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
1504         LValue value = lowJSValue(m_node->child1());
1505
1506         LBasicBlock isCellCase = m_out.newBlock();
1507         LBasicBlock slowCase = m_out.newBlock();
1508         LBasicBlock continuation = m_out.newBlock();
1509
1510         m_out.branch(isCell(value, provenType(m_node->child1())), usually(isCellCase), rarely(slowCase));
1511
1512         LBasicBlock lastNext = m_out.appendTo(isCellCase, slowCase);
1513         ValueFromBlock fastResult = m_out.anchor(value);
1514         m_out.branch(isObject(value), usually(continuation), rarely(slowCase));
1515
1516         m_out.appendTo(slowCase, continuation);
1517         ValueFromBlock slowResult = m_out.anchor(vmCall(Int64, m_out.operation(operationObjectConstructor), m_callFrame, m_out.constIntPtr(globalObject), value));
1518         m_out.jump(continuation);
1519
1520         m_out.appendTo(continuation, lastNext);
1521         setJSValue(m_out.phi(Int64, fastResult, slowResult));
1522     }
1523     
1524     void compileToThis()
1525     {
1526         LValue value = lowJSValue(m_node->child1());
1527         
1528         LBasicBlock isCellCase = m_out.newBlock();
1529         LBasicBlock slowCase = m_out.newBlock();
1530         LBasicBlock continuation = m_out.newBlock();
1531         
1532         m_out.branch(
1533             isCell(value, provenType(m_node->child1())), usually(isCellCase), rarely(slowCase));
1534         
1535         LBasicBlock lastNext = m_out.appendTo(isCellCase, slowCase);
1536         ValueFromBlock fastResult = m_out.anchor(value);
1537         m_out.branch(
1538             m_out.testIsZero32(
1539                 m_out.load8ZeroExt32(value, m_heaps.JSCell_typeInfoFlags),
1540                 m_out.constInt32(OverridesToThis)),
1541             usually(continuation), rarely(slowCase));
1542         
1543         m_out.appendTo(slowCase, continuation);
1544         J_JITOperation_EJ function;
1545         if (m_graph.isStrictModeFor(m_node->origin.semantic))
1546             function = operationToThisStrict;
1547         else
1548             function = operationToThis;
1549         ValueFromBlock slowResult = m_out.anchor(
1550             vmCall(Int64, m_out.operation(function), m_callFrame, value));
1551         m_out.jump(continuation);
1552         
1553         m_out.appendTo(continuation, lastNext);
1554         setJSValue(m_out.phi(Int64, fastResult, slowResult));
1555     }
1556
1557     void compileValueAdd()
1558     {
1559         JITAddIC* addIC = codeBlock()->addJITAddIC();
1560         auto repatchingFunction = operationValueAddOptimize;
1561         auto nonRepatchingFunction = operationValueAdd;
1562         compileMathIC(addIC, repatchingFunction, nonRepatchingFunction);
1563     }
1564
1565     template <typename Generator>
1566     void compileMathIC(JITMathIC<Generator>* mathIC, FunctionPtr repatchingFunction, FunctionPtr nonRepatchingFunction)
1567     {
1568         Node* node = m_node;
1569         
1570         LValue left = lowJSValue(node->child1());
1571         LValue right = lowJSValue(node->child2());
1572
1573         SnippetOperand leftOperand(m_state.forNode(node->child1()).resultType());
1574         SnippetOperand rightOperand(m_state.forNode(node->child2()).resultType());
1575             
1576         PatchpointValue* patchpoint = m_out.patchpoint(Int64);
1577         patchpoint->appendSomeRegister(left);
1578         patchpoint->appendSomeRegister(right);
1579         patchpoint->append(m_tagMask, ValueRep::lateReg(GPRInfo::tagMaskRegister));
1580         patchpoint->append(m_tagTypeNumber, ValueRep::lateReg(GPRInfo::tagTypeNumberRegister));
1581         RefPtr<PatchpointExceptionHandle> exceptionHandle =
1582             preparePatchpointForExceptions(patchpoint);
1583         patchpoint->numGPScratchRegisters = 1;
1584         patchpoint->numFPScratchRegisters = 2;
1585         patchpoint->clobber(RegisterSet::macroScratchRegisters());
1586         State* state = &m_ftlState;
1587         patchpoint->setGenerator(
1588             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
1589                 AllowMacroScratchRegisterUsage allowScratch(jit);
1590
1591                 Box<CCallHelpers::JumpList> exceptions =
1592                     exceptionHandle->scheduleExitCreation(params)->jumps(jit);
1593
1594 #if ENABLE(MATH_IC_STATS)
1595                 auto inlineStart = jit.label();
1596 #endif
1597
1598                 Box<MathICGenerationState> mathICGenerationState = Box<MathICGenerationState>::create();
1599                 ArithProfile* arithProfile = state->graph.baselineCodeBlockFor(node->origin.semantic)->arithProfileForBytecodeOffset(node->origin.semantic.bytecodeIndex);
1600                 mathIC->m_generator = Generator(leftOperand, rightOperand, JSValueRegs(params[0].gpr()),
1601                     JSValueRegs(params[1].gpr()), JSValueRegs(params[2].gpr()), params.fpScratch(0),
1602                     params.fpScratch(1), params.gpScratch(0), InvalidFPRReg, arithProfile);
1603
1604                 bool shouldEmitProfiling = false;
1605                 bool generatedInline = mathIC->generateInline(jit, *mathICGenerationState, shouldEmitProfiling);
1606
1607                 if (generatedInline) {
1608                     ASSERT(!mathICGenerationState->slowPathJumps.empty());
1609                     auto done = jit.label();
1610                     params.addLatePath([=] (CCallHelpers& jit) {
1611                         AllowMacroScratchRegisterUsage allowScratch(jit);
1612                         mathICGenerationState->slowPathJumps.link(&jit);
1613                         mathICGenerationState->slowPathStart = jit.label();
1614 #if ENABLE(MATH_IC_STATS)
1615                         auto slowPathStart = jit.label();
1616 #endif
1617
1618                         if (mathICGenerationState->shouldSlowPathRepatch) {
1619                             SlowPathCall call = callOperation(*state, params.unavailableRegisters(), jit, node->origin.semantic, exceptions.get(),
1620                                 repatchingFunction, params[0].gpr(), params[1].gpr(), params[2].gpr(), CCallHelpers::TrustedImmPtr(mathIC));
1621                             mathICGenerationState->slowPathCall = call.call();
1622                         } else {
1623                             SlowPathCall call = callOperation(*state, params.unavailableRegisters(), jit, node->origin.semantic,
1624                                 exceptions.get(), nonRepatchingFunction, params[0].gpr(), params[1].gpr(), params[2].gpr());
1625                             mathICGenerationState->slowPathCall = call.call();
1626                         }
1627                         jit.jump().linkTo(done, &jit);
1628
1629                         jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1630                             mathIC->finalizeInlineCode(*mathICGenerationState, linkBuffer);
1631                         });
1632
1633 #if ENABLE(MATH_IC_STATS)
1634                         auto slowPathEnd = jit.label();
1635                         jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1636                             size_t size = static_cast<char*>(linkBuffer.locationOf(slowPathEnd).executableAddress()) - static_cast<char*>(linkBuffer.locationOf(slowPathStart).executableAddress());
1637                             mathIC->m_generatedCodeSize += size;
1638                         });
1639 #endif
1640                     });
1641                 } else {
1642                     callOperation(
1643                         *state, params.unavailableRegisters(), jit, node->origin.semantic, exceptions.get(),
1644                         nonRepatchingFunction, params[0].gpr(), params[1].gpr(), params[2].gpr());
1645                 }
1646
1647 #if ENABLE(MATH_IC_STATS)
1648                 auto inlineEnd = jit.label();
1649                 jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1650                     size_t size = static_cast<char*>(linkBuffer.locationOf(inlineEnd).executableAddress()) - static_cast<char*>(linkBuffer.locationOf(inlineStart).executableAddress());
1651                     mathIC->m_generatedCodeSize += size;
1652                 });
1653 #endif
1654             });
1655
1656         setJSValue(patchpoint);
1657     }
1658     
1659     void compileStrCat()
1660     {
1661         LValue result;
1662         if (m_node->child3()) {
1663             result = vmCall(
1664                 Int64, m_out.operation(operationStrCat3), m_callFrame,
1665                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
1666                 lowJSValue(m_node->child2(), ManualOperandSpeculation),
1667                 lowJSValue(m_node->child3(), ManualOperandSpeculation));
1668         } else {
1669             result = vmCall(
1670                 Int64, m_out.operation(operationStrCat2), m_callFrame,
1671                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
1672                 lowJSValue(m_node->child2(), ManualOperandSpeculation));
1673         }
1674         setJSValue(result);
1675     }
1676     
1677     void compileArithAddOrSub()
1678     {
1679         bool isSub =  m_node->op() == ArithSub;
1680         switch (m_node->binaryUseKind()) {
1681         case Int32Use: {
1682             LValue left = lowInt32(m_node->child1());
1683             LValue right = lowInt32(m_node->child2());
1684
1685             if (!shouldCheckOverflow(m_node->arithMode())) {
1686                 setInt32(isSub ? m_out.sub(left, right) : m_out.add(left, right));
1687                 break;
1688             }
1689
1690             CheckValue* result =
1691                 isSub ? m_out.speculateSub(left, right) : m_out.speculateAdd(left, right);
1692             blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);
1693             setInt32(result);
1694             break;
1695         }
1696             
1697         case Int52RepUse: {
1698             if (!abstractValue(m_node->child1()).couldBeType(SpecInt52Only)
1699                 && !abstractValue(m_node->child2()).couldBeType(SpecInt52Only)) {
1700                 Int52Kind kind;
1701                 LValue left = lowWhicheverInt52(m_node->child1(), kind);
1702                 LValue right = lowInt52(m_node->child2(), kind);
1703                 setInt52(isSub ? m_out.sub(left, right) : m_out.add(left, right), kind);
1704                 break;
1705             }
1706
1707             LValue left = lowInt52(m_node->child1());
1708             LValue right = lowInt52(m_node->child2());
1709             CheckValue* result =
1710                 isSub ? m_out.speculateSub(left, right) : m_out.speculateAdd(left, right);
1711             blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);
1712             setInt52(result);
1713             break;
1714         }
1715             
1716         case DoubleRepUse: {
1717             LValue C1 = lowDouble(m_node->child1());
1718             LValue C2 = lowDouble(m_node->child2());
1719
1720             setDouble(isSub ? m_out.doubleSub(C1, C2) : m_out.doubleAdd(C1, C2));
1721             break;
1722         }
1723
1724         case UntypedUse: {
1725             if (!isSub) {
1726                 DFG_CRASH(m_graph, m_node, "Bad use kind");
1727                 break;
1728             }
1729
1730             JITSubIC* subIC = codeBlock()->addJITSubIC();
1731             auto repatchingFunction = operationValueSubOptimize;
1732             auto nonRepatchingFunction = operationValueSub;
1733             compileMathIC(subIC, repatchingFunction, nonRepatchingFunction);
1734             break;
1735         }
1736
1737         default:
1738             DFG_CRASH(m_graph, m_node, "Bad use kind");
1739             break;
1740         }
1741     }
1742
1743     void compileArithClz32()
1744     {
1745         if (m_node->child1().useKind() == Int32Use || m_node->child1().useKind() == KnownInt32Use) {
1746             LValue operand = lowInt32(m_node->child1());
1747             setInt32(m_out.ctlz32(operand));
1748             return;
1749         }
1750         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
1751         LValue argument = lowJSValue(m_node->child1());
1752         LValue result = vmCall(Int32, m_out.operation(operationArithClz32), m_callFrame, argument);
1753         setInt32(result);
1754     }
1755     
1756     void compileArithMul()
1757     {
1758         switch (m_node->binaryUseKind()) {
1759         case Int32Use: {
1760             LValue left = lowInt32(m_node->child1());
1761             LValue right = lowInt32(m_node->child2());
1762             
1763             LValue result;
1764
1765             if (!shouldCheckOverflow(m_node->arithMode()))
1766                 result = m_out.mul(left, right);
1767             else {
1768                 CheckValue* speculation = m_out.speculateMul(left, right);
1769                 blessSpeculation(speculation, Overflow, noValue(), nullptr, m_origin);
1770                 result = speculation;
1771             }
1772             
1773             if (shouldCheckNegativeZero(m_node->arithMode())) {
1774                 LBasicBlock slowCase = m_out.newBlock();
1775                 LBasicBlock continuation = m_out.newBlock();
1776                 
1777                 m_out.branch(
1778                     m_out.notZero32(result), usually(continuation), rarely(slowCase));
1779                 
1780                 LBasicBlock lastNext = m_out.appendTo(slowCase, continuation);
1781                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(left, m_out.int32Zero));
1782                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(right, m_out.int32Zero));
1783                 m_out.jump(continuation);
1784                 m_out.appendTo(continuation, lastNext);
1785             }
1786             
1787             setInt32(result);
1788             break;
1789         }
1790             
1791         case Int52RepUse: {
1792             Int52Kind kind;
1793             LValue left = lowWhicheverInt52(m_node->child1(), kind);
1794             LValue right = lowInt52(m_node->child2(), opposite(kind));
1795
1796             CheckValue* result = m_out.speculateMul(left, right);
1797             blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);
1798
1799             if (shouldCheckNegativeZero(m_node->arithMode())) {
1800                 LBasicBlock slowCase = m_out.newBlock();
1801                 LBasicBlock continuation = m_out.newBlock();
1802                 
1803                 m_out.branch(
1804                     m_out.notZero64(result), usually(continuation), rarely(slowCase));
1805                 
1806                 LBasicBlock lastNext = m_out.appendTo(slowCase, continuation);
1807                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(left, m_out.int64Zero));
1808                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(right, m_out.int64Zero));
1809                 m_out.jump(continuation);
1810                 m_out.appendTo(continuation, lastNext);
1811             }
1812             
1813             setInt52(result);
1814             break;
1815         }
1816             
1817         case DoubleRepUse: {
1818             setDouble(
1819                 m_out.doubleMul(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
1820             break;
1821         }
1822
1823         case UntypedUse: {
1824             JITMulIC* mulIC = codeBlock()->addJITMulIC();
1825             auto repatchingFunction = operationValueMulOptimize;
1826             auto nonRepatchingFunction = operationValueMul;
1827             compileMathIC(mulIC, repatchingFunction, nonRepatchingFunction);
1828             break;
1829         }
1830
1831         default:
1832             DFG_CRASH(m_graph, m_node, "Bad use kind");
1833             break;
1834         }
1835     }
1836
1837     void compileArithDiv()
1838     {
1839         switch (m_node->binaryUseKind()) {
1840         case Int32Use: {
1841             LValue numerator = lowInt32(m_node->child1());
1842             LValue denominator = lowInt32(m_node->child2());
1843
1844             if (shouldCheckNegativeZero(m_node->arithMode())) {
1845                 LBasicBlock zeroNumerator = m_out.newBlock();
1846                 LBasicBlock numeratorContinuation = m_out.newBlock();
1847
1848                 m_out.branch(
1849                     m_out.isZero32(numerator),
1850                     rarely(zeroNumerator), usually(numeratorContinuation));
1851
1852                 LBasicBlock innerLastNext = m_out.appendTo(zeroNumerator, numeratorContinuation);
1853
1854                 speculate(
1855                     NegativeZero, noValue(), 0, m_out.lessThan(denominator, m_out.int32Zero));
1856
1857                 m_out.jump(numeratorContinuation);
1858
1859                 m_out.appendTo(numeratorContinuation, innerLastNext);
1860             }
1861             
1862             if (shouldCheckOverflow(m_node->arithMode())) {
1863                 LBasicBlock unsafeDenominator = m_out.newBlock();
1864                 LBasicBlock continuation = m_out.newBlock();
1865
1866                 LValue adjustedDenominator = m_out.add(denominator, m_out.int32One);
1867                 m_out.branch(
1868                     m_out.above(adjustedDenominator, m_out.int32One),
1869                     usually(continuation), rarely(unsafeDenominator));
1870
1871                 LBasicBlock lastNext = m_out.appendTo(unsafeDenominator, continuation);
1872                 LValue neg2ToThe31 = m_out.constInt32(-2147483647-1);
1873                 speculate(Overflow, noValue(), nullptr, m_out.isZero32(denominator));
1874                 speculate(Overflow, noValue(), nullptr, m_out.equal(numerator, neg2ToThe31));
1875                 m_out.jump(continuation);
1876
1877                 m_out.appendTo(continuation, lastNext);
1878                 LValue result = m_out.div(numerator, denominator);
1879                 speculate(
1880                     Overflow, noValue(), 0,
1881                     m_out.notEqual(m_out.mul(result, denominator), numerator));
1882                 setInt32(result);
1883             } else
1884                 setInt32(m_out.chillDiv(numerator, denominator));
1885
1886             break;
1887         }
1888             
1889         case DoubleRepUse: {
1890             setDouble(m_out.doubleDiv(
1891                 lowDouble(m_node->child1()), lowDouble(m_node->child2())));
1892             break;
1893         }
1894
1895         case UntypedUse: {
1896             emitBinarySnippet<JITDivGenerator, NeedScratchFPR>(operationValueDiv);
1897             break;
1898         }
1899
1900         default:
1901             DFG_CRASH(m_graph, m_node, "Bad use kind");
1902             break;
1903         }
1904     }
1905     
1906     void compileArithMod()
1907     {
1908         switch (m_node->binaryUseKind()) {
1909         case Int32Use: {
1910             LValue numerator = lowInt32(m_node->child1());
1911             LValue denominator = lowInt32(m_node->child2());
1912
1913             LValue remainder;
1914             if (shouldCheckOverflow(m_node->arithMode())) {
1915                 LBasicBlock unsafeDenominator = m_out.newBlock();
1916                 LBasicBlock continuation = m_out.newBlock();
1917
1918                 LValue adjustedDenominator = m_out.add(denominator, m_out.int32One);
1919                 m_out.branch(
1920                     m_out.above(adjustedDenominator, m_out.int32One),
1921                     usually(continuation), rarely(unsafeDenominator));
1922
1923                 LBasicBlock lastNext = m_out.appendTo(unsafeDenominator, continuation);
1924                 LValue neg2ToThe31 = m_out.constInt32(-2147483647-1);
1925                 speculate(Overflow, noValue(), nullptr, m_out.isZero32(denominator));
1926                 speculate(Overflow, noValue(), nullptr, m_out.equal(numerator, neg2ToThe31));
1927                 m_out.jump(continuation);
1928
1929                 m_out.appendTo(continuation, lastNext);
1930                 LValue result = m_out.mod(numerator, denominator);
1931                 remainder = result;
1932             } else
1933                 remainder = m_out.chillMod(numerator, denominator);
1934
1935             if (shouldCheckNegativeZero(m_node->arithMode())) {
1936                 LBasicBlock negativeNumerator = m_out.newBlock();
1937                 LBasicBlock numeratorContinuation = m_out.newBlock();
1938
1939                 m_out.branch(
1940                     m_out.lessThan(numerator, m_out.int32Zero),
1941                     unsure(negativeNumerator), unsure(numeratorContinuation));
1942
1943                 LBasicBlock innerLastNext = m_out.appendTo(negativeNumerator, numeratorContinuation);
1944
1945                 speculate(NegativeZero, noValue(), 0, m_out.isZero32(remainder));
1946
1947                 m_out.jump(numeratorContinuation);
1948
1949                 m_out.appendTo(numeratorContinuation, innerLastNext);
1950             }
1951
1952             setInt32(remainder);
1953             break;
1954         }
1955             
1956         case DoubleRepUse: {
1957             setDouble(
1958                 m_out.doubleMod(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
1959             break;
1960         }
1961             
1962         default:
1963             DFG_CRASH(m_graph, m_node, "Bad use kind");
1964             break;
1965         }
1966     }
1967
1968     void compileArithMinOrMax()
1969     {
1970         switch (m_node->binaryUseKind()) {
1971         case Int32Use: {
1972             LValue left = lowInt32(m_node->child1());
1973             LValue right = lowInt32(m_node->child2());
1974             
1975             setInt32(
1976                 m_out.select(
1977                     m_node->op() == ArithMin
1978                         ? m_out.lessThan(left, right)
1979                         : m_out.lessThan(right, left),
1980                     left, right));
1981             break;
1982         }
1983             
1984         case DoubleRepUse: {
1985             LValue left = lowDouble(m_node->child1());
1986             LValue right = lowDouble(m_node->child2());
1987             
1988             LBasicBlock notLessThan = m_out.newBlock();
1989             LBasicBlock continuation = m_out.newBlock();
1990             
1991             Vector<ValueFromBlock, 2> results;
1992             
1993             results.append(m_out.anchor(left));
1994             m_out.branch(
1995                 m_node->op() == ArithMin
1996                     ? m_out.doubleLessThan(left, right)
1997                     : m_out.doubleGreaterThan(left, right),
1998                 unsure(continuation), unsure(notLessThan));
1999             
2000             LBasicBlock lastNext = m_out.appendTo(notLessThan, continuation);
2001             results.append(m_out.anchor(m_out.select(
2002                 m_node->op() == ArithMin
2003                     ? m_out.doubleGreaterThanOrEqual(left, right)
2004                     : m_out.doubleLessThanOrEqual(left, right),
2005                 right, m_out.constDouble(PNaN))));
2006             m_out.jump(continuation);
2007             
2008             m_out.appendTo(continuation, lastNext);
2009             setDouble(m_out.phi(Double, results));
2010             break;
2011         }
2012             
2013         default:
2014             DFG_CRASH(m_graph, m_node, "Bad use kind");
2015             break;
2016         }
2017     }
2018     
2019     void compileArithAbs()
2020     {
2021         switch (m_node->child1().useKind()) {
2022         case Int32Use: {
2023             LValue value = lowInt32(m_node->child1());
2024
2025             LValue mask = m_out.aShr(value, m_out.constInt32(31));
2026             LValue result = m_out.bitXor(mask, m_out.add(mask, value));
2027
2028             if (shouldCheckOverflow(m_node->arithMode()))
2029                 speculate(Overflow, noValue(), 0, m_out.lessThan(result, m_out.int32Zero));
2030
2031             setInt32(result);
2032             break;
2033         }
2034             
2035         case DoubleRepUse: {
2036             setDouble(m_out.doubleAbs(lowDouble(m_node->child1())));
2037             break;
2038         }
2039             
2040         default: {
2041             DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
2042             LValue argument = lowJSValue(m_node->child1());
2043             LValue result = vmCall(Double, m_out.operation(operationArithAbs), m_callFrame, argument);
2044             setDouble(result);
2045             break;
2046         }
2047         }
2048     }
2049
2050     void compileArithSin()
2051     {
2052         if (m_node->child1().useKind() == DoubleRepUse) {
2053             setDouble(m_out.doubleSin(lowDouble(m_node->child1())));
2054             return;
2055         }
2056         LValue argument = lowJSValue(m_node->child1());
2057         LValue result = vmCall(Double, m_out.operation(operationArithSin), m_callFrame, argument);
2058         setDouble(result);
2059     }
2060
2061     void compileArithCos()
2062     {
2063         if (m_node->child1().useKind() == DoubleRepUse) {
2064             setDouble(m_out.doubleCos(lowDouble(m_node->child1())));
2065             return;
2066         }
2067         LValue argument = lowJSValue(m_node->child1());
2068         LValue result = vmCall(Double, m_out.operation(operationArithCos), m_callFrame, argument);
2069         setDouble(result);
2070     }
2071
2072     void compileArithTan()
2073     {
2074         if (m_node->child1().useKind() == DoubleRepUse) {
2075             setDouble(m_out.doubleTan(lowDouble(m_node->child1())));
2076             return;
2077         }
2078         LValue argument = lowJSValue(m_node->child1());
2079         LValue result = vmCall(Double, m_out.operation(operationArithTan), m_callFrame, argument);
2080         setDouble(result);
2081     }
2082
2083     void compileArithPow()
2084     {
2085         if (m_node->child2().useKind() == Int32Use)
2086             setDouble(m_out.doublePowi(lowDouble(m_node->child1()), lowInt32(m_node->child2())));
2087         else {
2088             LValue base = lowDouble(m_node->child1());
2089             LValue exponent = lowDouble(m_node->child2());
2090
2091             LBasicBlock integerExponentIsSmallBlock = m_out.newBlock();
2092             LBasicBlock integerExponentPowBlock = m_out.newBlock();
2093             LBasicBlock doubleExponentPowBlockEntry = m_out.newBlock();
2094             LBasicBlock nanExceptionBaseIsOne = m_out.newBlock();
2095             LBasicBlock nanExceptionExponentIsInfinity = m_out.newBlock();
2096             LBasicBlock testExponentIsOneHalf = m_out.newBlock();
2097             LBasicBlock handleBaseZeroExponentIsOneHalf = m_out.newBlock();
2098             LBasicBlock handleInfinityForExponentIsOneHalf = m_out.newBlock();
2099             LBasicBlock exponentIsOneHalfNormal = m_out.newBlock();
2100             LBasicBlock exponentIsOneHalfInfinity = m_out.newBlock();
2101             LBasicBlock testExponentIsNegativeOneHalf = m_out.newBlock();
2102             LBasicBlock testBaseZeroExponentIsNegativeOneHalf = m_out.newBlock();
2103             LBasicBlock handleBaseZeroExponentIsNegativeOneHalf = m_out.newBlock();
2104             LBasicBlock handleInfinityForExponentIsNegativeOneHalf = m_out.newBlock();
2105             LBasicBlock exponentIsNegativeOneHalfNormal = m_out.newBlock();
2106             LBasicBlock exponentIsNegativeOneHalfInfinity = m_out.newBlock();
2107             LBasicBlock powBlock = m_out.newBlock();
2108             LBasicBlock nanExceptionResultIsNaN = m_out.newBlock();
2109             LBasicBlock continuation = m_out.newBlock();
2110
2111             LValue integerExponent = m_out.doubleToInt(exponent);
2112             LValue integerExponentConvertedToDouble = m_out.intToDouble(integerExponent);
2113             LValue exponentIsInteger = m_out.doubleEqual(exponent, integerExponentConvertedToDouble);
2114             m_out.branch(exponentIsInteger, unsure(integerExponentIsSmallBlock), unsure(doubleExponentPowBlockEntry));
2115
2116             LBasicBlock lastNext = m_out.appendTo(integerExponentIsSmallBlock, integerExponentPowBlock);
2117             LValue integerExponentBelowMax = m_out.belowOrEqual(integerExponent, m_out.constInt32(maxExponentForIntegerMathPow));
2118             m_out.branch(integerExponentBelowMax, usually(integerExponentPowBlock), rarely(doubleExponentPowBlockEntry));
2119
2120             m_out.appendTo(integerExponentPowBlock, doubleExponentPowBlockEntry);
2121             ValueFromBlock powDoubleIntResult = m_out.anchor(m_out.doublePowi(base, integerExponent));
2122             m_out.jump(continuation);
2123
2124             // If y is NaN, the result is NaN.
2125             m_out.appendTo(doubleExponentPowBlockEntry, nanExceptionBaseIsOne);
2126             LValue exponentIsNaN;
2127             if (provenType(m_node->child2()) & SpecDoubleNaN)
2128                 exponentIsNaN = m_out.doubleNotEqualOrUnordered(exponent, exponent);
2129             else
2130                 exponentIsNaN = m_out.booleanFalse;
2131             m_out.branch(exponentIsNaN, rarely(nanExceptionResultIsNaN), usually(nanExceptionBaseIsOne));
2132
2133             // If abs(x) is 1 and y is +infinity, the result is NaN.
2134             // If abs(x) is 1 and y is -infinity, the result is NaN.
2135
2136             //     Test if base == 1.
2137             m_out.appendTo(nanExceptionBaseIsOne, nanExceptionExponentIsInfinity);
2138             LValue absoluteBase = m_out.doubleAbs(base);
2139             LValue absoluteBaseIsOne = m_out.doubleEqual(absoluteBase, m_out.constDouble(1));
2140             m_out.branch(absoluteBaseIsOne, rarely(nanExceptionExponentIsInfinity), usually(testExponentIsOneHalf));
2141
2142             //     Test if abs(y) == Infinity.
2143             m_out.appendTo(nanExceptionExponentIsInfinity, testExponentIsOneHalf);
2144             LValue absoluteExponent = m_out.doubleAbs(exponent);
2145             LValue absoluteExponentIsInfinity = m_out.doubleEqual(absoluteExponent, m_out.constDouble(std::numeric_limits<double>::infinity()));
2146             m_out.branch(absoluteExponentIsInfinity, rarely(nanExceptionResultIsNaN), usually(testExponentIsOneHalf));
2147
2148             // If y == 0.5 or y == -0.5, handle it through SQRT.
2149             // We have be carefuly with -0 and -Infinity.
2150
2151             //     Test if y == 0.5
2152             m_out.appendTo(testExponentIsOneHalf, handleBaseZeroExponentIsOneHalf);
2153             LValue exponentIsOneHalf = m_out.doubleEqual(exponent, m_out.constDouble(0.5));
2154             m_out.branch(exponentIsOneHalf, rarely(handleBaseZeroExponentIsOneHalf), usually(testExponentIsNegativeOneHalf));
2155
2156             //     Handle x == -0.
2157             m_out.appendTo(handleBaseZeroExponentIsOneHalf, handleInfinityForExponentIsOneHalf);
2158             LValue baseIsZeroExponentIsOneHalf = m_out.doubleEqual(base, m_out.doubleZero);
2159             ValueFromBlock zeroResultExponentIsOneHalf = m_out.anchor(m_out.doubleZero);
2160             m_out.branch(baseIsZeroExponentIsOneHalf, rarely(continuation), usually(handleInfinityForExponentIsOneHalf));
2161
2162             //     Test if abs(x) == Infinity.
2163             m_out.appendTo(handleInfinityForExponentIsOneHalf, exponentIsOneHalfNormal);
2164             LValue absoluteBaseIsInfinityOneHalf = m_out.doubleEqual(absoluteBase, m_out.constDouble(std::numeric_limits<double>::infinity()));
2165             m_out.branch(absoluteBaseIsInfinityOneHalf, rarely(exponentIsOneHalfInfinity), usually(exponentIsOneHalfNormal));
2166
2167             //     The exponent is 0.5, the base is finite or NaN, we can use SQRT.
2168             m_out.appendTo(exponentIsOneHalfNormal, exponentIsOneHalfInfinity);
2169             ValueFromBlock sqrtResult = m_out.anchor(m_out.doubleSqrt(base));
2170             m_out.jump(continuation);
2171
2172             //     The exponent is 0.5, the base is infinite, the result is always infinite.
2173             m_out.appendTo(exponentIsOneHalfInfinity, testExponentIsNegativeOneHalf);
2174             ValueFromBlock sqrtInfinityResult = m_out.anchor(m_out.constDouble(std::numeric_limits<double>::infinity()));
2175             m_out.jump(continuation);
2176
2177             //     Test if y == -0.5
2178             m_out.appendTo(testExponentIsNegativeOneHalf, testBaseZeroExponentIsNegativeOneHalf);
2179             LValue exponentIsNegativeOneHalf = m_out.doubleEqual(exponent, m_out.constDouble(-0.5));
2180             m_out.branch(exponentIsNegativeOneHalf, rarely(testBaseZeroExponentIsNegativeOneHalf), usually(powBlock));
2181
2182             //     Handle x == -0.
2183             m_out.appendTo(testBaseZeroExponentIsNegativeOneHalf, handleBaseZeroExponentIsNegativeOneHalf);
2184             LValue baseIsZeroExponentIsNegativeOneHalf = m_out.doubleEqual(base, m_out.doubleZero);
2185             m_out.branch(baseIsZeroExponentIsNegativeOneHalf, rarely(handleBaseZeroExponentIsNegativeOneHalf), usually(handleInfinityForExponentIsNegativeOneHalf));
2186
2187             m_out.appendTo(handleBaseZeroExponentIsNegativeOneHalf, handleInfinityForExponentIsNegativeOneHalf);
2188             ValueFromBlock oneOverSqrtZeroResult = m_out.anchor(m_out.constDouble(std::numeric_limits<double>::infinity()));
2189             m_out.jump(continuation);
2190
2191             //     Test if abs(x) == Infinity.
2192             m_out.appendTo(handleInfinityForExponentIsNegativeOneHalf, exponentIsNegativeOneHalfNormal);
2193             LValue absoluteBaseIsInfinityNegativeOneHalf = m_out.doubleEqual(absoluteBase, m_out.constDouble(std::numeric_limits<double>::infinity()));
2194             m_out.branch(absoluteBaseIsInfinityNegativeOneHalf, rarely(exponentIsNegativeOneHalfInfinity), usually(exponentIsNegativeOneHalfNormal));
2195
2196             //     The exponent is -0.5, the base is finite or NaN, we can use 1/SQRT.
2197             m_out.appendTo(exponentIsNegativeOneHalfNormal, exponentIsNegativeOneHalfInfinity);
2198             LValue sqrtBase = m_out.doubleSqrt(base);
2199             ValueFromBlock oneOverSqrtResult = m_out.anchor(m_out.div(m_out.constDouble(1.), sqrtBase));
2200             m_out.jump(continuation);
2201
2202             //     The exponent is -0.5, the base is infinite, the result is always zero.
2203             m_out.appendTo(exponentIsNegativeOneHalfInfinity, powBlock);
2204             ValueFromBlock oneOverSqrtInfinityResult = m_out.anchor(m_out.doubleZero);
2205             m_out.jump(continuation);
2206
2207             m_out.appendTo(powBlock, nanExceptionResultIsNaN);
2208             ValueFromBlock powResult = m_out.anchor(m_out.doublePow(base, exponent));
2209             m_out.jump(continuation);
2210
2211             m_out.appendTo(nanExceptionResultIsNaN, continuation);
2212             ValueFromBlock pureNan = m_out.anchor(m_out.constDouble(PNaN));
2213             m_out.jump(continuation);
2214
2215             m_out.appendTo(continuation, lastNext);
2216             setDouble(m_out.phi(Double, powDoubleIntResult, zeroResultExponentIsOneHalf, sqrtResult, sqrtInfinityResult, oneOverSqrtZeroResult, oneOverSqrtResult, oneOverSqrtInfinityResult, powResult, pureNan));
2217         }
2218     }
2219
2220     void compileArithRandom()
2221     {
2222         JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
2223
2224         // Inlined WeakRandom::advance().
2225         // uint64_t x = m_low;
2226         void* lowAddress = reinterpret_cast<uint8_t*>(globalObject) + JSGlobalObject::weakRandomOffset() + WeakRandom::lowOffset();
2227         LValue low = m_out.load64(m_out.absolute(lowAddress));
2228         // uint64_t y = m_high;
2229         void* highAddress = reinterpret_cast<uint8_t*>(globalObject) + JSGlobalObject::weakRandomOffset() + WeakRandom::highOffset();
2230         LValue high = m_out.load64(m_out.absolute(highAddress));
2231         // m_low = y;
2232         m_out.store64(high, m_out.absolute(lowAddress));
2233
2234         // x ^= x << 23;
2235         LValue phase1 = m_out.bitXor(m_out.shl(low, m_out.constInt64(23)), low);
2236
2237         // x ^= x >> 17;
2238         LValue phase2 = m_out.bitXor(m_out.lShr(phase1, m_out.constInt64(17)), phase1);
2239
2240         // x ^= y ^ (y >> 26);
2241         LValue phase3 = m_out.bitXor(m_out.bitXor(high, m_out.lShr(high, m_out.constInt64(26))), phase2);
2242
2243         // m_high = x;
2244         m_out.store64(phase3, m_out.absolute(highAddress));
2245
2246         // return x + y;
2247         LValue random64 = m_out.add(phase3, high);
2248
2249         // Extract random 53bit. [0, 53] bit is safe integer number ranges in double representation.
2250         LValue random53 = m_out.bitAnd(random64, m_out.constInt64((1ULL << 53) - 1));
2251
2252         LValue double53Integer = m_out.intToDouble(random53);
2253
2254         // Convert `(53bit double integer value) / (1 << 53)` to `(53bit double integer value) * (1.0 / (1 << 53))`.
2255         // In latter case, `1.0 / (1 << 53)` will become a double value represented as (mantissa = 0 & exp = 970, it means 1e-(2**54)).
2256         static const double scale = 1.0 / (1ULL << 53);
2257
2258         // Multiplying 1e-(2**54) with the double integer does not change anything of the mantissa part of the double integer.
2259         // It just reduces the exp part of the given 53bit double integer.
2260         // (Except for 0.0. This is specially handled and in this case, exp just becomes 0.)
2261         // Now we get 53bit precision random double value in [0, 1).
2262         LValue result = m_out.doubleMul(double53Integer, m_out.constDouble(scale));
2263
2264         setDouble(result);
2265     }
2266
2267     void compileArithRound()
2268     {
2269         if (m_node->child1().useKind() == DoubleRepUse) {
2270             LValue result = nullptr;
2271             if (producesInteger(m_node->arithRoundingMode()) && !shouldCheckNegativeZero(m_node->arithRoundingMode())) {
2272                 LValue value = lowDouble(m_node->child1());
2273                 result = m_out.doubleFloor(m_out.doubleAdd(value, m_out.constDouble(0.5)));
2274             } else {
2275                 LBasicBlock realPartIsMoreThanHalf = m_out.newBlock();
2276                 LBasicBlock continuation = m_out.newBlock();
2277
2278                 LValue value = lowDouble(m_node->child1());
2279                 LValue integerValue = m_out.doubleCeil(value);
2280                 ValueFromBlock integerValueResult = m_out.anchor(integerValue);
2281
2282                 LValue realPart = m_out.doubleSub(integerValue, value);
2283
2284                 m_out.branch(m_out.doubleGreaterThanOrUnordered(realPart, m_out.constDouble(0.5)), unsure(realPartIsMoreThanHalf), unsure(continuation));
2285
2286                 LBasicBlock lastNext = m_out.appendTo(realPartIsMoreThanHalf, continuation);
2287                 LValue integerValueRoundedDown = m_out.doubleSub(integerValue, m_out.constDouble(1));
2288                 ValueFromBlock integerValueRoundedDownResult = m_out.anchor(integerValueRoundedDown);
2289                 m_out.jump(continuation);
2290                 m_out.appendTo(continuation, lastNext);
2291
2292                 result = m_out.phi(Double, integerValueResult, integerValueRoundedDownResult);
2293             }
2294
2295             if (producesInteger(m_node->arithRoundingMode())) {
2296                 LValue integerValue = convertDoubleToInt32(result, shouldCheckNegativeZero(m_node->arithRoundingMode()));
2297                 setInt32(integerValue);
2298             } else
2299                 setDouble(result);
2300             return;
2301         }
2302
2303         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
2304         LValue argument = lowJSValue(m_node->child1());
2305         setJSValue(vmCall(Int64, m_out.operation(operationArithRound), m_callFrame, argument));
2306     }
2307
2308     void compileArithFloor()
2309     {
2310         if (m_node->child1().useKind() == DoubleRepUse) {
2311             LValue value = lowDouble(m_node->child1());
2312             LValue integerValue = m_out.doubleFloor(value);
2313             if (producesInteger(m_node->arithRoundingMode()))
2314                 setInt32(convertDoubleToInt32(integerValue, shouldCheckNegativeZero(m_node->arithRoundingMode())));
2315             else
2316                 setDouble(integerValue);
2317             return;
2318         }
2319         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
2320         LValue argument = lowJSValue(m_node->child1());
2321         setJSValue(vmCall(Int64, m_out.operation(operationArithFloor), m_callFrame, argument));
2322     }
2323
2324     void compileArithCeil()
2325     {
2326         if (m_node->child1().useKind() == DoubleRepUse) {
2327             LValue value = lowDouble(m_node->child1());
2328             LValue integerValue = m_out.doubleCeil(value);
2329             if (producesInteger(m_node->arithRoundingMode()))
2330                 setInt32(convertDoubleToInt32(integerValue, shouldCheckNegativeZero(m_node->arithRoundingMode())));
2331             else
2332                 setDouble(integerValue);
2333             return;
2334         }
2335         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
2336         LValue argument = lowJSValue(m_node->child1());
2337         setJSValue(vmCall(Int64, m_out.operation(operationArithCeil), m_callFrame, argument));
2338     }
2339
2340     void compileArithTrunc()
2341     {
2342         if (m_node->child1().useKind() == DoubleRepUse) {
2343             LValue value = lowDouble(m_node->child1());
2344             LValue result = m_out.doubleTrunc(value);
2345             if (producesInteger(m_node->arithRoundingMode()))
2346                 setInt32(convertDoubleToInt32(result, shouldCheckNegativeZero(m_node->arithRoundingMode())));
2347             else
2348                 setDouble(result);
2349             return;
2350         }
2351         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
2352         LValue argument = lowJSValue(m_node->child1());
2353         setJSValue(vmCall(Int64, m_out.operation(operationArithTrunc), m_callFrame, argument));
2354     }
2355
2356     void compileArithSqrt()
2357     {
2358         if (m_node->child1().useKind() == DoubleRepUse) {
2359             setDouble(m_out.doubleSqrt(lowDouble(m_node->child1())));
2360             return;
2361         }
2362         LValue argument = lowJSValue(m_node->child1());
2363         LValue result = vmCall(Double, m_out.operation(operationArithSqrt), m_callFrame, argument);
2364         setDouble(result);
2365     }
2366
2367     void compileArithLog()
2368     {
2369         if (m_node->child1().useKind() == DoubleRepUse) {
2370             setDouble(m_out.doubleLog(lowDouble(m_node->child1())));
2371             return;
2372         }
2373         LValue argument = lowJSValue(m_node->child1());
2374         LValue result = vmCall(Double, m_out.operation(operationArithLog), m_callFrame, argument);
2375         setDouble(result);
2376     }
2377     
2378     void compileArithFRound()
2379     {
2380         if (m_node->child1().useKind() == DoubleRepUse) {
2381             setDouble(m_out.fround(lowDouble(m_node->child1())));
2382             return;
2383         }
2384         LValue argument = lowJSValue(m_node->child1());
2385         LValue result = vmCall(Double, m_out.operation(operationArithFRound), m_callFrame, argument);
2386         setDouble(result);
2387     }
2388     
2389     void compileArithNegate()
2390     {
2391         switch (m_node->child1().useKind()) {
2392         case Int32Use: {
2393             LValue value = lowInt32(m_node->child1());
2394             
2395             LValue result;
2396             if (!shouldCheckOverflow(m_node->arithMode()))
2397                 result = m_out.neg(value);
2398             else if (!shouldCheckNegativeZero(m_node->arithMode())) {
2399                 CheckValue* check = m_out.speculateSub(m_out.int32Zero, value);
2400                 blessSpeculation(check, Overflow, noValue(), nullptr, m_origin);
2401                 result = check;
2402             } else {
2403                 speculate(Overflow, noValue(), 0, m_out.testIsZero32(value, m_out.constInt32(0x7fffffff)));
2404                 result = m_out.neg(value);
2405             }
2406
2407             setInt32(result);
2408             break;
2409         }
2410             
2411         case Int52RepUse: {
2412             if (!abstractValue(m_node->child1()).couldBeType(SpecInt52Only)) {
2413                 Int52Kind kind;
2414                 LValue value = lowWhicheverInt52(m_node->child1(), kind);
2415                 LValue result = m_out.neg(value);
2416                 if (shouldCheckNegativeZero(m_node->arithMode()))
2417                     speculate(NegativeZero, noValue(), 0, m_out.isZero64(result));
2418                 setInt52(result, kind);
2419                 break;
2420             }
2421             
2422             LValue value = lowInt52(m_node->child1());
2423             CheckValue* result = m_out.speculateSub(m_out.int64Zero, value);
2424             blessSpeculation(result, Int52Overflow, noValue(), nullptr, m_origin);
2425             speculate(NegativeZero, noValue(), 0, m_out.isZero64(result));
2426             setInt52(result);
2427             break;
2428         }
2429             
2430         case DoubleRepUse: {
2431             setDouble(m_out.doubleNeg(lowDouble(m_node->child1())));
2432             break;
2433         }
2434             
2435         default:
2436             DFG_CRASH(m_graph, m_node, "Bad use kind");
2437             break;
2438         }
2439     }
2440     
2441     void compileBitAnd()
2442     {
2443         if (m_node->isBinaryUseKind(UntypedUse)) {
2444             emitBinaryBitOpSnippet<JITBitAndGenerator>(operationValueBitAnd);
2445             return;
2446         }
2447         setInt32(m_out.bitAnd(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2448     }
2449     
2450     void compileBitOr()
2451     {
2452         if (m_node->isBinaryUseKind(UntypedUse)) {
2453             emitBinaryBitOpSnippet<JITBitOrGenerator>(operationValueBitOr);
2454             return;
2455         }
2456         setInt32(m_out.bitOr(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2457     }
2458     
2459     void compileBitXor()
2460     {
2461         if (m_node->isBinaryUseKind(UntypedUse)) {
2462             emitBinaryBitOpSnippet<JITBitXorGenerator>(operationValueBitXor);
2463             return;
2464         }
2465         setInt32(m_out.bitXor(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2466     }
2467     
2468     void compileBitRShift()
2469     {
2470         if (m_node->isBinaryUseKind(UntypedUse)) {
2471             emitRightShiftSnippet(JITRightShiftGenerator::SignedShift);
2472             return;
2473         }
2474         setInt32(m_out.aShr(
2475             lowInt32(m_node->child1()),
2476             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2477     }
2478     
2479     void compileBitLShift()
2480     {
2481         if (m_node->isBinaryUseKind(UntypedUse)) {
2482             emitBinaryBitOpSnippet<JITLeftShiftGenerator>(operationValueBitLShift);
2483             return;
2484         }
2485         setInt32(m_out.shl(
2486             lowInt32(m_node->child1()),
2487             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2488     }
2489     
2490     void compileBitURShift()
2491     {
2492         if (m_node->isBinaryUseKind(UntypedUse)) {
2493             emitRightShiftSnippet(JITRightShiftGenerator::UnsignedShift);
2494             return;
2495         }
2496         setInt32(m_out.lShr(
2497             lowInt32(m_node->child1()),
2498             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2499     }
2500     
2501     void compileUInt32ToNumber()
2502     {
2503         LValue value = lowInt32(m_node->child1());
2504
2505         if (doesOverflow(m_node->arithMode())) {
2506             setStrictInt52(m_out.zeroExtPtr(value));
2507             return;
2508         }
2509
2510         speculate(Overflow, noValue(), 0, m_out.lessThan(value, m_out.int32Zero));
2511         setInt32(value);
2512     }
2513     
2514     void compileCheckStructure()
2515     {
2516         ExitKind exitKind;
2517         if (m_node->child1()->hasConstant())
2518             exitKind = BadConstantCache;
2519         else
2520             exitKind = BadCache;
2521
2522         switch (m_node->child1().useKind()) {
2523         case CellUse:
2524         case KnownCellUse: {
2525             LValue cell = lowCell(m_node->child1());
2526             
2527             checkStructure(
2528                 m_out.load32(cell, m_heaps.JSCell_structureID), jsValueValue(cell),
2529                 exitKind, m_node->structureSet(),
2530                 [&] (Structure* structure) {
2531                     return weakStructureID(structure);
2532                 });
2533             return;
2534         }
2535
2536         case CellOrOtherUse: {
2537             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
2538
2539             LBasicBlock cellCase = m_out.newBlock();
2540             LBasicBlock notCellCase = m_out.newBlock();
2541             LBasicBlock continuation = m_out.newBlock();
2542
2543             m_out.branch(
2544                 isCell(value, provenType(m_node->child1())), unsure(cellCase), unsure(notCellCase));
2545
2546             LBasicBlock lastNext = m_out.appendTo(cellCase, notCellCase);
2547             checkStructure(
2548                 m_out.load32(value, m_heaps.JSCell_structureID), jsValueValue(value),
2549                 exitKind, m_node->structureSet(),
2550                 [&] (Structure* structure) {
2551                     return weakStructureID(structure);
2552                 });
2553             m_out.jump(continuation);
2554
2555             m_out.appendTo(notCellCase, continuation);
2556             FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), SpecCell | SpecOther, isNotOther(value));
2557             m_out.jump(continuation);
2558
2559             m_out.appendTo(continuation, lastNext);
2560             return;
2561         }
2562
2563         default:
2564             DFG_CRASH(m_graph, m_node, "Bad use kind");
2565             return;
2566         }
2567     }
2568     
2569     void compileCheckCell()
2570     {
2571         LValue cell = lowCell(m_node->child1());
2572         
2573         speculate(
2574             BadCell, jsValueValue(cell), m_node->child1().node(),
2575             m_out.notEqual(cell, weakPointer(m_node->cellOperand()->cell())));
2576     }
2577     
2578     void compileCheckBadCell()
2579     {
2580         terminate(BadCell);
2581     }
2582
2583     void compileCheckNotEmpty()
2584     {
2585         speculate(TDZFailure, noValue(), nullptr, m_out.isZero64(lowJSValue(m_node->child1())));
2586     }
2587
2588     void compileCheckStringIdent()
2589     {
2590         UniquedStringImpl* uid = m_node->uidOperand();
2591         LValue string = lowStringIdent(m_node->child1());
2592         LValue stringImpl = m_out.loadPtr(string, m_heaps.JSString_value);
2593         speculate(BadIdent, noValue(), nullptr, m_out.notEqual(stringImpl, m_out.constIntPtr(uid)));
2594     }
2595
2596     void compileGetExecutable()
2597     {
2598         LValue cell = lowCell(m_node->child1());
2599         speculateFunction(m_node->child1(), cell);
2600         setJSValue(m_out.loadPtr(cell, m_heaps.JSFunction_executable));
2601     }
2602     
2603     void compileArrayifyToStructure()
2604     {
2605         LValue cell = lowCell(m_node->child1());
2606         LValue property = !!m_node->child2() ? lowInt32(m_node->child2()) : 0;
2607         
2608         LBasicBlock unexpectedStructure = m_out.newBlock();
2609         LBasicBlock continuation = m_out.newBlock();
2610         
2611         LValue structureID = m_out.load32(cell, m_heaps.JSCell_structureID);
2612         
2613         m_out.branch(
2614             m_out.notEqual(structureID, weakStructureID(m_node->structure())),
2615             rarely(unexpectedStructure), usually(continuation));
2616         
2617         LBasicBlock lastNext = m_out.appendTo(unexpectedStructure, continuation);
2618         
2619         if (property) {
2620             switch (m_node->arrayMode().type()) {
2621             case Array::Int32:
2622             case Array::Double:
2623             case Array::Contiguous:
2624                 speculate(
2625                     Uncountable, noValue(), 0,
2626                     m_out.aboveOrEqual(property, m_out.constInt32(MIN_SPARSE_ARRAY_INDEX)));
2627                 break;
2628             default:
2629                 break;
2630             }
2631         }
2632         
2633         switch (m_node->arrayMode().type()) {
2634         case Array::Int32:
2635             vmCall(Void, m_out.operation(operationEnsureInt32), m_callFrame, cell);
2636             break;
2637         case Array::Double:
2638             vmCall(Void, m_out.operation(operationEnsureDouble), m_callFrame, cell);
2639             break;
2640         case Array::Contiguous:
2641             vmCall(Void, m_out.operation(operationEnsureContiguous), m_callFrame, cell);
2642             break;
2643         case Array::ArrayStorage:
2644         case Array::SlowPutArrayStorage:
2645             vmCall(Void, m_out.operation(operationEnsureArrayStorage), m_callFrame, cell);
2646             break;
2647         default:
2648             DFG_CRASH(m_graph, m_node, "Bad array type");
2649             break;
2650         }
2651         
2652         structureID = m_out.load32(cell, m_heaps.JSCell_structureID);
2653         speculate(
2654             BadIndexingType, jsValueValue(cell), 0,
2655             m_out.notEqual(structureID, weakStructureID(m_node->structure())));
2656         m_out.jump(continuation);
2657         
2658         m_out.appendTo(continuation, lastNext);
2659     }
2660     
2661     void compilePutStructure()
2662     {
2663         m_ftlState.jitCode->common.notifyCompilingStructureTransition(m_graph.m_plan, codeBlock(), m_node);
2664
2665         Structure* oldStructure = m_node->transition()->previous;
2666         Structure* newStructure = m_node->transition()->next;
2667         ASSERT_UNUSED(oldStructure, oldStructure->indexingType() == newStructure->indexingType());
2668         ASSERT(oldStructure->typeInfo().inlineTypeFlags() == newStructure->typeInfo().inlineTypeFlags());
2669         ASSERT(oldStructure->typeInfo().type() == newStructure->typeInfo().type());
2670
2671         LValue cell = lowCell(m_node->child1()); 
2672         m_out.store32(
2673             weakStructureID(newStructure),
2674             cell, m_heaps.JSCell_structureID);
2675     }
2676     
2677     void compileGetById(AccessType type)
2678     {
2679         ASSERT(type == AccessType::Get || type == AccessType::GetPure);
2680         switch (m_node->child1().useKind()) {
2681         case CellUse: {
2682             setJSValue(getById(lowCell(m_node->child1()), type));
2683             return;
2684         }
2685             
2686         case UntypedUse: {
2687             // This is pretty weird, since we duplicate the slow path both here and in the
2688             // code generated by the IC. We should investigate making this less bad.
2689             // https://bugs.webkit.org/show_bug.cgi?id=127830
2690             LValue value = lowJSValue(m_node->child1());
2691             
2692             LBasicBlock cellCase = m_out.newBlock();
2693             LBasicBlock notCellCase = m_out.newBlock();
2694             LBasicBlock continuation = m_out.newBlock();
2695             
2696             m_out.branch(
2697                 isCell(value, provenType(m_node->child1())), unsure(cellCase), unsure(notCellCase));
2698             
2699             LBasicBlock lastNext = m_out.appendTo(cellCase, notCellCase);
2700             ValueFromBlock cellResult = m_out.anchor(getById(value, type));
2701             m_out.jump(continuation);
2702
2703             J_JITOperation_EJI getByIdFunction;
2704             if (type == AccessType::Get)
2705                 getByIdFunction = operationGetByIdGeneric;
2706             else
2707                 getByIdFunction = operationTryGetByIdGeneric;
2708
2709             m_out.appendTo(notCellCase, continuation);
2710             ValueFromBlock notCellResult = m_out.anchor(vmCall(
2711                 Int64, m_out.operation(getByIdFunction),
2712                 m_callFrame, value,
2713                 m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()])));
2714             m_out.jump(continuation);
2715             
2716             m_out.appendTo(continuation, lastNext);
2717             setJSValue(m_out.phi(Int64, cellResult, notCellResult));
2718             return;
2719         }
2720             
2721         default:
2722             DFG_CRASH(m_graph, m_node, "Bad use kind");
2723             return;
2724         }
2725     }
2726
2727     void compileGetByIdWithThis()
2728     {
2729         LValue base = lowJSValue(m_node->child1());
2730         LValue thisValue = lowJSValue(m_node->child2());
2731         LValue result = vmCall(Int64, m_out.operation(operationGetByIdWithThis), m_callFrame, base, thisValue, m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()]));
2732         setJSValue(result);
2733     }
2734
2735     void compileGetByValWithThis()
2736     {
2737         LValue base = lowJSValue(m_node->child1());
2738         LValue thisValue = lowJSValue(m_node->child2());
2739         LValue subscript = lowJSValue(m_node->child3());
2740
2741         LValue result = vmCall(Int64, m_out.operation(operationGetByValWithThis), m_callFrame, base, thisValue, subscript);
2742         setJSValue(result);
2743     }
2744
2745     void compilePutByIdWithThis()
2746     {
2747         LValue base = lowJSValue(m_node->child1());
2748         LValue thisValue = lowJSValue(m_node->child2());
2749         LValue value = lowJSValue(m_node->child3());
2750
2751         vmCall(Void, m_out.operation(m_graph.isStrictModeFor(m_node->origin.semantic) ? operationPutByIdWithThisStrict : operationPutByIdWithThis),
2752             m_callFrame, base, thisValue, value, m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()]));
2753     }
2754
2755     void compilePutByValWithThis()
2756     {
2757         LValue base = lowJSValue(m_graph.varArgChild(m_node, 0));
2758         LValue thisValue = lowJSValue(m_graph.varArgChild(m_node, 1));
2759         LValue property = lowJSValue(m_graph.varArgChild(m_node, 2));
2760         LValue value = lowJSValue(m_graph.varArgChild(m_node, 3));
2761
2762         vmCall(Void, m_out.operation(m_graph.isStrictModeFor(m_node->origin.semantic) ? operationPutByValWithThisStrict : operationPutByValWithThis),
2763             m_callFrame, base, thisValue, property, value);
2764     }
2765     
2766     void compilePutById()
2767     {
2768         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == CellUse);
2769
2770         Node* node = m_node;
2771         LValue base = lowCell(node->child1());
2772         LValue value = lowJSValue(node->child2());
2773         auto uid = m_graph.identifiers()[node->identifierNumber()];
2774
2775         B3::PatchpointValue* patchpoint = m_out.patchpoint(Void);
2776         patchpoint->appendSomeRegister(base);
2777         patchpoint->appendSomeRegister(value);
2778         patchpoint->append(m_tagMask, ValueRep::reg(GPRInfo::tagMaskRegister));
2779         patchpoint->append(m_tagTypeNumber, ValueRep::reg(GPRInfo::tagTypeNumberRegister));
2780         patchpoint->clobber(RegisterSet::macroScratchRegisters());
2781
2782         // FIXME: If this is a PutByIdFlush, we might want to late-clobber volatile registers.
2783         // https://bugs.webkit.org/show_bug.cgi?id=152848
2784
2785         RefPtr<PatchpointExceptionHandle> exceptionHandle =
2786             preparePatchpointForExceptions(patchpoint);
2787
2788         State* state = &m_ftlState;
2789         ECMAMode ecmaMode = m_graph.executableFor(node->origin.semantic)->ecmaMode();
2790         
2791         patchpoint->setGenerator(
2792             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
2793                 AllowMacroScratchRegisterUsage allowScratch(jit);
2794
2795                 CallSiteIndex callSiteIndex =
2796                     state->jitCode->common.addUniqueCallSiteIndex(node->origin.semantic);
2797
2798                 Box<CCallHelpers::JumpList> exceptions =
2799                     exceptionHandle->scheduleExitCreation(params)->jumps(jit);
2800
2801                 // JS setter call ICs generated by the PutById IC will need this.
2802                 exceptionHandle->scheduleExitCreationForUnwind(params, callSiteIndex);
2803
2804                 auto generator = Box<JITPutByIdGenerator>::create(
2805                     jit.codeBlock(), node->origin.semantic, callSiteIndex,
2806                     params.unavailableRegisters(), JSValueRegs(params[0].gpr()),
2807                     JSValueRegs(params[1].gpr()), GPRInfo::patchpointScratchRegister, ecmaMode,
2808                     node->op() == PutByIdDirect ? Direct : NotDirect);
2809
2810                 generator->generateFastPath(jit);
2811                 CCallHelpers::Label done = jit.label();
2812
2813                 params.addLatePath(
2814                     [=] (CCallHelpers& jit) {
2815                         AllowMacroScratchRegisterUsage allowScratch(jit);
2816
2817                         generator->slowPathJump().link(&jit);
2818                         CCallHelpers::Label slowPathBegin = jit.label();
2819                         CCallHelpers::Call slowPathCall = callOperation(
2820                             *state, params.unavailableRegisters(), jit, node->origin.semantic,
2821                             exceptions.get(), generator->slowPathFunction(), InvalidGPRReg,
2822                             CCallHelpers::TrustedImmPtr(generator->stubInfo()), params[1].gpr(),
2823                             params[0].gpr(), CCallHelpers::TrustedImmPtr(uid)).call();
2824                         jit.jump().linkTo(done, &jit);
2825
2826                         generator->reportSlowPathCall(slowPathBegin, slowPathCall);
2827
2828                         jit.addLinkTask(
2829                             [=] (LinkBuffer& linkBuffer) {
2830                                 generator->finalize(linkBuffer);
2831                             });
2832                     });
2833             });
2834     }
2835     
2836     void compileGetButterfly()
2837     {
2838         setStorage(m_out.loadPtr(lowCell(m_node->child1()), m_heaps.JSObject_butterfly));
2839     }
2840
2841     void compileConstantStoragePointer()
2842     {
2843         setStorage(m_out.constIntPtr(m_node->storagePointer()));
2844     }
2845     
2846     void compileGetIndexedPropertyStorage()
2847     {
2848         LValue cell = lowCell(m_node->child1());
2849         
2850         if (m_node->arrayMode().type() == Array::String) {
2851             LBasicBlock slowPath = m_out.newBlock();
2852             LBasicBlock continuation = m_out.newBlock();
2853
2854             LValue fastResultValue = m_out.loadPtr(cell, m_heaps.JSString_value);
2855             ValueFromBlock fastResult = m_out.anchor(fastResultValue);
2856             
2857             m_out.branch(
2858                 m_out.notNull(fastResultValue), usually(continuation), rarely(slowPath));
2859             
2860             LBasicBlock lastNext = m_out.appendTo(slowPath, continuation);
2861             
2862             ValueFromBlock slowResult = m_out.anchor(
2863                 vmCall(pointerType(), m_out.operation(operationResolveRope), m_callFrame, cell));
2864             
2865             m_out.jump(continuation);
2866             
2867             m_out.appendTo(continuation, lastNext);
2868             
2869             setStorage(m_out.loadPtr(m_out.phi(pointerType(), fastResult, slowResult), m_heaps.StringImpl_data));
2870             return;
2871         }
2872
2873         DFG_ASSERT(m_graph, m_node, isTypedView(m_node->arrayMode().typedArrayType()));
2874         setStorage(m_out.loadPtr(cell, m_heaps.JSArrayBufferView_vector));
2875     }
2876     
2877     void compileCheckArray()
2878     {
2879         Edge edge = m_node->child1();
2880         LValue cell = lowCell(edge);
2881         
2882         if (m_node->arrayMode().alreadyChecked(m_graph, m_node, abstractValue(edge)))
2883             return;
2884         
2885         speculate(
2886             BadIndexingType, jsValueValue(cell), 0,
2887             m_out.logicalNot(isArrayType(cell, m_node->arrayMode())));
2888     }
2889
2890     void compileGetTypedArrayByteOffset()
2891     {
2892         LValue basePtr = lowCell(m_node->child1());    
2893
2894         LBasicBlock simpleCase = m_out.newBlock();
2895         LBasicBlock wastefulCase = m_out.newBlock();
2896         LBasicBlock continuation = m_out.newBlock();
2897         
2898         LValue mode = m_out.load32(basePtr, m_heaps.JSArrayBufferView_mode);
2899         m_out.branch(
2900             m_out.notEqual(mode, m_out.constInt32(WastefulTypedArray)),
2901             unsure(simpleCase), unsure(wastefulCase));
2902
2903         LBasicBlock lastNext = m_out.appendTo(simpleCase, wastefulCase);
2904
2905         ValueFromBlock simpleOut = m_out.anchor(m_out.constIntPtr(0));
2906
2907         m_out.jump(continuation);
2908
2909         m_out.appendTo(wastefulCase, continuation);
2910
2911         LValue vectorPtr = m_out.loadPtr(basePtr, m_heaps.JSArrayBufferView_vector);
2912         LValue butterflyPtr = m_out.loadPtr(basePtr, m_heaps.JSObject_butterfly);
2913         LValue arrayBufferPtr = m_out.loadPtr(butterflyPtr, m_heaps.Butterfly_arrayBuffer);
2914         LValue dataPtr = m_out.loadPtr(arrayBufferPtr, m_heaps.ArrayBuffer_data);
2915
2916         ValueFromBlock wastefulOut = m_out.anchor(m_out.sub(vectorPtr, dataPtr));
2917
2918         m_out.jump(continuation);
2919         m_out.appendTo(continuation, lastNext);
2920
2921         setInt32(m_out.castToInt32(m_out.phi(pointerType(), simpleOut, wastefulOut)));
2922     }
2923     
2924     void compileGetArrayLength()
2925     {
2926         switch (m_node->arrayMode().type()) {
2927         case Array::Undecided:
2928         case Array::Int32:
2929         case Array::Double:
2930         case Array::Contiguous: {
2931             setInt32(m_out.load32NonNegative(lowStorage(m_node->child2()), m_heaps.Butterfly_publicLength));
2932             return;
2933         }
2934             
2935         case Array::String: {
2936             LValue string = lowCell(m_node->child1());
2937             setInt32(m_out.load32NonNegative(string, m_heaps.JSString_length));
2938             return;
2939         }
2940             
2941         case Array::DirectArguments: {
2942             LValue arguments = lowCell(m_node->child1());
2943             speculate(
2944                 ExoticObjectMode, noValue(), nullptr,
2945                 m_out.notNull(m_out.loadPtr(arguments, m_heaps.DirectArguments_overrides)));
2946             setInt32(m_out.load32NonNegative(arguments, m_heaps.DirectArguments_length));
2947             return;
2948         }
2949             
2950         case Array::ScopedArguments: {
2951             LValue arguments = lowCell(m_node->child1());
2952             speculate(
2953                 ExoticObjectMode, noValue(), nullptr,
2954                 m_out.notZero32(m_out.load8ZeroExt32(arguments, m_heaps.ScopedArguments_overrodeThings)));
2955             setInt32(m_out.load32NonNegative(arguments, m_heaps.ScopedArguments_totalLength));
2956             return;
2957         }
2958             
2959         default:
2960             if (m_node->arrayMode().isSomeTypedArrayView()) {
2961                 setInt32(
2962                     m_out.load32NonNegative(lowCell(m_node->child1()), m_heaps.JSArrayBufferView_length));
2963                 return;
2964             }
2965             
2966             DFG_CRASH(m_graph, m_node, "Bad array type");
2967             return;
2968         }
2969     }
2970     
2971     void compileCheckInBounds()
2972     {
2973         speculate(
2974             OutOfBounds, noValue(), 0,
2975             m_out.aboveOrEqual(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2976     }
2977     
2978     void compileGetByVal()
2979     {
2980         switch (m_node->arrayMode().type()) {
2981         case Array::Int32:
2982         case Array::Contiguous: {
2983             LValue index = lowInt32(m_node->child2());
2984             LValue storage = lowStorage(m_node->child3());
2985             
2986             IndexedAbstractHeap& heap = m_node->arrayMode().type() == Array::Int32 ?
2987                 m_heaps.indexedInt32Properties : m_heaps.indexedContiguousProperties;
2988             
2989             if (m_node->arrayMode().isInBounds()) {
2990                 LValue result = m_out.load64(baseIndex(heap, storage, index, m_node->child2()));
2991                 LValue isHole = m_out.isZero64(result);
2992                 if (m_node->arrayMode().isSaneChain()) {
2993                     DFG_ASSERT(
2994                         m_graph, m_node, m_node->arrayMode().type() == Array::Contiguous);
2995                     result = m_out.select(
2996                         isHole, m_out.constInt64(JSValue::encode(jsUndefined())), result);
2997                 } else
2998                     speculate(LoadFromHole, noValue(), 0, isHole);
2999                 setJSValue(result);
3000                 return;
3001             }
3002             
3003             LValue base = lowCell(m_node->child1());
3004             
3005             LBasicBlock fastCase = m_out.newBlock();
3006             LBasicBlock slowCase = m_out.newBlock();
3007             LBasicBlock continuation = m_out.newBlock();
3008             
3009             m_out.branch(
3010                 m_out.aboveOrEqual(
3011                     index, m_out.load32NonNegative(storage, m_heaps.Butterfly_publicLength)),
3012                 rarely(slowCase), usually(fastCase));
3013             
3014             LBasicBlock lastNext = m_out.appendTo(fastCase, slowCase);
3015
3016             LValue fastResultValue = m_out.load64(baseIndex(heap, storage, index, m_node->child2()));
3017             ValueFromBlock fastResult = m_out.anchor(fastResultValue);
3018             m_out.branch(
3019                 m_out.isZero64(fastResultValue), rarely(slowCase), usually(continuation));
3020             
3021             m_out.appendTo(slowCase, continuation);
3022             ValueFromBlock slowResult = m_out.anchor(
3023                 vmCall(Int64, m_out.operation(operationGetByValArrayInt), m_callFrame, base, index));
3024             m_out.jump(continuation);
3025             
3026             m_out.appendTo(continuation, lastNext);
3027             setJSValue(m_out.phi(Int64, fastResult, slowResult));
3028             return;
3029         }
3030             
3031         case Array::Double: {
3032             LValue index = lowInt32(m_node->child2());
3033             LValue storage = lowStorage(m_node->child3());
3034             
3035             IndexedAbstractHeap& heap = m_heaps.indexedDoubleProperties;
3036             
3037             if (m_node->arrayMode().isInBounds()) {
3038                 LValue result = m_out.loadDouble(
3039                     baseIndex(heap, storage, index, m_node->child2()));
3040                 
3041                 if (!m_node->arrayMode().isSaneChain()) {
3042                     speculate(
3043                         LoadFromHole, noValue(), 0,
3044                         m_out.doubleNotEqualOrUnordered(result, result));
3045                 }
3046                 setDouble(result);
3047                 break;
3048             }
3049             
3050             LValue base = lowCell(m_node->child1());
3051             
3052             LBasicBlock inBounds = m_out.newBlock();
3053             LBasicBlock boxPath = m_out.newBlock();
3054             LBasicBlock slowCase = m_out.newBlock();
3055             LBasicBlock continuation = m_out.newBlock();
3056             
3057             m_out.branch(
3058                 m_out.aboveOrEqual(
3059                     index, m_out.load32NonNegative(storage, m_heaps.Butterfly_publicLength)),
3060                 rarely(slowCase), usually(inBounds));
3061             
3062             LBasicBlock lastNext = m_out.appendTo(inBounds, boxPath);
3063             LValue doubleValue = m_out.loadDouble(
3064                 baseIndex(heap, storage, index, m_node->child2()));
3065             m_out.branch(
3066                 m_out.doubleNotEqualOrUnordered(doubleValue, doubleValue),
3067                 rarely(slowCase), usually(boxPath));
3068             
3069             m_out.appendTo(boxPath, slowCase);
3070             ValueFromBlock fastResult = m_out.anchor(boxDouble(doubleValue));
3071             m_out.jump(continuation);
3072             
3073             m_out.appendTo(slowCase, continuation);
3074             ValueFromBlock slowResult = m_out.anchor(
3075                 vmCall(Int64, m_out.operation(operationGetByValArrayInt), m_callFrame, base, index));
3076             m_out.jump(continuation);
3077             
3078             m_out.appendTo(continuation, lastNext);
3079             setJSValue(m_out.phi(Int64, fastResult, slowResult));
3080             return;
3081         }
3082
3083         case Array::Undecided: {
3084             LValue index = lowInt32(m_node->child2());
3085
3086             speculate(OutOfBounds, noValue(), m_node, m_out.lessThan(index, m_out.int32Zero));
3087             setJSValue(m_out.constInt64(ValueUndefined));
3088             return;
3089         }
3090             
3091         case Array::DirectArguments: {
3092             LValue base = lowCell(m_node->child1());
3093             LValue index = lowInt32(m_node->child2());
3094             
3095             speculate(
3096                 ExoticObjectMode, noValue(), nullptr,
3097                 m_out.notNull(m_out.loadPtr(base, m_heaps.DirectArguments_overrides)));
3098             speculate(
3099                 ExoticObjectMode, noValue(), nullptr,
3100                 m_out.aboveOrEqual(
3101                     index,
3102                     m_out.load32NonNegative(base, m_heaps.DirectArguments_length)));
3103
3104             TypedPointer address = m_out.baseIndex(
3105                 m_heaps.DirectArguments_storage, base, m_out.zeroExtPtr(index));
3106             setJSValue(m_out.load64(address));
3107             return;
3108         }
3109             
3110         case Array::ScopedArguments: {
3111             LValue base = lowCell(m_node->child1());
3112             LValue index = lowInt32(m_node->child2());
3113             
3114             speculate(
3115                 ExoticObjectMode, noValue(), nullptr,
3116                 m_out.aboveOrEqual(
3117                     index,
3118                     m_out.load32NonNegative(base, m_heaps.ScopedArguments_totalLength)));
3119             
3120             LValue table = m_out.loadPtr(base, m_heaps.ScopedArguments_table);
3121             LValue namedLength = m_out.load32(table, m_heaps.ScopedArgumentsTable_length);
3122             
3123             LBasicBlock namedCase = m_out.newBlock();
3124             LBasicBlock overflowCase = m_out.newBlock();
3125             LBasicBlock continuation = m_out.newBlock();
3126             
3127             m_out.branch(
3128                 m_out.aboveOrEqual(index, namedLength), unsure(overflowCase), unsure(namedCase));
3129             
3130             LBasicBlock lastNext = m_out.appendTo(namedCase, overflowCase);
3131             
3132             LValue scope = m_out.loadPtr(base, m_heaps.ScopedArguments_scope);
3133             LValue arguments = m_out.loadPtr(table, m_heaps.ScopedArgumentsTable_arguments);
3134             
3135             TypedPointer address = m_out.baseIndex(
3136                 m_heaps.scopedArgumentsTableArguments, arguments, m_out.zeroExtPtr(index));
3137             LValue scopeOffset = m_out.load32(address);
3138             
3139             speculate(
3140                 ExoticObjectMode, noValue(), nullptr,
3141                 m_out.equal(scopeOffset, m_out.constInt32(ScopeOffset::invalidOffset)));
3142             
3143             address = m_out.baseIndex(
3144                 m_heaps.JSEnvironmentRecord_variables, scope, m_out.zeroExtPtr(scopeOffset));
3145             ValueFromBlock namedResult = m_out.anchor(m_out.load64(address));
3146             m_out.jump(continuation);
3147             
3148             m_out.appendTo(overflowCase, continuation);
3149             
3150             address = m_out.baseIndex(
3151                 m_heaps.ScopedArguments_overflowStorage, base,
3152                 m_out.zeroExtPtr(m_out.sub(index, namedLength)));
3153             LValue overflowValue = m_out.load64(address);
3154             speculate(ExoticObjectMode, noValue(), nullptr, m_out.isZero64(overflowValue));
3155             ValueFromBlock overflowResult = m_out.anchor(overflowValue);
3156             m_out.jump(continuation);
3157             
3158             m_out.appendTo(continuation, lastNext);
3159             setJSValue(m_out.phi(Int64, namedResult, overflowResult));
3160             return;
3161         }
3162             
3163         case Array::Generic: {
3164             setJSValue(vmCall(
3165                 Int64, m_out.operation(operationGetByVal), m_callFrame,
3166                 lowJSValue(m_node->child1()), lowJSValue(m_node->child2())));
3167             return;
3168         }
3169             
3170         case Array::String: {
3171             compileStringCharAt();
3172             return;
3173         }
3174             
3175         default: {
3176             LValue index = lowInt32(m_node->child2());
3177             LValue storage = lowStorage(m_node->child3());
3178             
3179             TypedArrayType type = m_node->arrayMode().typedArrayType();
3180             
3181             if (isTypedView(type)) {
3182                 TypedPointer pointer = TypedPointer(
3183                     m_heaps.typedArrayProperties,
3184                     m_out.add(
3185                         storage,
3186                         m_out.shl(
3187                             m_out.zeroExtPtr(index),
3188                             m_out.constIntPtr(logElementSize(type)))));
3189                 
3190                 if (isInt(type)) {
3191                     LValue result;
3192                     switch (elementSize(type)) {
3193                     case 1:
3194                         result = isSigned(type) ? m_out.load8SignExt32(pointer) :  m_out.load8ZeroExt32(pointer);
3195                         break;
3196                     case 2:
3197                         result = isSigned(type) ? m_out.load16SignExt32(pointer) :  m_out.load16ZeroExt32(pointer);
3198                         break;
3199                     case 4:
3200                         result = m_out.load32(pointer);
3201                         break;
3202                     default:
3203                         DFG_CRASH(m_graph, m_node, "Bad element size");
3204                     }
3205                     
3206                     if (elementSize(type) < 4 || isSigned(type)) {
3207                         setInt32(result);
3208                         return;
3209                     }
3210
3211                     if (m_node->shouldSpeculateInt32()) {
3212                         speculate(
3213                             Overflow, noValue(), 0, m_out.lessThan(result, m_out.int32Zero));
3214                         setInt32(result);
3215                         return;
3216                     }
3217                     
3218                     if (m_node->shouldSpeculateAnyInt()) {
3219                         setStrictInt52(m_out.zeroExt(result, Int64));
3220                         return;
3221                     }
3222                     
3223                     setDouble(m_out.unsignedToDouble(result));
3224                     return;
3225                 }
3226             
3227                 ASSERT(isFloat(type));
3228                 
3229                 LValue result;
3230                 switch (type) {
3231                 case TypeFloat32:
3232                     result = m_out.floatToDouble(m_out.loadFloat(pointer));
3233                     break;
3234                 case TypeFloat64:
3235                     result = m_out.loadDouble(pointer);
3236                     break;
3237                 default:
3238                     DFG_CRASH(m_graph, m_node, "Bad typed array type");
3239                 }
3240                 
3241                 setDouble(result);
3242                 return;
3243             }
3244             
3245             DFG_CRASH(m_graph, m_node, "Bad array type");
3246             return;
3247         } }
3248     }
3249     
3250     void compileGetMyArgumentByVal()
3251     {
3252         InlineCallFrame* inlineCallFrame = m_node->child1()->origin.semantic.inlineCallFrame;
3253         
3254         LValue index = lowInt32(m_node->child2());
3255         
3256         LValue limit;
3257         if (inlineCallFrame && !inlineCallFrame->isVarargs())
3258             limit = m_out.constInt32(inlineCallFrame->arguments.size() - 1);
3259         else {
3260             VirtualRegister argumentCountRegister;
3261             if (!inlineCallFrame)
3262                 argumentCountRegister = VirtualRegister(CallFrameSlot::argumentCount);
3263             else
3264                 argumentCountRegister = inlineCallFrame->argumentCountRegister;
3265             limit = m_out.sub(m_out.load32(payloadFor(argumentCountRegister)), m_out.int32One);
3266         }
3267         
3268         LValue isOutOfBounds = m_out.aboveOrEqual(index, limit);
3269         LBasicBlock continuation = nullptr;
3270         LBasicBlock lastNext = nullptr;
3271         ValueFromBlock slowResult;
3272         if (m_node->op() == GetMyArgumentByValOutOfBounds) {
3273             LBasicBlock normalCase = m_out.newBlock();
3274             continuation = m_out.newBlock();
3275             
3276             slowResult = m_out.anchor(m_out.constInt64(JSValue::encode(jsUndefined())));
3277             m_out.branch(isOutOfBounds, unsure(continuation), unsure(normalCase));
3278             
3279             lastNext = m_out.appendTo(normalCase, continuation);
3280         } else
3281             speculate(ExoticObjectMode, noValue(), 0, isOutOfBounds);
3282         
3283         TypedPointer base;
3284         if (inlineCallFrame) {
3285             if (inlineCallFrame->arguments.size() > 1)
3286                 base = addressFor(inlineCallFrame->arguments[1].virtualRegister());
3287         } else
3288             base = addressFor(virtualRegisterForArgument(1));
3289         
3290         LValue result;
3291         if (base) {
3292             LValue pointer = m_out.baseIndex(
3293                 base.value(), m_out.zeroExt(index, pointerType()), ScaleEight);
3294             result = m_out.load64(TypedPointer(m_heaps.variables.atAnyIndex(), pointer));
3295         } else
3296             result = m_out.constInt64(JSValue::encode(jsUndefined()));
3297         
3298         if (m_node->op() == GetMyArgumentByValOutOfBounds) {
3299             ValueFromBlock normalResult = m_out.anchor(result);
3300             m_out.jump(continuation);
3301             
3302             m_out.appendTo(continuation, lastNext);
3303             result = m_out.phi(Int64, slowResult, normalResult);
3304         }
3305         
3306         setJSValue(result);
3307     }
3308     
3309     void compilePutByVal()
3310     {
3311         Edge child1 = m_graph.varArgChild(m_node, 0);
3312         Edge child2 = m_graph.varArgChild(m_node, 1);
3313         Edge child3 = m_graph.varArgChild(m_node, 2);
3314         Edge child4 = m_graph.varArgChild(m_node, 3);
3315         Edge child5 = m_graph.varArgChild(m_node, 4);
3316         
3317         switch (m_node->arrayMode().type()) {
3318         case Array::Generic: {
3319             V_JITOperation_EJJJ operation;
3320             if (m_node->op() == PutByValDirect) {
3321                 if (m_graph.isStrictModeFor(m_node->origin.semantic))
3322                     operation = operationPutByValDirectStrict;
3323                 else
3324                     operation = operationPutByValDirectNonStrict;
3325             } else {
3326                 if (m_graph.isStrictModeFor(m_node->origin.semantic))
3327                     operation = operationPutByValStrict;
3328                 else
3329                     operation = operationPutByValNonStrict;
3330             }
3331                 
3332             vmCall(
3333                 Void, m_out.operation(operation), m_callFrame,
3334                 lowJSValue(child1), lowJSValue(child2), lowJSValue(child3));
3335             return;
3336         }
3337             
3338         default:
3339             break;
3340         }
3341
3342         LValue base = lowCell(child1);
3343         LValue index = lowInt32(child2);
3344         LValue storage = lowStorage(child4);
3345         
3346         switch (m_node->arrayMode().type()) {
3347         case Array::Int32:
3348         case Array::Double:
3349         case Array::Contiguous: {
3350             LBasicBlock continuation = m_out.newBlock();
3351             LBasicBlock outerLastNext = m_out.appendTo(m_out.m_block, continuation);
3352             
3353             switch (m_node->arrayMode().type()) {
3354             case Array::Int32:
3355             case Array::Contiguous: {
3356                 LValue value = lowJSValue(child3, ManualOperandSpeculation);
3357                 
3358                 if (m_node->arrayMode().type() == Array::Int32)
3359                     FTL_TYPE_CHECK(jsValueValue(value), child3, SpecInt32Only, isNotInt32(value));
3360                 
3361                 TypedPointer elementPointer = m_out.baseIndex(
3362                     m_node->arrayMode().type() == Array::Int32 ?
3363                     m_heaps.indexedInt32Properties : m_heaps.indexedContiguousProperties,
3364                     storage, m_out.zeroExtPtr(index), provenValue(child2));
3365                 
3366                 if (m_node->op() == PutByValAlias) {
3367                     m_out.store64(value, elementPointer);
3368                     break;
3369                 }
3370                 
3371                 contiguousPutByValOutOfBounds(
3372                     codeBlock()->isStrictMode()
3373                     ? operationPutByValBeyondArrayBoundsStrict
3374                     : operationPutByValBeyondArrayBoundsNonStrict,
3375                     base, storage, index, value, continuation);
3376                 
3377                 m_out.store64(value, elementPointer);
3378                 break;
3379             }
3380                 
3381             case Array::Double: {
3382                 LValue value = lowDouble(child3);
3383                 
3384                 FTL_TYPE_CHECK(
3385                     doubleValue(value), child3, SpecDoubleReal,
3386                     m_out.doubleNotEqualOrUnordered(value, value));
3387                 
3388                 TypedPointer elementPointer = m_out.baseIndex(
3389                     m_heaps.indexedDoubleProperties, storage, m_out.zeroExtPtr(index),
3390                     provenValue(child2));
3391                 
3392                 if (m_node->op() == PutByValAlias) {
3393                     m_out.storeDouble(value, elementPointer);
3394                     break;
3395                 }
3396                 
3397                 contiguousPutByValOutOfBounds(
3398                     codeBlock()->isStrictMode()
3399                     ? operationPutDoubleByValBeyondArrayBoundsStrict
3400                     : operationPutDoubleByValBeyondArrayBoundsNonStrict,
3401                     base, storage, index, value, continuation);
3402                 
3403                 m_out.storeDouble(value, elementPointer);
3404                 break;
3405             }
3406                 
3407             default:
3408                 DFG_CRASH(m_graph, m_node, "Bad array type");
3409             }
3410
3411             m_out.jump(continuation);
3412             m_out.appendTo(continuation, outerLastNext);
3413             return;
3414         }
3415             
3416         default:
3417             TypedArrayType type = m_node->arrayMode().typedArrayType();
3418             
3419             if (isTypedView(type)) {
3420                 TypedPointer pointer = TypedPointer(
3421                     m_heaps.typedArrayProperties,
3422                     m_out.add(
3423                         storage,
3424                         m_out.shl(
3425                             m_out.zeroExt(index, pointerType()),
3426                             m_out.constIntPtr(logElementSize(type)))));
3427                 
3428                 Output::StoreType storeType;
3429                 LValue valueToStore;
3430                 
3431                 if (isInt(type)) {
3432                     LValue intValue;
3433                     switch (child3.useKind()) {
3434                     case Int52RepUse:
3435                     case Int32Use: {
3436                         if (child3.useKind() == Int32Use)
3437                             intValue = lowInt32(child3);
3438                         else
3439                             intValue = m_out.castToInt32(lowStrictInt52(child3));
3440
3441                         if (isClamped(type)) {
3442                             ASSERT(elementSize(type) == 1);
3443                             
3444                             LBasicBlock atLeastZero = m_out.newBlock();
3445                             LBasicBlock continuation = m_out.newBlock();
3446                             
3447                             Vector<ValueFromBlock, 2> intValues;
3448                             intValues.append(m_out.anchor(m_out.int32Zero));
3449                             m_out.branch(
3450                                 m_out.lessThan(intValue, m_out.int32Zero),
3451                                 unsure(continuation), unsure(atLeastZero));
3452                             
3453                             LBasicBlock lastNext = m_out.appendTo(atLeastZero, continuation);
3454                             
3455                             intValues.append(m_out.anchor(m_out.select(
3456                                 m_out.greaterThan(intValue, m_out.constInt32(255)),
3457                                 m_out.constInt32(255),
3458                                 intValue)));
3459                             m_out.jump(continuation);
3460                             
3461                             m_out.appendTo(continuation, lastNext);
3462                             intValue = m_out.phi(Int32, intValues);
3463                         }
3464                         break;
3465                     }
3466                         
3467                     case DoubleRepUse: {
3468                         LValue doubleValue = lowDouble(child3);
3469                         
3470                         if (isClamped(type)) {
3471                             ASSERT(elementSize(type) == 1);
3472                             
3473                             LBasicBlock atLeastZero = m_out.newBlock();
3474                             LBasicBlock withinRange = m_out.newBlock();
3475                             LBasicBlock continuation = m_out.newBlock();
3476                             
3477                             Vector<ValueFromBlock, 3> intValues;
3478                             intValues.append(m_out.anchor(m_out.int32Zero));
3479                             m_out.branch(
3480                                 m_out.doubleLessThanOrUnordered(doubleValue, m_out.doubleZero),
3481                                 unsure(continuation), unsure(atLeastZero));
3482                             
3483                             LBasicBlock lastNext = m_out.appendTo(atLeastZero, withinRange);
3484                             intValues.append(m_out.anchor(m_out.constInt32(255)));
3485                             m_out.branch(
3486                                 m_out.doubleGreaterThan(doubleValue, m_out.constDouble(255)),
3487                                 unsure(continuation), unsure(withinRange));
3488                             
3489                             m_out.appendTo(withinRange, continuation);
3490                             intValues.append(m_out.anchor(m_out.doubleToInt(doubleValue)));
3491                             m_out.jump(continuation);
3492                             
3493                             m_out.appendTo(continuation, lastNext);
3494                             intValue = m_out.phi(Int32, intValues);
3495                         } else
3496                             intValue = doubleToInt32(doubleValue);
3497                         break;
3498                     }
3499                         
3500                     default:
3501                         DFG_CRASH(m_graph, m_node, "Bad use kind");
3502                     }
3503
3504                     valueToStore = intValue;
3505                     switch (elementSize(type)) {
3506                     case 1:
3507                         storeType = Output::Store32As8;
3508                         break;
3509                     case 2:
3510                         storeType = Output::Store32As16;
3511                         break;
3512                     case 4:
3513                         storeType = Output::Store32;
3514                         break;
3515                     default:
3516                         DFG_CRASH(m_graph, m_node, "Bad element size");
3517                     }
3518                 } else /* !isInt(type) */ {
3519                     LValue value = lowDouble(child3);
3520                     switch (type) {
3521                     case TypeFloat32:
3522                         valueToStore = m_out.doubleToFloat(value);
3523                         storeType = Output::StoreFloat;
3524                         break;
3525                     case TypeFloat64:
3526                         valueToStore = value;
3527                         storeType = Output::StoreDouble;
3528                         break;
3529                     default:
3530                         DFG_CRASH(m_graph, m_node, "Bad typed array type");
3531                     }
3532                 }
3533
3534                 if (m_node->arrayMode().isInBounds() || m_node->op() == PutByValAlias)
3535                     m_out.store(valueToStore, pointer, storeType);
3536                 else {
3537                     LBasicBlock isInBounds = m_out.newBlock();
3538                     LBasicBlock isOutOfBounds = m_out.newBlock();
3539                     LBasicBlock continuation = m_out.newBlock();
3540                     
3541                     m_out.branch(
3542                         m_out.aboveOrEqual(index, lowInt32(child5)),
3543                         unsure(isOutOfBounds), unsure(isInBounds));
3544                     
3545                     LBasicBlock lastNext = m_out.appendTo(isInBounds, isOutOfBounds);
3546                     m_out.store(valueToStore, pointer, storeType);
3547                     m_out.jump(continuation);
3548
3549                     m_out.appendTo(isOutOfBounds, continuation);
3550                     speculateTypedArrayIsNotNeutered(base);
3551                     m_out.jump(continuation);
3552                     
3553                     m_out.appendTo(continuation, lastNext);
3554                 }
3555                 
3556                 return;
3557             }
3558
3559             DFG_CRASH(m_graph, m_node, "Bad array type");
3560             break;
3561         }
3562     }
3563
3564     void compilePutAccessorById()
3565     {
3566         LValue