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