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