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