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