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