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