Unreviewed, rolling out r156474.
[WebKit-https.git] / Source / JavaScriptCore / ftl / FTLLowerDFGToLLVM.cpp
1 /*
2  * Copyright (C) 2013 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 "FTLLowerDFGToLLVM.h"
28
29 #if ENABLE(FTL_JIT)
30
31 #include "CodeBlockWithJITType.h"
32 #include "DFGAbstractInterpreterInlines.h"
33 #include "DFGInPlaceAbstractState.h"
34 #include "FTLAbstractHeapRepository.h"
35 #include "FTLExitThunkGenerator.h"
36 #include "FTLForOSREntryJITCode.h"
37 #include "FTLFormattedValue.h"
38 #include "FTLLoweredNodeValue.h"
39 #include "FTLOutput.h"
40 #include "FTLThunks.h"
41 #include "FTLValueSource.h"
42 #include "LinkBuffer.h"
43 #include "OperandsInlines.h"
44 #include "Operations.h"
45 #include <wtf/ProcessID.h>
46
47 namespace JSC { namespace FTL {
48
49 using namespace DFG;
50
51 static int compileCounter;
52
53 // Using this instead of typeCheck() helps to reduce the load on LLVM, by creating
54 // significantly less dead code.
55 #define FTL_TYPE_CHECK(lowValue, highValue, typesPassedThrough, failCondition) do { \
56         FormattedValue _ftc_lowValue = (lowValue);                      \
57         Edge _ftc_highValue = (highValue);                              \
58         SpeculatedType _ftc_typesPassedThrough = (typesPassedThrough);  \
59         if (!m_interpreter.needsTypeCheck(_ftc_highValue, _ftc_typesPassedThrough)) \
60             break;                                                      \
61         typeCheck(_ftc_lowValue, _ftc_highValue, _ftc_typesPassedThrough, (failCondition)); \
62     } while (false)
63
64 class LowerDFGToLLVM {
65 public:
66     LowerDFGToLLVM(State& state)
67         : m_graph(state.graph)
68         , m_ftlState(state)
69         , m_heaps(state.context)
70         , m_out(state.context)
71         , m_valueSources(OperandsLike, state.graph.block(0)->variablesAtHead)
72         , m_lastSetOperand(std::numeric_limits<int>::max())
73         , m_exitThunkGenerator(state)
74         , m_state(state.graph)
75         , m_interpreter(state.graph, m_state)
76     {
77     }
78     
79     void lower()
80     {
81         CString name;
82         if (verboseCompilationEnabled()) {
83             name = toCString(
84                 "jsBody_", atomicIncrement(&compileCounter), "_", codeBlock()->inferredName(),
85                 "_", codeBlock()->hash());
86         } else
87             name = "jsBody";
88         
89         m_graph.m_dominators.computeIfNecessary(m_graph);
90         
91         m_ftlState.module =
92             LLVMModuleCreateWithNameInContext(name.data(), m_ftlState.context);
93         
94         m_ftlState.function = addFunction(
95             m_ftlState.module, name.data(), functionType(m_out.int64, m_out.intPtr));
96         setFunctionCallingConv(m_ftlState.function, LLVMCCallConv);
97         
98         m_out.initialize(m_ftlState.module, m_ftlState.function, m_heaps);
99         
100         m_prologue = appendBasicBlock(m_ftlState.context, m_ftlState.function);
101         m_out.appendTo(m_prologue);
102         createPhiVariables();
103         
104         m_initialization = appendBasicBlock(m_ftlState.context, m_ftlState.function);
105
106         m_callFrame = m_out.param(0);
107         m_tagTypeNumber = m_out.constInt64(TagTypeNumber);
108         m_tagMask = m_out.constInt64(TagMask);
109         
110         for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
111             m_highBlock = m_graph.block(blockIndex);
112             if (!m_highBlock)
113                 continue;
114             m_blocks.add(m_highBlock, FTL_NEW_BLOCK(m_out, ("Block ", *m_highBlock)));
115         }
116         
117         Vector<BasicBlock*> depthFirst;
118         m_graph.getBlocksInDepthFirstOrder(depthFirst);
119         for (unsigned i = 0; i < depthFirst.size(); ++i)
120             compileBlock(depthFirst[i]);
121         
122         // And now complete the initialization block.
123         linkOSRExitsAndCompleteInitializationBlocks();
124
125         if (Options::dumpLLVMIR())
126             dumpModule(m_ftlState.module);
127         
128         if (verboseCompilationEnabled())
129             m_ftlState.dumpState("after lowering");
130         if (validationEnabled())
131             verifyModule(m_ftlState.module);
132     }
133
134 private:
135     
136     void createPhiVariables()
137     {
138         for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
139             BasicBlock* block = m_graph.block(blockIndex);
140             if (!block)
141                 continue;
142             for (unsigned nodeIndex = block->size(); nodeIndex--;) {
143                 Node* node = block->at(nodeIndex);
144                 if (node->op() != Phi)
145                     continue;
146                 LType type;
147                 switch (node->flags() & NodeResultMask) {
148                 case NodeResultNumber:
149                     type = m_out.doubleType;
150                     break;
151                 case NodeResultInt32:
152                     type = m_out.int32;
153                     break;
154                 case NodeResultInt52:
155                     type = m_out.int64;
156                     break;
157                 case NodeResultBoolean:
158                     type = m_out.boolean;
159                     break;
160                 case NodeResultJS:
161                     type = m_out.int64;
162                     break;
163                 default:
164                     RELEASE_ASSERT_NOT_REACHED();
165                     break;
166                 }
167                 m_phis.add(node, buildAlloca(m_out.m_builder, type));
168             }
169         }
170     }
171     
172     void compileBlock(BasicBlock* block)
173     {
174         if (!block)
175             return;
176         
177         if (verboseCompilationEnabled())
178             dataLog("Compiling block ", *block, "\n");
179         
180         m_highBlock = block;
181         
182         LBasicBlock lowBlock = m_blocks.get(m_highBlock);
183         
184         m_nextHighBlock = 0;
185         for (BlockIndex nextBlockIndex = m_highBlock->index + 1; nextBlockIndex < m_graph.numBlocks(); ++nextBlockIndex) {
186             m_nextHighBlock = m_graph.block(nextBlockIndex);
187             if (m_nextHighBlock)
188                 break;
189         }
190         m_nextLowBlock = m_nextHighBlock ? m_blocks.get(m_nextHighBlock) : 0;
191         
192         // All of this effort to find the next block gives us the ability to keep the
193         // generated IR in roughly program order. This ought not affect the performance
194         // of the generated code (since we expect LLVM to reorder things) but it will
195         // make IR dumps easier to read.
196         m_out.appendTo(lowBlock, m_nextLowBlock);
197         
198         if (Options::ftlCrashes())
199             m_out.crashNonTerminal();
200         
201         if (!m_highBlock->cfaHasVisited) {
202             m_out.crash();
203             return;
204         }
205         
206         initializeOSRExitStateForBlock();
207         
208         m_live = block->ssa->liveAtHead;
209         
210         m_state.reset();
211         m_state.beginBasicBlock(m_highBlock);
212         
213         for (m_nodeIndex = 0; m_nodeIndex < m_highBlock->size(); ++m_nodeIndex) {
214             if (!compileNode(m_nodeIndex))
215                 break;
216         }
217     }
218     
219     bool compileNode(unsigned nodeIndex)
220     {
221         if (!m_state.isValid()) {
222             m_out.unreachable();
223             return false;
224         }
225         
226         m_node = m_highBlock->at(nodeIndex);
227         m_codeOriginForExitProfile = m_node->codeOrigin;
228         m_codeOriginForExitTarget = m_node->codeOriginForExitTarget;
229         
230         if (verboseCompilationEnabled())
231             dataLog("Lowering ", m_node, "\n");
232         
233         bool shouldExecuteEffects = m_interpreter.startExecuting(m_node);
234         
235         m_direction = (m_node->flags() & NodeExitsForward) ? ForwardSpeculation : BackwardSpeculation;
236         
237         switch (m_node->op()) {
238         case Upsilon:
239             compileUpsilon();
240             break;
241         case Phi:
242             compilePhi();
243             break;
244         case JSConstant:
245             break;
246         case WeakJSConstant:
247             compileWeakJSConstant();
248             break;
249         case GetArgument:
250             compileGetArgument();
251             break;
252         case ExtractOSREntryLocal:
253             compileExtractOSREntryLocal();
254             break;
255         case GetLocal:
256             compileGetLocal();
257             break;
258         case SetLocal:
259             compileSetLocal();
260             break;
261         case MovHint:
262             compileMovHint();
263             break;
264         case ZombieHint:
265             compileZombieHint();
266             break;
267         case MovHintAndCheck:
268             compileMovHintAndCheck();
269             break;
270         case Phantom:
271             compilePhantom();
272             break;
273         case Flush:
274         case PhantomLocal:
275         case SetArgument:
276         case LoopHint:
277             break;
278         case ArithAdd:
279         case ValueAdd:
280             compileAdd();
281             break;
282         case ArithSub:
283             compileArithSub();
284             break;
285         case ArithMul:
286             compileArithMul();
287             break;
288         case ArithDiv:
289             compileArithDiv();
290             break;
291         case ArithMod:
292             compileArithMod();
293             break;
294         case ArithMin:
295         case ArithMax:
296             compileArithMinOrMax();
297             break;
298         case ArithAbs:
299             compileArithAbs();
300             break;
301         case ArithNegate:
302             compileArithNegate();
303             break;
304         case BitAnd:
305             compileBitAnd();
306             break;
307         case BitOr:
308             compileBitOr();
309             break;
310         case BitXor:
311             compileBitXor();
312             break;
313         case BitRShift:
314             compileBitRShift();
315             break;
316         case BitLShift:
317             compileBitLShift();
318             break;
319         case BitURShift:
320             compileBitURShift();
321             break;
322         case UInt32ToNumber:
323             compileUInt32ToNumber();
324             break;
325         case Int32ToDouble:
326             compileInt32ToDouble();
327             break;
328         case CheckStructure:
329             compileCheckStructure();
330             break;
331         case StructureTransitionWatchpoint:
332             compileStructureTransitionWatchpoint();
333             break;
334         case ArrayifyToStructure:
335             compileArrayifyToStructure();
336             break;
337         case PutStructure:
338             compilePutStructure();
339             break;
340         case PhantomPutStructure:
341             compilePhantomPutStructure();
342             break;
343         case GetButterfly:
344             compileGetButterfly();
345             break;
346         case GetIndexedPropertyStorage:
347             compileGetIndexedPropertyStorage();
348             break;
349         case CheckArray:
350             compileCheckArray();
351             break;
352         case GetArrayLength:
353             compileGetArrayLength();
354             break;
355         case GetByVal:
356             compileGetByVal();
357             break;
358         case PutByVal:
359         case PutByValAlias:
360             compilePutByVal();
361             break;
362         case GetByOffset:
363             compileGetByOffset();
364             break;
365         case PutByOffset:
366             compilePutByOffset();
367             break;
368         case GetGlobalVar:
369             compileGetGlobalVar();
370             break;
371         case PutGlobalVar:
372             compilePutGlobalVar();
373             break;
374         case GlobalVarWatchpoint:
375             compileGlobalVarWatchpoint();
376             break;
377         case GetMyScope:
378             compileGetMyScope();
379             break;
380         case SkipScope:
381             compileSkipScope();
382             break;
383         case GetClosureRegisters:
384             compileGetClosureRegisters();
385             break;
386         case GetClosureVar:
387             compileGetClosureVar();
388             break;
389         case PutClosureVar:
390             compilePutClosureVar();
391             break;
392         case CompareEq:
393             compileCompareEq();
394             break;
395         case CompareEqConstant:
396             compileCompareEqConstant();
397             break;
398         case CompareStrictEq:
399             compileCompareStrictEq();
400             break;
401         case CompareStrictEqConstant:
402             compileCompareStrictEqConstant();
403             break;
404         case CompareLess:
405             compileCompareLess();
406             break;
407         case CompareLessEq:
408             compileCompareLessEq();
409             break;
410         case CompareGreater:
411             compileCompareGreater();
412             break;
413         case CompareGreaterEq:
414             compileCompareGreaterEq();
415             break;
416         case LogicalNot:
417             compileLogicalNot();
418             break;
419         case Call:
420         case Construct:
421             compileCallOrConstruct();
422             break;
423         case Jump:
424             compileJump();
425             break;
426         case Branch:
427             compileBranch();
428             break;
429         case Switch:
430             compileSwitch();
431             break;
432         case Return:
433             compileReturn();
434             break;
435         case ForceOSRExit:
436             compileForceOSRExit();
437             break;
438         default:
439             RELEASE_ASSERT_NOT_REACHED();
440             break;
441         }
442         
443         if (m_node->shouldGenerate())
444             DFG_NODE_DO_TO_CHILDREN(m_graph, m_node, use);
445         
446         if (m_node->adjustedRefCount())
447             m_live.add(m_node);
448         
449         if (shouldExecuteEffects)
450             m_interpreter.executeEffects(nodeIndex);
451         
452         return true;
453     }
454     
455     void compileUpsilon()
456     {
457         LValue destination = m_phis.get(m_node->phi());
458         
459         switch (m_node->child1().useKind()) {
460         case NumberUse:
461             m_out.set(lowDouble(m_node->child1()), destination);
462             break;
463         case Int32Use:
464             m_out.set(lowInt32(m_node->child1()), destination);
465             break;
466         case MachineIntUse:
467             m_out.set(lowInt52(m_node->child1()), destination);
468             break;
469         case BooleanUse:
470             m_out.set(lowBoolean(m_node->child1()), destination);
471             break;
472         case CellUse:
473             m_out.set(lowCell(m_node->child1()), destination);
474             break;
475         case UntypedUse:
476             m_out.set(lowJSValue(m_node->child1()), destination);
477             break;
478         default:
479             RELEASE_ASSERT_NOT_REACHED();
480             break;
481         }
482     }
483     
484     void compilePhi()
485     {
486         LValue source = m_phis.get(m_node);
487         
488         switch (m_node->flags() & NodeResultMask) {
489         case NodeResultNumber:
490             setDouble(m_out.get(source));
491             break;
492         case NodeResultInt32:
493             setInt32(m_out.get(source));
494             break;
495         case NodeResultInt52:
496             setInt52(m_out.get(source));
497             break;
498         case NodeResultBoolean:
499             setBoolean(m_out.get(source));
500             break;
501         case NodeResultJS:
502             setJSValue(m_out.get(source));
503             break;
504         default:
505             RELEASE_ASSERT_NOT_REACHED();
506             break;
507         }
508     }
509     
510     void compileJSConstant()
511     {
512         JSValue value = m_graph.valueOfJSConstant(m_node);
513         if (value.isDouble())
514             setDouble(m_out.constDouble(value.asDouble()));
515         else
516             setJSValue(m_out.constInt64(JSValue::encode(value)));
517     }
518     
519     void compileWeakJSConstant()
520     {
521         setJSValue(weakPointer(m_node->weakConstant()));
522     }
523     
524     void compileGetArgument()
525     {
526         VariableAccessData* variable = m_node->variableAccessData();
527         int operand = variable->operand();
528
529         LValue jsValue = m_out.load64(addressFor(operand));
530
531         switch (useKindFor(variable->flushFormat())) {
532         case Int32Use:
533             speculateBackward(BadType, jsValueValue(jsValue), m_node, isNotInt32(jsValue));
534             setInt32(unboxInt32(jsValue));
535             break;
536         case CellUse:
537             speculateBackward(BadType, jsValueValue(jsValue), m_node, isNotCell(jsValue));
538             setJSValue(jsValue);
539             break;
540         case BooleanUse:
541             speculateBackward(BadType, jsValueValue(jsValue), m_node, isNotBoolean(jsValue));
542             setBoolean(unboxBoolean(jsValue));
543             break;
544         case UntypedUse:
545             setJSValue(jsValue);
546             break;
547         default:
548             RELEASE_ASSERT_NOT_REACHED();
549             break;
550         }
551     }
552     
553     void compileExtractOSREntryLocal()
554     {
555         EncodedJSValue* buffer = static_cast<EncodedJSValue*>(
556             m_ftlState.jitCode->ftlForOSREntry()->entryBuffer()->dataBuffer());
557         setJSValue(m_out.load64(m_out.absolute(buffer + operandToLocal(m_node->unlinkedLocal()))));
558     }
559     
560     void compileGetLocal()
561     {
562         // GetLocals arise only for captured variables.
563         
564         VariableAccessData* variable = m_node->variableAccessData();
565         AbstractValue& value = m_state.variables().operand(variable->local());
566         
567         RELEASE_ASSERT(variable->isCaptured());
568         
569         if (isInt32Speculation(value.m_type))
570             setInt32(m_out.load32(payloadFor(variable->local())));
571         else
572             setJSValue(m_out.load64(addressFor(variable->local())));
573     }
574     
575     void compileSetLocal()
576     {
577         observeMovHint(m_node);
578         
579         VariableAccessData* variable = m_node->variableAccessData();
580         switch (variable->flushFormat()) {
581         case FlushedJSValue: {
582             LValue value = lowJSValue(m_node->child1());
583             m_out.store64(value, addressFor(variable->local()));
584             m_valueSources.operand(variable->local()) = ValueSource(ValueInJSStack);
585             return;
586         }
587             
588         case FlushedDouble: {
589             LValue value = lowDouble(m_node->child1());
590             m_out.storeDouble(value, addressFor(variable->local()));
591             m_valueSources.operand(variable->local()) = ValueSource(DoubleInJSStack);
592             return;
593         }
594             
595         case FlushedInt32: {
596             LValue value = lowInt32(m_node->child1());
597             m_out.store32(value, payloadFor(variable->local()));
598             m_valueSources.operand(variable->local()) = ValueSource(Int32InJSStack);
599             return;
600         }
601             
602         case FlushedInt52: {
603             LValue value = lowInt52(m_node->child1());
604             m_out.store64(value, addressFor(variable->local()));
605             m_valueSources.operand(variable->local()) = ValueSource(Int52InJSStack);
606             return;
607         }
608             
609         case FlushedCell: {
610             LValue value = lowCell(m_node->child1());
611             m_out.store64(value, addressFor(variable->local()));
612             m_valueSources.operand(variable->local()) = ValueSource(ValueInJSStack);
613             return;
614         }
615             
616         case FlushedBoolean: {
617             speculateBoolean(m_node->child1());
618             m_out.store64(
619                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
620                 addressFor(variable->local()));
621             m_valueSources.operand(variable->local()) = ValueSource(ValueInJSStack);
622             return;
623         }
624             
625         case DeadFlush:
626             RELEASE_ASSERT_NOT_REACHED();
627         }
628         
629         RELEASE_ASSERT_NOT_REACHED();
630     }
631     
632     void compileMovHint()
633     {
634         observeMovHint(m_node);
635     }
636     
637     void compileZombieHint()
638     {
639         VariableAccessData* data = m_node->variableAccessData();
640         m_lastSetOperand = data->local();
641         m_valueSources.operand(data->local()) = ValueSource(SourceIsDead);
642     }
643     
644     void compileMovHintAndCheck()
645     {
646         observeMovHint(m_node);
647         speculate(m_node->child1());
648     }
649     
650     void compilePhantom()
651     {
652         DFG_NODE_DO_TO_CHILDREN(m_graph, m_node, speculate);
653     }
654     
655     void compileAdd()
656     {
657         switch (m_node->binaryUseKind()) {
658         case Int32Use: {
659             LValue left = lowInt32(m_node->child1());
660             LValue right = lowInt32(m_node->child2());
661             
662             if (bytecodeCanTruncateInteger(m_node->arithNodeFlags())) {
663                 setInt32(m_out.add(left, right));
664                 break;
665             }
666             
667             LValue result = m_out.addWithOverflow32(left, right);
668             speculate(Overflow, noValue(), 0, m_out.extractValue(result, 1));
669             setInt32(m_out.extractValue(result, 0));
670             break;
671         }
672             
673         case MachineIntUse: {
674             if (!m_state.forNode(m_node->child1()).couldBeType(SpecInt52)
675                 && !m_state.forNode(m_node->child2()).couldBeType(SpecInt52)) {
676                 Int52Kind kind;
677                 LValue left = lowWhicheverInt52(m_node->child1(), kind);
678                 LValue right = lowInt52(m_node->child2(), kind);
679                 setInt52(m_out.add(left, right), kind);
680                 break;
681             }
682             
683             LValue left = lowInt52(m_node->child1());
684             LValue right = lowInt52(m_node->child2());
685             LValue result = m_out.addWithOverflow64(left, right);
686             speculate(Int52Overflow, noValue(), 0, m_out.extractValue(result, 1));
687             setInt52(m_out.extractValue(result, 0));
688             break;
689         }
690             
691         case NumberUse: {
692             setDouble(
693                 m_out.doubleAdd(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
694             break;
695         }
696             
697         default:
698             RELEASE_ASSERT_NOT_REACHED();
699             break;
700         }
701     }
702     
703     void compileArithSub()
704     {
705         switch (m_node->binaryUseKind()) {
706         case Int32Use: {
707             LValue left = lowInt32(m_node->child1());
708             LValue right = lowInt32(m_node->child2());
709             
710             if (bytecodeCanTruncateInteger(m_node->arithNodeFlags())) {
711                 setInt32(m_out.sub(left, right));
712                 break;
713             }
714             
715             LValue result = m_out.subWithOverflow32(left, right);
716             speculate(Overflow, noValue(), 0, m_out.extractValue(result, 1));
717             setInt32(m_out.extractValue(result, 0));
718             break;
719         }
720             
721         case MachineIntUse: {
722             if (!m_state.forNode(m_node->child1()).couldBeType(SpecInt52)
723                 && !m_state.forNode(m_node->child2()).couldBeType(SpecInt52)) {
724                 Int52Kind kind;
725                 LValue left = lowWhicheverInt52(m_node->child1(), kind);
726                 LValue right = lowInt52(m_node->child2(), kind);
727                 setInt52(m_out.sub(left, right), kind);
728                 break;
729             }
730             
731             LValue left = lowInt52(m_node->child1());
732             LValue right = lowInt52(m_node->child2());
733             LValue result = m_out.subWithOverflow64(left, right);
734             speculate(Int52Overflow, noValue(), 0, m_out.extractValue(result, 1));
735             setInt52(m_out.extractValue(result, 0));
736             break;
737         }
738             
739         case NumberUse: {
740             setDouble(
741                 m_out.doubleSub(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
742             break;
743         }
744             
745         default:
746             RELEASE_ASSERT_NOT_REACHED();
747             break;
748         }
749     }
750     
751     void compileArithMul()
752     {
753         switch (m_node->binaryUseKind()) {
754         case Int32Use: {
755             LValue left = lowInt32(m_node->child1());
756             LValue right = lowInt32(m_node->child2());
757             
758             LValue result;
759             if (bytecodeCanTruncateInteger(m_node->arithNodeFlags()))
760                 result = m_out.mul(left, right);
761             else {
762                 LValue overflowResult = m_out.mulWithOverflow32(left, right);
763                 speculate(Overflow, noValue(), 0, m_out.extractValue(overflowResult, 1));
764                 result = m_out.extractValue(overflowResult, 0);
765             }
766             
767             if (!bytecodeCanIgnoreNegativeZero(m_node->arithNodeFlags())) {
768                 LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("ArithMul slow case"));
769                 LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithMul continuation"));
770                 
771                 m_out.branch(m_out.notZero32(result), continuation, slowCase);
772                 
773                 LBasicBlock lastNext = m_out.appendTo(slowCase, continuation);
774                 speculate(NegativeZero, noValue(), 0, m_out.lessThan(left, m_out.int32Zero));
775                 speculate(NegativeZero, noValue(), 0, m_out.lessThan(right, m_out.int32Zero));
776                 m_out.jump(continuation);
777                 m_out.appendTo(continuation, lastNext);
778             }
779             
780             setInt32(result);
781             break;
782         }
783             
784         case MachineIntUse: {
785             Int52Kind kind;
786             LValue left = lowWhicheverInt52(m_node->child1(), kind);
787             LValue right = lowInt52(m_node->child2(), opposite(kind));
788             
789             LValue overflowResult = m_out.mulWithOverflow64(left, right);
790             speculate(Int52Overflow, noValue(), 0, m_out.extractValue(overflowResult, 1));
791             LValue result = m_out.extractValue(overflowResult, 0);
792             
793             if (!bytecodeCanIgnoreNegativeZero(m_node->arithNodeFlags())) {
794                 LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("ArithMul slow case"));
795                 LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithMul continuation"));
796                 
797                 m_out.branch(m_out.notZero64(result), continuation, slowCase);
798                 
799                 LBasicBlock lastNext = m_out.appendTo(slowCase, continuation);
800                 speculate(NegativeZero, noValue(), 0, m_out.lessThan(left, m_out.int64Zero));
801                 speculate(NegativeZero, noValue(), 0, m_out.lessThan(right, m_out.int64Zero));
802                 m_out.jump(continuation);
803                 m_out.appendTo(continuation, lastNext);
804             }
805             
806             setInt52(result);
807             break;
808         }
809             
810         case NumberUse: {
811             setDouble(
812                 m_out.doubleMul(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
813             break;
814         }
815             
816         default:
817             RELEASE_ASSERT_NOT_REACHED();
818             break;
819         }
820     }
821     
822     void compileArithDiv()
823     {
824         switch (m_node->binaryUseKind()) {
825         case Int32Use: {
826             LValue numerator = lowInt32(m_node->child1());
827             LValue denominator = lowInt32(m_node->child2());
828             
829             LBasicBlock unsafeDenominator = FTL_NEW_BLOCK(m_out, ("ArithDiv unsafe denominator"));
830             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithDiv continuation"));
831             LBasicBlock done = FTL_NEW_BLOCK(m_out, ("ArithDiv done"));
832             
833             Vector<ValueFromBlock, 3> results;
834             
835             LValue adjustedDenominator = m_out.add(denominator, m_out.int32One);
836             
837             m_out.branch(m_out.above(adjustedDenominator, m_out.int32One), continuation, unsafeDenominator);
838             
839             LBasicBlock lastNext = m_out.appendTo(unsafeDenominator, continuation);
840             
841             LValue neg2ToThe31 = m_out.constInt32(-2147483647-1);
842             
843             if (bytecodeUsesAsNumber(m_node->arithNodeFlags())) {
844                 speculate(Overflow, noValue(), 0, m_out.isZero32(denominator));
845                 speculate(Overflow, noValue(), 0, m_out.equal(numerator, neg2ToThe31));
846                 m_out.jump(continuation);
847             } else {
848                 // This is the case where we convert the result to an int after we're done. So,
849                 // if the denominator is zero, then the result should be result should be zero.
850                 // If the denominator is not zero (i.e. it's -1 because we're guarded by the
851                 // check above) and the numerator is -2^31 then the result should be -2^31.
852                 
853                 LBasicBlock divByZero = FTL_NEW_BLOCK(m_out, ("ArithDiv divide by zero"));
854                 LBasicBlock notDivByZero = FTL_NEW_BLOCK(m_out, ("ArithDiv not divide by zero"));
855                 LBasicBlock neg2ToThe31ByNeg1 = FTL_NEW_BLOCK(m_out, ("ArithDiv -2^31/-1"));
856                 
857                 m_out.branch(m_out.isZero32(denominator), divByZero, notDivByZero);
858                 
859                 m_out.appendTo(divByZero, notDivByZero);
860                 results.append(m_out.anchor(m_out.int32Zero));
861                 m_out.jump(done);
862                 
863                 m_out.appendTo(notDivByZero, neg2ToThe31ByNeg1);
864                 m_out.branch(m_out.equal(numerator, neg2ToThe31), neg2ToThe31ByNeg1, continuation);
865                 
866                 m_out.appendTo(neg2ToThe31ByNeg1, continuation);
867                 results.append(m_out.anchor(neg2ToThe31));
868                 m_out.jump(done);
869             }
870             
871             m_out.appendTo(continuation, done);
872             
873             if (!bytecodeCanIgnoreNegativeZero(m_node->arithNodeFlags())) {
874                 LBasicBlock zeroNumerator = FTL_NEW_BLOCK(m_out, ("ArithDiv zero numerator"));
875                 LBasicBlock numeratorContinuation = FTL_NEW_BLOCK(m_out, ("ArithDiv numerator continuation"));
876                 
877                 m_out.branch(m_out.isZero32(numerator), zeroNumerator, numeratorContinuation);
878                 
879                 LBasicBlock innerLastNext = m_out.appendTo(zeroNumerator, numeratorContinuation);
880                 
881                 speculate(
882                     NegativeZero, noValue(), 0, m_out.lessThan(denominator, m_out.int32Zero));
883                 
884                 m_out.jump(numeratorContinuation);
885                 
886                 m_out.appendTo(numeratorContinuation, innerLastNext);
887             }
888             
889             LValue divisionResult = m_out.div(numerator, denominator);
890             
891             if (bytecodeUsesAsNumber(m_node->arithNodeFlags())) {
892                 speculate(
893                     Overflow, noValue(), 0,
894                     m_out.notEqual(m_out.mul(divisionResult, denominator), numerator));
895             }
896             
897             results.append(m_out.anchor(divisionResult));
898             m_out.jump(done);
899             
900             m_out.appendTo(done, lastNext);
901             
902             setInt32(m_out.phi(m_out.int32, results));
903             break;
904         }
905             
906         case NumberUse: {
907             setDouble(
908                 m_out.doubleDiv(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
909             break;
910         }
911             
912         default:
913             RELEASE_ASSERT_NOT_REACHED();
914             break;
915         }
916     }
917     
918     void compileArithMod()
919     {
920         switch (m_node->binaryUseKind()) {
921         case Int32Use: {
922             LValue numerator = lowInt32(m_node->child1());
923             LValue denominator = lowInt32(m_node->child2());
924             
925             LBasicBlock unsafeDenominator = FTL_NEW_BLOCK(m_out, ("ArithMod unsafe denominator"));
926             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithMod continuation"));
927             LBasicBlock done = FTL_NEW_BLOCK(m_out, ("ArithMod done"));
928             
929             Vector<ValueFromBlock, 3> results;
930             
931             LValue adjustedDenominator = m_out.add(denominator, m_out.int32One);
932             
933             m_out.branch(m_out.above(adjustedDenominator, m_out.int32One), continuation, unsafeDenominator);
934             
935             LBasicBlock lastNext = m_out.appendTo(unsafeDenominator, continuation);
936             
937             LValue neg2ToThe31 = m_out.constInt32(-2147483647-1);
938             
939             // FIXME: -2^31 / -1 will actually yield negative zero, so we could have a
940             // separate case for that. But it probably doesn't matter so much.
941             if (bytecodeUsesAsNumber(m_node->arithNodeFlags())) {
942                 speculate(Overflow, noValue(), 0, m_out.isZero32(denominator));
943                 speculate(Overflow, noValue(), 0, m_out.equal(numerator, neg2ToThe31));
944                 m_out.jump(continuation);
945             } else {
946                 // This is the case where we convert the result to an int after we're done. So,
947                 // if the denominator is zero, then the result should be result should be zero.
948                 // If the denominator is not zero (i.e. it's -1 because we're guarded by the
949                 // check above) and the numerator is -2^31 then the result should be -2^31.
950                 
951                 LBasicBlock modByZero = FTL_NEW_BLOCK(m_out, ("ArithMod modulo by zero"));
952                 LBasicBlock notModByZero = FTL_NEW_BLOCK(m_out, ("ArithMod not modulo by zero"));
953                 LBasicBlock neg2ToThe31ByNeg1 = FTL_NEW_BLOCK(m_out, ("ArithMod -2^31/-1"));
954                 
955                 m_out.branch(m_out.isZero32(denominator), modByZero, notModByZero);
956                 
957                 m_out.appendTo(modByZero, notModByZero);
958                 results.append(m_out.anchor(m_out.int32Zero));
959                 m_out.jump(done);
960                 
961                 m_out.appendTo(notModByZero, neg2ToThe31ByNeg1);
962                 m_out.branch(m_out.equal(numerator, neg2ToThe31), neg2ToThe31ByNeg1, continuation);
963                 
964                 m_out.appendTo(neg2ToThe31ByNeg1, continuation);
965                 results.append(m_out.anchor(m_out.int32Zero));
966                 m_out.jump(done);
967             }
968             
969             m_out.appendTo(continuation, done);
970             
971             LValue remainder = m_out.rem(numerator, denominator);
972             
973             if (!bytecodeCanIgnoreNegativeZero(m_node->arithNodeFlags())) {
974                 LBasicBlock negativeNumerator = FTL_NEW_BLOCK(m_out, ("ArithMod negative numerator"));
975                 LBasicBlock numeratorContinuation = FTL_NEW_BLOCK(m_out, ("ArithMod numerator continuation"));
976                 
977                 m_out.branch(
978                     m_out.lessThan(numerator, m_out.int32Zero),
979                     negativeNumerator, numeratorContinuation);
980                 
981                 LBasicBlock innerLastNext = m_out.appendTo(negativeNumerator, numeratorContinuation);
982                 
983                 speculate(NegativeZero, noValue(), 0, m_out.isZero32(remainder));
984                 
985                 m_out.jump(numeratorContinuation);
986                 
987                 m_out.appendTo(numeratorContinuation, innerLastNext);
988             }
989             
990             results.append(m_out.anchor(remainder));
991             m_out.jump(done);
992             
993             m_out.appendTo(done, lastNext);
994             
995             setInt32(m_out.phi(m_out.int32, results));
996             break;
997         }
998             
999         case NumberUse: {
1000             setDouble(
1001                 m_out.doubleRem(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
1002             break;
1003         }
1004             
1005         default:
1006             RELEASE_ASSERT_NOT_REACHED();
1007             break;
1008         }
1009     }
1010
1011     void compileArithMinOrMax()
1012     {
1013         switch (m_node->binaryUseKind()) {
1014         case Int32Use: {
1015             LValue left = lowInt32(m_node->child1());
1016             LValue right = lowInt32(m_node->child2());
1017             
1018             setInt32(
1019                 m_out.select(
1020                     m_node->op() == ArithMin
1021                         ? m_out.lessThan(left, right)
1022                         : m_out.lessThan(right, left),
1023                     left, right));
1024             break;
1025         }
1026             
1027         case NumberUse: {
1028             LValue left = lowDouble(m_node->child1());
1029             LValue right = lowDouble(m_node->child2());
1030             
1031             LBasicBlock notLessThan = FTL_NEW_BLOCK(m_out, ("ArithMin/ArithMax not less than"));
1032             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithMin/ArithMax continuation"));
1033             
1034             Vector<ValueFromBlock, 2> results;
1035             
1036             results.append(m_out.anchor(left));
1037             m_out.branch(
1038                 m_node->op() == ArithMin
1039                     ? m_out.doubleLessThan(left, right)
1040                     : m_out.doubleGreaterThan(left, right),
1041                 continuation, notLessThan);
1042             
1043             LBasicBlock lastNext = m_out.appendTo(notLessThan, continuation);
1044             results.append(m_out.anchor(m_out.select(
1045                 m_node->op() == ArithMin
1046                     ? m_out.doubleGreaterThanOrEqual(left, right)
1047                     : m_out.doubleLessThanOrEqual(left, right),
1048                 right, m_out.constDouble(0.0 / 0.0))));
1049             m_out.jump(continuation);
1050             
1051             m_out.appendTo(continuation, lastNext);
1052             setDouble(m_out.phi(m_out.doubleType, results));
1053             break;
1054         }
1055             
1056         default:
1057             RELEASE_ASSERT_NOT_REACHED();
1058             break;
1059         }
1060     }
1061     
1062     void compileArithAbs()
1063     {
1064         switch (m_node->child1().useKind()) {
1065         case Int32Use: {
1066             LValue value = lowInt32(m_node->child1());
1067             
1068             LValue mask = m_out.aShr(value, m_out.constInt32(31));
1069             LValue result = m_out.bitXor(mask, m_out.add(mask, value));
1070             
1071             speculate(Overflow, noValue(), 0, m_out.equal(result, m_out.constInt32(1 << 31)));
1072             
1073             setInt32(result);
1074             break;
1075         }
1076             
1077         case NumberUse: {
1078             setDouble(m_out.doubleAbs(lowDouble(m_node->child1())));
1079             break;
1080         }
1081             
1082         default:
1083             RELEASE_ASSERT_NOT_REACHED();
1084             break;
1085         }
1086     }
1087     
1088     void compileArithNegate()
1089     {
1090         switch (m_node->child1().useKind()) {
1091         case Int32Use: {
1092             LValue value = lowInt32(m_node->child1());
1093             
1094             LValue result;
1095             if (bytecodeCanTruncateInteger(m_node->arithNodeFlags()))
1096                 result = m_out.neg(value);
1097             else if (bytecodeCanIgnoreNegativeZero(m_node->arithNodeFlags())) {
1098                 // We don't have a negate-with-overflow intrinsic. Hopefully this
1099                 // does the trick, though.
1100                 LValue overflowResult = m_out.subWithOverflow32(m_out.int32Zero, value);
1101                 speculate(Overflow, noValue(), 0, m_out.extractValue(overflowResult, 1));
1102                 result = m_out.extractValue(overflowResult, 0);
1103             } else {
1104                 speculate(Overflow, noValue(), 0, m_out.testIsZero32(value, m_out.constInt32(0x7fffffff)));
1105                 result = m_out.neg(value);
1106             }
1107             
1108             setInt32(result);
1109             break;
1110         }
1111             
1112         case MachineIntUse: {
1113             if (!m_state.forNode(m_node->child1()).couldBeType(SpecInt52)) {
1114                 Int52Kind kind;
1115                 LValue value = lowWhicheverInt52(m_node->child1(), kind);
1116                 LValue result = m_out.neg(value);
1117                 if (!bytecodeCanIgnoreNegativeZero(m_node->arithNodeFlags()))
1118                     speculate(NegativeZero, noValue(), 0, m_out.isZero64(result));
1119                 setInt52(result, kind);
1120                 break;
1121             }
1122             
1123             LValue value = lowInt52(m_node->child1());
1124             LValue overflowResult = m_out.subWithOverflow64(m_out.int64Zero, value);
1125             speculate(Int52Overflow, noValue(), 0, m_out.extractValue(overflowResult, 1));
1126             LValue result = m_out.extractValue(overflowResult, 0);
1127             speculate(NegativeZero, noValue(), 0, m_out.isZero64(result));
1128             setInt52(result);
1129             break;
1130         }
1131             
1132         case NumberUse: {
1133             setDouble(m_out.doubleNeg(lowDouble(m_node->child1())));
1134             break;
1135         }
1136             
1137         default:
1138             RELEASE_ASSERT_NOT_REACHED();
1139             break;
1140         }
1141     }
1142     
1143     void compileBitAnd()
1144     {
1145         setInt32(m_out.bitAnd(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
1146     }
1147     
1148     void compileBitOr()
1149     {
1150         setInt32(m_out.bitOr(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
1151     }
1152     
1153     void compileBitXor()
1154     {
1155         setInt32(m_out.bitXor(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
1156     }
1157     
1158     void compileBitRShift()
1159     {
1160         setInt32(m_out.aShr(
1161             lowInt32(m_node->child1()),
1162             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
1163     }
1164     
1165     void compileBitLShift()
1166     {
1167         setInt32(m_out.shl(
1168             lowInt32(m_node->child1()),
1169             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
1170     }
1171     
1172     void compileBitURShift()
1173     {
1174         setInt32(m_out.lShr(
1175             lowInt32(m_node->child1()),
1176             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
1177     }
1178     
1179     void compileUInt32ToNumber()
1180     {
1181         LValue value = lowInt32(m_node->child1());
1182
1183         if (!nodeCanSpeculateInt32(m_node->arithNodeFlags())) {
1184             setDouble(m_out.unsignedToDouble(value));
1185             return;
1186         }
1187         
1188         speculateForward(
1189             Overflow, noValue(), 0, m_out.lessThan(value, m_out.int32Zero),
1190             FormattedValue(ValueFormatUInt32, value));
1191         setInt32(value);
1192     }
1193     
1194     void compileInt32ToDouble()
1195     {
1196         // This node is tricky to compile in the DFG backend because it tries to
1197         // avoid converting child1 to a double in-place, as that would make subsequent
1198         // int uses of of child1 fail. But the FTL needs no such special magic, since
1199         // unlike the DFG backend, the FTL allows each node to have multiple
1200         // contemporaneous low-level representations. So, this gives child1 a double
1201         // representation and then forwards that representation to m_node.
1202         
1203         setDouble(lowDouble(m_node->child1()));
1204     }
1205     
1206     void compileCheckStructure()
1207     {
1208         LValue cell = lowCell(m_node->child1());
1209         
1210         ExitKind exitKind;
1211         if (m_node->child1()->op() == WeakJSConstant)
1212             exitKind = BadWeakConstantCache;
1213         else
1214             exitKind = BadCache;
1215         
1216         LValue structure = m_out.loadPtr(cell, m_heaps.JSCell_structure);
1217         
1218         if (m_node->structureSet().size() == 1) {
1219             speculate(
1220                 exitKind, jsValueValue(cell), 0,
1221                 m_out.notEqual(structure, weakPointer(m_node->structureSet()[0])));
1222             return;
1223         }
1224         
1225         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("CheckStructure continuation"));
1226         
1227         LBasicBlock lastNext = m_out.insertNewBlocksBefore(continuation);
1228         for (unsigned i = 0; i < m_node->structureSet().size() - 1; ++i) {
1229             LBasicBlock nextStructure = FTL_NEW_BLOCK(m_out, ("CheckStructure nextStructure"));
1230             m_out.branch(
1231                 m_out.equal(structure, weakPointer(m_node->structureSet()[i])),
1232                 continuation, nextStructure);
1233             m_out.appendTo(nextStructure);
1234         }
1235         
1236         speculate(
1237             exitKind, jsValueValue(cell), 0,
1238             m_out.notEqual(structure, weakPointer(m_node->structureSet().last())));
1239         
1240         m_out.jump(continuation);
1241         m_out.appendTo(continuation, lastNext);
1242     }
1243     
1244     void compileStructureTransitionWatchpoint()
1245     {
1246         addWeakReference(m_node->structure());
1247         
1248         // FIXME: Implement structure transition watchpoints.
1249         // https://bugs.webkit.org/show_bug.cgi?id=113647
1250         
1251         speculateCell(m_node->child1());
1252     }
1253     
1254     void compileArrayifyToStructure()
1255     {
1256         LValue cell = lowCell(m_node->child1());
1257         LValue property = !!m_node->child2() ? lowInt32(m_node->child2()) : 0;
1258         
1259         LBasicBlock unexpectedStructure = FTL_NEW_BLOCK(m_out, ("ArrayifyToStructure unexpected structure"));
1260         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArrayifyToStructure continuation"));
1261         
1262         LValue structure = m_out.loadPtr(cell, m_heaps.JSCell_structure);
1263         
1264         m_out.branch(
1265             m_out.notEqual(structure, weakPointer(m_node->structure())),
1266             unexpectedStructure, continuation);
1267         
1268         LBasicBlock lastNext = m_out.appendTo(unexpectedStructure, continuation);
1269         
1270         if (property) {
1271             switch (m_node->arrayMode().type()) {
1272             case Array::Int32:
1273             case Array::Double:
1274             case Array::Contiguous:
1275                 speculate(
1276                     Uncountable, noValue(), 0,
1277                     m_out.aboveOrEqual(property, m_out.constInt32(MIN_SPARSE_ARRAY_INDEX)));
1278                 break;
1279             default:
1280                 break;
1281             }
1282         }
1283         
1284         switch (m_node->arrayMode().type()) {
1285         case Array::Int32:
1286             vmCall(m_out.operation(operationEnsureInt32), m_callFrame, cell);
1287             break;
1288         case Array::Double:
1289             vmCall(m_out.operation(operationEnsureDouble), m_callFrame, cell);
1290             break;
1291         case Array::Contiguous:
1292             if (m_node->arrayMode().conversion() == Array::RageConvert)
1293                 vmCall(m_out.operation(operationRageEnsureContiguous), m_callFrame, cell);
1294             else
1295                 vmCall(m_out.operation(operationEnsureContiguous), m_callFrame, cell);
1296             break;
1297         case Array::ArrayStorage:
1298         case Array::SlowPutArrayStorage:
1299             vmCall(m_out.operation(operationEnsureArrayStorage), m_callFrame, cell);
1300             break;
1301         default:
1302             RELEASE_ASSERT_NOT_REACHED();
1303             break;
1304         }
1305         
1306         structure = m_out.loadPtr(cell, m_heaps.JSCell_structure);
1307         speculate(
1308             BadIndexingType, jsValueValue(cell), 0,
1309             m_out.notEqual(structure, weakPointer(m_node->structure())));
1310         m_out.jump(continuation);
1311         
1312         m_out.appendTo(continuation, lastNext);
1313     }
1314     
1315     void compilePutStructure()
1316     {
1317         m_ftlState.jitCode->common.notifyCompilingStructureTransition(m_graph.m_plan, codeBlock(), m_node);
1318         
1319         m_out.store64(
1320             m_out.constIntPtr(m_node->structureTransitionData().newStructure),
1321             lowCell(m_node->child1()), m_heaps.JSCell_structure);
1322     }
1323     
1324     void compilePhantomPutStructure()
1325     {
1326         m_ftlState.jitCode->common.notifyCompilingStructureTransition(m_graph.m_plan, codeBlock(), m_node);
1327     }
1328     
1329     void compileGetButterfly()
1330     {
1331         setStorage(m_out.loadPtr(lowCell(m_node->child1()), m_heaps.JSObject_butterfly));
1332     }
1333     
1334     void compileGetIndexedPropertyStorage()
1335     {
1336         setStorage(m_out.loadPtr(lowCell(m_node->child1()), m_heaps.JSArrayBufferView_vector));
1337     }
1338     
1339     void compileCheckArray()
1340     {
1341         Edge edge = m_node->child1();
1342         LValue cell = lowCell(edge);
1343         
1344         if (m_node->arrayMode().alreadyChecked(m_graph, m_node, m_state.forNode(edge)))
1345             return;
1346         
1347         speculate(
1348             BadIndexingType, jsValueValue(cell), 0,
1349             m_out.bitNot(isArrayType(cell, m_node->arrayMode())));
1350     }
1351     
1352     void compileGetArrayLength()
1353     {
1354         switch (m_node->arrayMode().type()) {
1355         case Array::Int32:
1356         case Array::Double:
1357         case Array::Contiguous: {
1358             setInt32(m_out.load32(lowStorage(m_node->child2()), m_heaps.Butterfly_publicLength));
1359             return;
1360         }
1361             
1362         default:
1363             if (isTypedView(m_node->arrayMode().typedArrayType())) {
1364                 setInt32(
1365                     m_out.load32(lowCell(m_node->child1()), m_heaps.JSArrayBufferView_length));
1366                 return;
1367             }
1368             
1369             RELEASE_ASSERT_NOT_REACHED();
1370             return;
1371         }
1372     }
1373     
1374     void compileGetByVal()
1375     {
1376         LValue index = lowInt32(m_node->child2());
1377         LValue storage = lowStorage(m_node->child3());
1378         
1379         switch (m_node->arrayMode().type()) {
1380         case Array::Int32:
1381         case Array::Contiguous: {
1382             if (m_node->arrayMode().isInBounds()) {
1383                 speculate(
1384                     OutOfBounds, noValue(), 0,
1385                     m_out.aboveOrEqual(
1386                         index, m_out.load32(storage, m_heaps.Butterfly_publicLength)));
1387                 
1388                 LValue result = m_out.load64(m_out.baseIndex(
1389                     m_node->arrayMode().type() == Array::Int32 ?
1390                         m_heaps.indexedInt32Properties : m_heaps.indexedContiguousProperties,
1391                     storage, m_out.zeroExt(index, m_out.intPtr),
1392                     m_state.forNode(m_node->child2()).m_value));
1393                 speculate(LoadFromHole, noValue(), 0, m_out.isZero64(result));
1394                 setJSValue(result);
1395                 return;
1396             }
1397             
1398             // FIXME: Implement hole/OOB loads in the FTL.
1399             // https://bugs.webkit.org/show_bug.cgi?id=118077
1400             RELEASE_ASSERT_NOT_REACHED();
1401             return;
1402         }
1403             
1404         case Array::Double: {
1405             if (m_node->arrayMode().isInBounds()) {
1406                 if (m_node->arrayMode().isSaneChain()) {
1407                     // FIXME: Implement structure transition watchpoints.
1408                     // https://bugs.webkit.org/show_bug.cgi?id=113647
1409                 }
1410             
1411                 speculate(
1412                     OutOfBounds, noValue(), 0,
1413                     m_out.aboveOrEqual(
1414                         index, m_out.load32(storage, m_heaps.Butterfly_publicLength)));
1415                 
1416                 LValue result = m_out.loadDouble(m_out.baseIndex(
1417                     m_heaps.indexedDoubleProperties,
1418                     storage, m_out.zeroExt(index, m_out.intPtr),
1419                     m_state.forNode(m_node->child2()).m_value));
1420                 
1421                 if (!m_node->arrayMode().isSaneChain()) {
1422                     speculate(
1423                         LoadFromHole, noValue(), 0,
1424                         m_out.doubleNotEqualOrUnordered(result, result));
1425                 }
1426                 setDouble(result);
1427                 break;
1428             }
1429             
1430             // FIXME: Implement hole/OOB loads in the FTL.
1431             // https://bugs.webkit.org/show_bug.cgi?id=118077
1432             RELEASE_ASSERT_NOT_REACHED();
1433             return;
1434         }
1435             
1436         default: {
1437             TypedArrayType type = m_node->arrayMode().typedArrayType();
1438             
1439             if (isTypedView(type)) {
1440                 LValue array = lowCell(m_node->child1());
1441                 
1442                 speculate(
1443                     OutOfBounds, noValue(), 0,
1444                     m_out.aboveOrEqual(
1445                         index, m_out.load32(array, m_heaps.JSArrayBufferView_length)));
1446                 
1447                 TypedPointer pointer = TypedPointer(
1448                     m_heaps.typedArrayProperties,
1449                     m_out.add(
1450                         storage,
1451                         m_out.shl(
1452                             m_out.zeroExt(index, m_out.intPtr),
1453                             m_out.constIntPtr(logElementSize(type)))));
1454                 
1455                 if (isInt(type)) {
1456                     LValue result;
1457                     switch (elementSize(type)) {
1458                     case 1:
1459                         result = m_out.load8(pointer);
1460                         break;
1461                     case 2:
1462                         result = m_out.load16(pointer);
1463                         break;
1464                     case 4:
1465                         result = m_out.load32(pointer);
1466                         break;
1467                     default:
1468                         RELEASE_ASSERT_NOT_REACHED();
1469                     }
1470                     
1471                     if (elementSize(type) < 4) {
1472                         if (isSigned(type))
1473                             result = m_out.signExt(result, m_out.int32);
1474                         else
1475                             result = m_out.zeroExt(result, m_out.int32);
1476                         setInt32(result);
1477                         return;
1478                     }
1479                     
1480                     if (isSigned(type)) {
1481                         setInt32(result);
1482                         return;
1483                     }
1484                     
1485                     if (m_node->shouldSpeculateInt32()) {
1486                         speculateForward(
1487                             Overflow, noValue(), 0, m_out.lessThan(result, m_out.int32Zero),
1488                             uInt32Value(result));
1489                         setInt32(result);
1490                         return;
1491                     }
1492                     
1493                     setDouble(m_out.unsignedToFP(result, m_out.doubleType));
1494                     return;
1495                 }
1496             
1497                 ASSERT(isFloat(type));
1498                 
1499                 LValue result;
1500                 switch (type) {
1501                 case TypeFloat32:
1502                     result = m_out.fpCast(m_out.loadFloat(pointer), m_out.doubleType);
1503                     break;
1504                 case TypeFloat64:
1505                     result = m_out.loadDouble(pointer);
1506                     break;
1507                 default:
1508                     RELEASE_ASSERT_NOT_REACHED();
1509                 }
1510                 
1511                 result = m_out.select(
1512                     m_out.doubleEqual(result, result), result, m_out.constDouble(QNaN));
1513                 setDouble(result);
1514                 return;
1515             }
1516             
1517             RELEASE_ASSERT_NOT_REACHED();
1518             return;
1519         } }
1520     }
1521     
1522     void compilePutByVal()
1523     {
1524         Edge child1 = m_graph.varArgChild(m_node, 0);
1525         Edge child2 = m_graph.varArgChild(m_node, 1);
1526         Edge child3 = m_graph.varArgChild(m_node, 2);
1527         Edge child4 = m_graph.varArgChild(m_node, 3);
1528
1529         LValue base = lowCell(child1);
1530         LValue index = lowInt32(child2);
1531         LValue storage = lowStorage(child4);
1532         
1533         switch (m_node->arrayMode().type()) {
1534         case Array::Int32:
1535         case Array::Double:
1536         case Array::Contiguous: {
1537             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("PutByVal continuation"));
1538             LBasicBlock outerLastNext = m_out.appendTo(m_out.m_block, continuation);
1539             
1540             switch (m_node->arrayMode().type()) {
1541             case Array::Int32:
1542             case Array::Contiguous: {
1543                 LValue value = lowJSValue(child3, ManualOperandSpeculation);
1544                 
1545                 if (m_node->arrayMode().type() == Array::Int32)
1546                     FTL_TYPE_CHECK(jsValueValue(value), child3, SpecInt32, isNotInt32(value));
1547                 
1548                 TypedPointer elementPointer = m_out.baseIndex(
1549                     m_node->arrayMode().type() == Array::Int32 ?
1550                     m_heaps.indexedInt32Properties : m_heaps.indexedContiguousProperties,
1551                     storage, m_out.zeroExt(index, m_out.intPtr),
1552                     m_state.forNode(child2).m_value);
1553                 
1554                 if (m_node->op() == PutByValAlias) {
1555                     m_out.store64(value, elementPointer);
1556                     break;
1557                 }
1558                 
1559                 contiguousPutByValOutOfBounds(
1560                     codeBlock()->isStrictMode()
1561                     ? operationPutByValBeyondArrayBoundsStrict
1562                     : operationPutByValBeyondArrayBoundsNonStrict,
1563                     base, storage, index, value, continuation);
1564                 
1565                 m_out.store64(value, elementPointer);
1566                 break;
1567             }
1568                 
1569             case Array::Double: {
1570                 LValue value = lowDouble(child3);
1571                 
1572                 FTL_TYPE_CHECK(
1573                     doubleValue(value), child3, SpecFullRealNumber,
1574                     m_out.doubleNotEqualOrUnordered(value, value));
1575                 
1576                 TypedPointer elementPointer = m_out.baseIndex(
1577                     m_heaps.indexedDoubleProperties,
1578                     storage, m_out.zeroExt(index, m_out.intPtr),
1579                     m_state.forNode(child2).m_value);
1580                 
1581                 if (m_node->op() == PutByValAlias) {
1582                     m_out.storeDouble(value, elementPointer);
1583                     break;
1584                 }
1585                 
1586                 contiguousPutByValOutOfBounds(
1587                     codeBlock()->isStrictMode()
1588                     ? operationPutDoubleByValBeyondArrayBoundsStrict
1589                     : operationPutDoubleByValBeyondArrayBoundsNonStrict,
1590                     base, storage, index, value, continuation);
1591                 
1592                 m_out.storeDouble(value, elementPointer);
1593                 break;
1594             }
1595                 
1596             default:
1597                 RELEASE_ASSERT_NOT_REACHED();
1598             }
1599
1600             m_out.jump(continuation);
1601             m_out.appendTo(continuation, outerLastNext);
1602             return;
1603         }
1604             
1605         default:
1606             TypedArrayType type = m_node->arrayMode().typedArrayType();
1607             
1608             if (isTypedView(type)) {
1609                 if (m_node->op() == PutByVal) {
1610                     speculate(
1611                         OutOfBounds, noValue(), 0,
1612                         m_out.aboveOrEqual(
1613                             index, m_out.load32(base, m_heaps.JSArrayBufferView_length)));
1614                 }
1615                 
1616                 TypedPointer pointer = TypedPointer(
1617                     m_heaps.typedArrayProperties,
1618                     m_out.add(
1619                         storage,
1620                         m_out.shl(
1621                             m_out.zeroExt(index, m_out.intPtr),
1622                             m_out.constIntPtr(logElementSize(type)))));
1623                 
1624                 if (isInt(type)) {
1625                     LValue intValue;
1626                     switch (child3.useKind()) {
1627                     case Int32Use: {
1628                         intValue = lowInt32(child3);
1629                         if (isClamped(type)) {
1630                             ASSERT(elementSize(type) == 1);
1631                             
1632                             LBasicBlock atLeastZero = FTL_NEW_BLOCK(m_out, ("PutByVal int clamp atLeastZero"));
1633                             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("PutByVal int clamp continuation"));
1634                             
1635                             Vector<ValueFromBlock, 2> intValues;
1636                             intValues.append(m_out.anchor(m_out.int32Zero));
1637                             m_out.branch(
1638                                 m_out.lessThan(intValue, m_out.int32Zero),
1639                                 continuation, atLeastZero);
1640                             
1641                             LBasicBlock lastNext = m_out.appendTo(atLeastZero, continuation);
1642                             
1643                             intValues.append(m_out.anchor(m_out.select(
1644                                 m_out.greaterThan(intValue, m_out.constInt32(255)),
1645                                 m_out.constInt32(255),
1646                                 intValue)));
1647                             m_out.jump(continuation);
1648                             
1649                             m_out.appendTo(continuation, lastNext);
1650                             intValue = m_out.phi(m_out.int32, intValues);
1651                         }
1652                         break;
1653                     }
1654                         
1655                     case NumberUse: {
1656                         LValue doubleValue = lowDouble(child3);
1657                         
1658                         if (isClamped(type)) {
1659                             ASSERT(elementSize(type) == 1);
1660                             
1661                             LBasicBlock atLeastZero = FTL_NEW_BLOCK(m_out, ("PutByVal double clamp atLeastZero"));
1662                             LBasicBlock withinRange = FTL_NEW_BLOCK(m_out, ("PutByVal double clamp withinRange"));
1663                             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("PutByVal double clamp continuation"));
1664                             
1665                             Vector<ValueFromBlock, 3> intValues;
1666                             intValues.append(m_out.anchor(m_out.int32Zero));
1667                             m_out.branch(
1668                                 m_out.doubleLessThanOrUnordered(doubleValue, m_out.doubleZero),
1669                                 continuation, atLeastZero);
1670                             
1671                             LBasicBlock lastNext = m_out.appendTo(atLeastZero, withinRange);
1672                             intValues.append(m_out.anchor(m_out.constInt32(255)));
1673                             m_out.branch(
1674                                 m_out.doubleGreaterThan(doubleValue, m_out.constDouble(255)),
1675                                 continuation, withinRange);
1676                             
1677                             m_out.appendTo(withinRange, continuation);
1678                             intValues.append(m_out.anchor(m_out.fpToInt32(doubleValue)));
1679                             m_out.jump(continuation);
1680                             
1681                             m_out.appendTo(continuation, lastNext);
1682                             intValue = m_out.phi(m_out.int32, intValues);
1683                         } else if (isSigned(type))
1684                             intValue = doubleToInt32(doubleValue);
1685                         else
1686                             intValue = doubleToUInt32(doubleValue);
1687                         break;
1688                     }
1689                         
1690                     default:
1691                         RELEASE_ASSERT_NOT_REACHED();
1692                     }
1693                     
1694                     switch (elementSize(type)) {
1695                     case 1:
1696                         m_out.store8(m_out.intCast(intValue, m_out.int8), pointer);
1697                         break;
1698                     case 2:
1699                         m_out.store16(m_out.intCast(intValue, m_out.int16), pointer);
1700                         break;
1701                     case 4:
1702                         m_out.store32(intValue, pointer);
1703                         break;
1704                     default:
1705                         RELEASE_ASSERT_NOT_REACHED();
1706                     }
1707                     
1708                     return;
1709                 }
1710                 
1711                 ASSERT(isFloat(type));
1712                 
1713                 LValue value = lowDouble(child3);
1714                 switch (type) {
1715                 case TypeFloat32:
1716                     m_out.storeFloat(m_out.fpCast(value, m_out.floatType), pointer);
1717                     break;
1718                 case TypeFloat64:
1719                     m_out.storeDouble(value, pointer);
1720                     break;
1721                 default:
1722                     RELEASE_ASSERT_NOT_REACHED();
1723                 }
1724                 return;
1725             }
1726             
1727             RELEASE_ASSERT_NOT_REACHED();
1728             break;
1729         }
1730     }
1731     
1732     void compileGetByOffset()
1733     {
1734         StorageAccessData& data =
1735             m_graph.m_storageAccessData[m_node->storageAccessDataIndex()];
1736         
1737         setJSValue(
1738             m_out.load64(
1739                 m_out.address(
1740                     m_heaps.properties[data.identifierNumber],
1741                     lowStorage(m_node->child1()),
1742                     offsetRelativeToBase(data.offset))));
1743     }
1744     
1745     void compilePutByOffset()
1746     {
1747         StorageAccessData& data =
1748             m_graph.m_storageAccessData[m_node->storageAccessDataIndex()];
1749         
1750         m_out.store64(
1751             lowJSValue(m_node->child3()),
1752             m_out.address(
1753                 m_heaps.properties[data.identifierNumber],
1754                 lowStorage(m_node->child1()),
1755                 offsetRelativeToBase(data.offset)));
1756     }
1757     
1758     void compileGetGlobalVar()
1759     {
1760         setJSValue(m_out.load64(m_out.absolute(m_node->registerPointer())));
1761     }
1762     
1763     void compilePutGlobalVar()
1764     {
1765         m_out.store64(
1766             lowJSValue(m_node->child1()), m_out.absolute(m_node->registerPointer()));
1767     }
1768     
1769     void compileGlobalVarWatchpoint()
1770     {
1771         // FIXME: Implement watchpoints.
1772         // https://bugs.webkit.org/show_bug.cgi?id=113647
1773     }
1774     
1775     void compileGetMyScope()
1776     {
1777         setJSValue(m_out.loadPtr(addressFor(
1778             m_node->codeOrigin.stackOffset() + JSStack::ScopeChain)));
1779     }
1780     
1781     void compileSkipScope()
1782     {
1783         setJSValue(m_out.loadPtr(lowCell(m_node->child1()), m_heaps.JSScope_next));
1784     }
1785     
1786     void compileGetClosureRegisters()
1787     {
1788         setStorage(m_out.loadPtr(
1789             lowCell(m_node->child1()), m_heaps.JSVariableObject_registers));
1790     }
1791     
1792     void compileGetClosureVar()
1793     {
1794         setJSValue(m_out.load64(
1795             addressFor(lowStorage(m_node->child1()), m_node->varNumber())));
1796     }
1797     
1798     void compilePutClosureVar()
1799     {
1800         m_out.store64(
1801             lowJSValue(m_node->child3()),
1802             addressFor(lowStorage(m_node->child2()), m_node->varNumber()));
1803     }
1804     
1805     void compileCompareEq()
1806     {
1807         if (m_node->isBinaryUseKind(Int32Use)
1808             || m_node->isBinaryUseKind(MachineIntUse)
1809             || m_node->isBinaryUseKind(NumberUse)
1810             || m_node->isBinaryUseKind(ObjectUse)) {
1811             compileCompareStrictEq();
1812             return;
1813         }
1814         
1815         RELEASE_ASSERT_NOT_REACHED();
1816     }
1817     
1818     void compileCompareEqConstant()
1819     {
1820         ASSERT(m_graph.valueOfJSConstant(m_node->child2().node()).isNull());
1821         masqueradesAsUndefinedWatchpointIfIsStillValid();
1822         setBoolean(
1823             equalNullOrUndefined(
1824                 m_node->child1(), AllCellsAreFalse, EqualNullOrUndefined));
1825     }
1826     
1827     void compileCompareStrictEq()
1828     {
1829         if (m_node->isBinaryUseKind(Int32Use)) {
1830             setBoolean(
1831                 m_out.equal(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
1832             return;
1833         }
1834         
1835         if (m_node->isBinaryUseKind(MachineIntUse)) {
1836             Int52Kind kind;
1837             LValue left = lowWhicheverInt52(m_node->child1(), kind);
1838             LValue right = lowInt52(m_node->child2(), kind);
1839             setBoolean(m_out.equal(left, right));
1840             return;
1841         }
1842         
1843         if (m_node->isBinaryUseKind(NumberUse)) {
1844             setBoolean(
1845                 m_out.doubleEqual(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
1846             return;
1847         }
1848         
1849         if (m_node->isBinaryUseKind(ObjectUse)) {
1850             masqueradesAsUndefinedWatchpointIfIsStillValid();
1851             setBoolean(
1852                 m_out.equal(
1853                     lowNonNullObject(m_node->child1()),
1854                     lowNonNullObject(m_node->child2())));
1855             return;
1856         }
1857         
1858         RELEASE_ASSERT_NOT_REACHED();
1859     }
1860     
1861     void compileCompareStrictEqConstant()
1862     {
1863         JSValue constant = m_graph.valueOfJSConstant(m_node->child2().node());
1864
1865         if (constant.isUndefinedOrNull()
1866             && !masqueradesAsUndefinedWatchpointIfIsStillValid()) {
1867             if (constant.isNull()) {
1868                 setBoolean(equalNullOrUndefined(m_node->child1(), AllCellsAreFalse, EqualNull));
1869                 return;
1870             }
1871         
1872             ASSERT(constant.isUndefined());
1873             setBoolean(equalNullOrUndefined(m_node->child1(), AllCellsAreFalse, EqualUndefined));
1874             return;
1875         }
1876         
1877         setBoolean(
1878             m_out.equal(
1879                 lowJSValue(m_node->child1()),
1880                 m_out.constInt64(JSValue::encode(constant))));
1881     }
1882     
1883     void compileCompareLess()
1884     {
1885         if (m_node->isBinaryUseKind(Int32Use)) {
1886             setBoolean(
1887                 m_out.lessThan(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
1888             return;
1889         }
1890         
1891         if (m_node->isBinaryUseKind(MachineIntUse)) {
1892             Int52Kind kind;
1893             LValue left = lowWhicheverInt52(m_node->child1(), kind);
1894             LValue right = lowInt52(m_node->child2(), kind);
1895             setBoolean(m_out.lessThan(left, right));
1896             return;
1897         }
1898         
1899         if (m_node->isBinaryUseKind(NumberUse)) {
1900             setBoolean(
1901                 m_out.doubleLessThan(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
1902             return;
1903         }
1904         
1905         RELEASE_ASSERT_NOT_REACHED();
1906     }
1907     
1908     void compileCompareLessEq()
1909     {
1910         if (m_node->isBinaryUseKind(Int32Use)) {
1911             setBoolean(
1912                 m_out.lessThanOrEqual(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
1913             return;
1914         }
1915         
1916         if (m_node->isBinaryUseKind(MachineIntUse)) {
1917             Int52Kind kind;
1918             LValue left = lowWhicheverInt52(m_node->child1(), kind);
1919             LValue right = lowInt52(m_node->child2(), kind);
1920             setBoolean(m_out.lessThanOrEqual(left, right));
1921             return;
1922         }
1923         
1924         if (m_node->isBinaryUseKind(NumberUse)) {
1925             setBoolean(
1926                 m_out.doubleLessThanOrEqual(
1927                     lowDouble(m_node->child1()), lowDouble(m_node->child2())));
1928             return;
1929         }
1930         
1931         RELEASE_ASSERT_NOT_REACHED();
1932     }
1933     
1934     void compileCompareGreater()
1935     {
1936         if (m_node->isBinaryUseKind(Int32Use)) {
1937             setBoolean(
1938                 m_out.greaterThan(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
1939             return;
1940         }
1941         
1942         if (m_node->isBinaryUseKind(MachineIntUse)) {
1943             Int52Kind kind;
1944             LValue left = lowWhicheverInt52(m_node->child1(), kind);
1945             LValue right = lowInt52(m_node->child2(), kind);
1946             setBoolean(m_out.greaterThan(left, right));
1947             return;
1948         }
1949         
1950         if (m_node->isBinaryUseKind(NumberUse)) {
1951             setBoolean(
1952                 m_out.doubleGreaterThan(
1953                     lowDouble(m_node->child1()), lowDouble(m_node->child2())));
1954             return;
1955         }
1956         
1957         RELEASE_ASSERT_NOT_REACHED();
1958     }
1959     
1960     void compileCompareGreaterEq()
1961     {
1962         if (m_node->isBinaryUseKind(Int32Use)) {
1963             setBoolean(
1964                 m_out.greaterThanOrEqual(
1965                     lowInt32(m_node->child1()), lowInt32(m_node->child2())));
1966             return;
1967         }
1968         
1969         if (m_node->isBinaryUseKind(MachineIntUse)) {
1970             Int52Kind kind;
1971             LValue left = lowWhicheverInt52(m_node->child1(), kind);
1972             LValue right = lowInt52(m_node->child2(), kind);
1973             setBoolean(m_out.greaterThanOrEqual(left, right));
1974             return;
1975         }
1976         
1977         if (m_node->isBinaryUseKind(NumberUse)) {
1978             setBoolean(
1979                 m_out.doubleGreaterThanOrEqual(
1980                     lowDouble(m_node->child1()), lowDouble(m_node->child2())));
1981             return;
1982         }
1983         
1984         RELEASE_ASSERT_NOT_REACHED();
1985     }
1986     
1987     void compileLogicalNot()
1988     {
1989         setBoolean(m_out.bitNot(boolify(m_node->child1())));
1990     }
1991     
1992     void compileCallOrConstruct()
1993     {
1994         // FIXME: This is unacceptably slow.
1995         // https://bugs.webkit.org/show_bug.cgi?id=113621
1996         
1997         J_DFGOperation_E function =
1998             m_node->op() == Call ? operationFTLCall : operationFTLConstruct;
1999         
2000         int dummyThisArgument = m_node->op() == Call ? 0 : 1;
2001         
2002         int numPassedArgs = m_node->numChildren() - 1;
2003         
2004         LValue calleeFrame = m_out.add(
2005             m_callFrame,
2006             m_out.constIntPtr(sizeof(Register) * localToOperand(codeBlock()->m_numCalleeRegisters)));
2007         
2008         m_out.store32(
2009             m_out.constInt32(numPassedArgs + dummyThisArgument),
2010             payloadFor(calleeFrame, JSStack::ArgumentCount));
2011         m_out.store64(m_callFrame, addressFor(calleeFrame, JSStack::CallerFrame));
2012         m_out.store64(
2013             lowJSValue(m_graph.varArgChild(m_node, 0)),
2014             addressFor(calleeFrame, JSStack::Callee));
2015         
2016         for (int i = 0; i < numPassedArgs; ++i) {
2017             m_out.store64(
2018                 lowJSValue(m_graph.varArgChild(m_node, 1 + i)),
2019                 addressFor(calleeFrame, argumentToOperand(i + dummyThisArgument)));
2020         }
2021         
2022         setJSValue(vmCall(m_out.operation(function), calleeFrame));
2023     }
2024     
2025     void compileJump()
2026     {
2027         m_out.jump(lowBlock(m_node->takenBlock()));
2028     }
2029     
2030     void compileBranch()
2031     {
2032         m_out.branch(
2033             boolify(m_node->child1()),
2034             lowBlock(m_node->takenBlock()),
2035             lowBlock(m_node->notTakenBlock()));
2036     }
2037     
2038     void compileSwitch()
2039     {
2040         SwitchData* data = m_node->switchData();
2041         switch (data->kind) {
2042         case SwitchImm: {
2043             Vector<ValueFromBlock, 2> intValues;
2044             LBasicBlock switchOnInts = FTL_NEW_BLOCK(m_out, ("Switch/SwitchImm int case"));
2045             
2046             LBasicBlock lastNext = m_out.appendTo(m_out.m_block, switchOnInts);
2047             
2048             switch (m_node->child1().useKind()) {
2049             case Int32Use: {
2050                 intValues.append(m_out.anchor(lowInt32(m_node->child1())));
2051                 m_out.jump(switchOnInts);
2052                 break;
2053             }
2054                 
2055             case UntypedUse: {
2056                 LBasicBlock isInt = FTL_NEW_BLOCK(m_out, ("Switch/SwitchImm is int"));
2057                 LBasicBlock isNotInt = FTL_NEW_BLOCK(m_out, ("Switch/SwitchImm is not int"));
2058                 LBasicBlock isDouble = FTL_NEW_BLOCK(m_out, ("Switch/SwitchImm is double"));
2059                 
2060                 LValue boxedValue = lowJSValue(m_node->child1());
2061                 m_out.branch(isNotInt32(boxedValue), isNotInt, isInt);
2062                 
2063                 LBasicBlock innerLastNext = m_out.appendTo(isInt, isNotInt);
2064                 
2065                 intValues.append(m_out.anchor(unboxInt32(boxedValue)));
2066                 m_out.jump(switchOnInts);
2067                 
2068                 m_out.appendTo(isNotInt, isDouble);
2069                 m_out.branch(
2070                     isCellOrMisc(boxedValue), lowBlock(data->fallThrough), isDouble);
2071                 
2072                 m_out.appendTo(isDouble, innerLastNext);
2073                 LValue doubleValue = unboxDouble(boxedValue);
2074                 LValue intInDouble = m_out.fpToInt32(doubleValue);
2075                 intValues.append(m_out.anchor(intInDouble));
2076                 m_out.branch(
2077                     m_out.doubleEqual(m_out.intToDouble(intInDouble), doubleValue),
2078                     switchOnInts, lowBlock(data->fallThrough));
2079                 break;
2080             }
2081                 
2082             default:
2083                 RELEASE_ASSERT_NOT_REACHED();
2084                 break;
2085             }
2086             
2087             m_out.appendTo(switchOnInts, lastNext);
2088             buildSwitch(data, m_out.int32, m_out.phi(m_out.int32, intValues));
2089             return;
2090         }
2091         
2092         case SwitchChar: {
2093             LValue stringValue;
2094             
2095             switch (m_node->child1().useKind()) {
2096             case StringUse: {
2097                 stringValue = lowString(m_node->child1());
2098                 break;
2099             }
2100                 
2101             case UntypedUse: {
2102                 LValue unboxedValue = lowJSValue(m_node->child1());
2103                 
2104                 LBasicBlock isCellCase = FTL_NEW_BLOCK(m_out, ("Switch/SwitchChar is cell"));
2105                 LBasicBlock isStringCase = FTL_NEW_BLOCK(m_out, ("Switch/SwitchChar is string"));
2106                 
2107                 m_out.branch(
2108                     isNotCell(unboxedValue), lowBlock(data->fallThrough), isCellCase);
2109                 
2110                 LBasicBlock lastNext = m_out.appendTo(isCellCase, isStringCase);
2111                 LValue cellValue = unboxedValue;
2112                 m_out.branch(isNotString(cellValue), lowBlock(data->fallThrough), isStringCase);
2113                 
2114                 m_out.appendTo(isStringCase, lastNext);
2115                 stringValue = cellValue;
2116                 break;
2117             }
2118                 
2119             default:
2120                 RELEASE_ASSERT_NOT_REACHED();
2121                 break;
2122             }
2123             
2124             LBasicBlock lengthIs1 = FTL_NEW_BLOCK(m_out, ("Switch/SwitchChar length is 1"));
2125             LBasicBlock needResolution = FTL_NEW_BLOCK(m_out, ("Switch/SwitchChar resolution"));
2126             LBasicBlock resolved = FTL_NEW_BLOCK(m_out, ("Switch/SwitchChar resolved"));
2127             LBasicBlock is8Bit = FTL_NEW_BLOCK(m_out, ("Switch/SwitchChar 8bit"));
2128             LBasicBlock is16Bit = FTL_NEW_BLOCK(m_out, ("Switch/SwitchChar 16bit"));
2129             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("Switch/SwitchChar continuation"));
2130             
2131             m_out.branch(
2132                 m_out.notEqual(
2133                     m_out.load32(stringValue, m_heaps.JSString_length),
2134                     m_out.int32One),
2135                 lowBlock(data->fallThrough), lengthIs1);
2136             
2137             LBasicBlock lastNext = m_out.appendTo(lengthIs1, needResolution);
2138             Vector<ValueFromBlock, 2> values;
2139             LValue fastValue = m_out.loadPtr(stringValue, m_heaps.JSString_value);
2140             values.append(m_out.anchor(fastValue));
2141             m_out.branch(m_out.isNull(fastValue), needResolution, resolved);
2142             
2143             m_out.appendTo(needResolution, resolved);
2144             values.append(m_out.anchor(
2145                 vmCall(m_out.operation(operationResolveRope), m_callFrame, stringValue)));
2146             m_out.jump(resolved);
2147             
2148             m_out.appendTo(resolved, is8Bit);
2149             LValue value = m_out.phi(m_out.intPtr, values);
2150             LValue characterData = m_out.loadPtr(value, m_heaps.StringImpl_data);
2151             m_out.branch(
2152                 m_out.testNonZero32(
2153                     m_out.load32(value, m_heaps.StringImpl_hashAndFlags),
2154                     m_out.constInt32(StringImpl::flagIs8Bit())),
2155                 is8Bit, is16Bit);
2156             
2157             Vector<ValueFromBlock, 2> characters;
2158             m_out.appendTo(is8Bit, is16Bit);
2159             characters.append(m_out.anchor(
2160                 m_out.zeroExt(m_out.load8(characterData, m_heaps.characters8[0]), m_out.int16)));
2161             m_out.jump(continuation);
2162             
2163             m_out.appendTo(is16Bit, continuation);
2164             characters.append(m_out.anchor(m_out.load16(characterData, m_heaps.characters16[0])));
2165             m_out.jump(continuation);
2166             
2167             m_out.appendTo(continuation, lastNext);
2168             buildSwitch(data, m_out.int16, m_out.phi(m_out.int16, characters));
2169             return;
2170         }
2171         
2172         case SwitchString:
2173             RELEASE_ASSERT_NOT_REACHED();
2174             break;
2175         }
2176         
2177         RELEASE_ASSERT_NOT_REACHED();
2178     }
2179     
2180     void compileReturn()
2181     {
2182         // FIXME: have a real epilogue when we switch to using our calling convention.
2183         // https://bugs.webkit.org/show_bug.cgi?id=113621
2184         m_out.ret(lowJSValue(m_node->child1()));
2185     }
2186     
2187     void compileForceOSRExit()
2188     {
2189         terminate(InadequateCoverage);
2190     }
2191     
2192     LValue boolify(Edge edge)
2193     {
2194         switch (edge.useKind()) {
2195         case BooleanUse:
2196             return lowBoolean(m_node->child1());
2197         case Int32Use:
2198             return m_out.notZero32(lowInt32(m_node->child1()));
2199         case NumberUse:
2200             return m_out.doubleNotEqual(lowDouble(edge), m_out.doubleZero);
2201         case ObjectOrOtherUse:
2202             return m_out.bitNot(
2203                 equalNullOrUndefined(
2204                     edge, CellCaseSpeculatesObject, SpeculateNullOrUndefined,
2205                     ManualOperandSpeculation));
2206         default:
2207             RELEASE_ASSERT_NOT_REACHED();
2208             return 0;
2209         }
2210     }
2211     
2212     enum StringOrObjectMode {
2213         AllCellsAreFalse,
2214         CellCaseSpeculatesObject
2215     };
2216     enum EqualNullOrUndefinedMode {
2217         EqualNull,
2218         EqualUndefined,
2219         EqualNullOrUndefined,
2220         SpeculateNullOrUndefined
2221     };
2222     LValue equalNullOrUndefined(
2223         Edge edge, StringOrObjectMode cellMode, EqualNullOrUndefinedMode primitiveMode,
2224         OperandSpeculationMode operandMode = AutomaticOperandSpeculation)
2225     {
2226         bool validWatchpoint = masqueradesAsUndefinedWatchpointIfIsStillValid();
2227         
2228         LValue value = lowJSValue(edge, operandMode);
2229         
2230         LBasicBlock cellCase = FTL_NEW_BLOCK(m_out, ("EqualNullOrUndefined cell case"));
2231         LBasicBlock primitiveCase = FTL_NEW_BLOCK(m_out, ("EqualNullOrUndefined primitive case"));
2232         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("EqualNullOrUndefined continuation"));
2233         
2234         m_out.branch(isNotCell(value), primitiveCase, cellCase);
2235         
2236         LBasicBlock lastNext = m_out.appendTo(cellCase, primitiveCase);
2237         
2238         Vector<ValueFromBlock, 3> results;
2239         
2240         switch (cellMode) {
2241         case AllCellsAreFalse:
2242             break;
2243         case CellCaseSpeculatesObject:
2244             FTL_TYPE_CHECK(
2245                 jsValueValue(value), edge, (~SpecCell) | SpecObject,
2246                 m_out.equal(
2247                     m_out.loadPtr(value, m_heaps.JSCell_structure),
2248                     m_out.constIntPtr(vm().stringStructure.get())));
2249             break;
2250         }
2251         
2252         if (validWatchpoint) {
2253             results.append(m_out.anchor(m_out.booleanFalse));
2254             m_out.jump(continuation);
2255         } else {
2256             LBasicBlock masqueradesCase =
2257                 FTL_NEW_BLOCK(m_out, ("EqualNullOrUndefined masquerades case"));
2258                 
2259             LValue structure = m_out.loadPtr(value, m_heaps.JSCell_structure);
2260             
2261             results.append(m_out.anchor(m_out.booleanFalse));
2262             
2263             m_out.branch(
2264                 m_out.testNonZero8(
2265                     m_out.load8(structure, m_heaps.Structure_typeInfoFlags),
2266                     m_out.constInt8(MasqueradesAsUndefined)),
2267                 masqueradesCase, continuation);
2268             
2269             m_out.appendTo(masqueradesCase, primitiveCase);
2270             
2271             results.append(m_out.anchor(
2272                 m_out.equal(
2273                     m_out.constIntPtr(m_graph.globalObjectFor(m_node->codeOrigin)),
2274                     m_out.loadPtr(structure, m_heaps.Structure_globalObject))));
2275             m_out.jump(continuation);
2276         }
2277         
2278         m_out.appendTo(primitiveCase, continuation);
2279         
2280         LValue primitiveResult;
2281         switch (primitiveMode) {
2282         case EqualNull:
2283             primitiveResult = m_out.equal(value, m_out.constInt64(ValueNull));
2284             break;
2285         case EqualUndefined:
2286             primitiveResult = m_out.equal(value, m_out.constInt64(ValueUndefined));
2287             break;
2288         case EqualNullOrUndefined:
2289             primitiveResult = m_out.equal(
2290                 m_out.bitAnd(value, m_out.constInt64(~TagBitUndefined)),
2291                 m_out.constInt64(ValueNull));
2292             break;
2293         case SpeculateNullOrUndefined:
2294             FTL_TYPE_CHECK(
2295                 jsValueValue(value), edge, SpecCell | SpecOther,
2296                 m_out.notEqual(
2297                     m_out.bitAnd(value, m_out.constInt64(~TagBitUndefined)),
2298                     m_out.constInt64(ValueNull)));
2299             primitiveResult = m_out.booleanTrue;
2300             break;
2301         }
2302         results.append(m_out.anchor(primitiveResult));
2303         m_out.jump(continuation);
2304         
2305         m_out.appendTo(continuation, lastNext);
2306         
2307         return m_out.phi(m_out.boolean, results);
2308     }
2309     
2310     template<typename FunctionType>
2311     void contiguousPutByValOutOfBounds(
2312         FunctionType slowPathFunction,
2313         LValue base, LValue storage, LValue index, LValue value,
2314         LBasicBlock continuation)
2315     {
2316         LValue isNotInBounds = m_out.aboveOrEqual(
2317             index, m_out.load32(storage, m_heaps.Butterfly_publicLength));
2318         if (m_node->arrayMode().isInBounds())
2319             speculate(StoreToHoleOrOutOfBounds, noValue(), 0, isNotInBounds);
2320         else {
2321             LBasicBlock notInBoundsCase =
2322                 FTL_NEW_BLOCK(m_out, ("PutByVal not in bounds"));
2323             LBasicBlock performStore =
2324                 FTL_NEW_BLOCK(m_out, ("PutByVal perform store"));
2325                 
2326             m_out.branch(isNotInBounds, notInBoundsCase, performStore);
2327                 
2328             LBasicBlock lastNext = m_out.appendTo(notInBoundsCase, performStore);
2329                 
2330             LValue isOutOfBounds = m_out.aboveOrEqual(
2331                 index, m_out.load32(storage, m_heaps.Butterfly_vectorLength));
2332                 
2333             if (!m_node->arrayMode().isOutOfBounds())
2334                 speculate(OutOfBounds, noValue(), 0, isOutOfBounds);
2335             else {
2336                 LBasicBlock outOfBoundsCase =
2337                     FTL_NEW_BLOCK(m_out, ("PutByVal out of bounds"));
2338                 LBasicBlock holeCase =
2339                     FTL_NEW_BLOCK(m_out, ("PutByVal hole case"));
2340                     
2341                 m_out.branch(isOutOfBounds, outOfBoundsCase, holeCase);
2342                     
2343                 LBasicBlock innerLastNext = m_out.appendTo(outOfBoundsCase, holeCase);
2344                     
2345                 vmCall(
2346                     m_out.operation(slowPathFunction),
2347                     m_callFrame, base, index, value);
2348                     
2349                 m_out.jump(continuation);
2350                     
2351                 m_out.appendTo(holeCase, innerLastNext);
2352             }
2353             
2354             m_out.store32(
2355                 m_out.add(index, m_out.int32One),
2356                 storage, m_heaps.Butterfly_publicLength);
2357                 
2358             m_out.jump(performStore);
2359             m_out.appendTo(performStore, lastNext);
2360         }
2361     }
2362     
2363     void buildSwitch(SwitchData* data, LType type, LValue switchValue)
2364     {
2365         Vector<SwitchCase> cases;
2366         for (unsigned i = 0; i < data->cases.size(); ++i) {
2367             cases.append(SwitchCase(
2368                 constInt(type, data->cases[i].value.switchLookupValue()),
2369                 lowBlock(data->cases[i].target)));
2370         }
2371         
2372         m_out.switchInstruction(switchValue, cases, lowBlock(data->fallThrough));
2373     }
2374     
2375     LValue doubleToInt32(LValue doubleValue, double low, double high, bool isSigned = true)
2376     {
2377         // FIXME: Optimize double-to-int conversions.
2378         // <rdar://problem/14938465>
2379         
2380         LBasicBlock greatEnough = FTL_NEW_BLOCK(m_out, ("doubleToInt32 greatEnough"));
2381         LBasicBlock withinRange = FTL_NEW_BLOCK(m_out, ("doubleToInt32 withinRange"));
2382         LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("doubleToInt32 slowPath"));
2383         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("doubleToInt32 continuation"));
2384         
2385         Vector<ValueFromBlock, 2> results;
2386         
2387         m_out.branch(
2388             m_out.greaterThanOrEqual(doubleValue, m_out.constDouble(low)),
2389             greatEnough, slowPath);
2390         
2391         LBasicBlock lastNext = m_out.appendTo(greatEnough, withinRange);
2392         m_out.branch(
2393             m_out.lessThanOrEqual(doubleValue, m_out.constDouble(high)),
2394             withinRange, slowPath);
2395         
2396         m_out.appendTo(withinRange, slowPath);
2397         LValue fastResult;
2398         if (isSigned)
2399             fastResult = m_out.fpToInt32(doubleValue);
2400         else
2401             fastResult = m_out.fpToUInt32(doubleValue);
2402         results.append(m_out.anchor(fastResult));
2403         m_out.jump(continuation);
2404         
2405         m_out.appendTo(slowPath, continuation);
2406         results.append(m_out.anchor(m_out.call(m_out.operation(toInt32), doubleValue)));
2407         m_out.jump(continuation);
2408         
2409         m_out.appendTo(continuation, lastNext);
2410         return m_out.phi(m_out.int32, results);
2411     }
2412     
2413     LValue doubleToInt32(LValue doubleValue)
2414     {
2415         double limit = pow(2, 31) - 1;
2416         return doubleToInt32(doubleValue, -limit, limit);
2417     }
2418     
2419     LValue doubleToUInt32(LValue doubleValue)
2420     {
2421         return doubleToInt32(doubleValue, 0, pow(2, 32) - 1, false);
2422     }
2423     
2424     void speculateBackward(
2425         ExitKind kind, FormattedValue lowValue, Node* highValue, LValue failCondition)
2426     {
2427         appendOSRExit(
2428             kind, lowValue, highValue, failCondition, BackwardSpeculation, FormattedValue());
2429     }
2430     
2431     void speculateForward(
2432         ExitKind kind, FormattedValue lowValue, Node* highValue, LValue failCondition,
2433         const FormattedValue& recovery)
2434     {
2435         appendOSRExit(
2436             kind, lowValue, highValue, failCondition, ForwardSpeculation, recovery);
2437     }
2438     
2439     void speculate(
2440         ExitKind kind, FormattedValue lowValue, Node* highValue, LValue failCondition)
2441     {
2442         appendOSRExit(
2443             kind, lowValue, highValue, failCondition, m_direction, FormattedValue());
2444     }
2445     
2446     void terminate(ExitKind kind)
2447     {
2448         speculate(kind, noValue(), 0, m_out.booleanTrue);
2449     }
2450     
2451     void backwardTypeCheck(
2452         FormattedValue lowValue, Edge highValue, SpeculatedType typesPassedThrough,
2453         LValue failCondition)
2454     {
2455         appendTypeCheck(
2456             lowValue, highValue, typesPassedThrough, failCondition, BackwardSpeculation,
2457             FormattedValue());
2458     }
2459     
2460     void forwardTypeCheck(
2461         FormattedValue lowValue, Edge highValue, SpeculatedType typesPassedThrough,
2462         LValue failCondition)
2463     {
2464         appendTypeCheck(
2465             lowValue, highValue, typesPassedThrough, failCondition, ForwardSpeculation,
2466             FormattedValue());
2467     }
2468     
2469     void typeCheck(
2470         FormattedValue lowValue, Edge highValue, SpeculatedType typesPassedThrough,
2471         LValue failCondition)
2472     {
2473         appendTypeCheck(
2474             lowValue, highValue, typesPassedThrough, failCondition, m_direction,
2475             FormattedValue());
2476     }
2477     
2478     void appendTypeCheck(
2479         FormattedValue lowValue, Edge highValue, SpeculatedType typesPassedThrough,
2480         LValue failCondition, SpeculationDirection direction, FormattedValue recovery)
2481     {
2482         if (!m_interpreter.needsTypeCheck(highValue, typesPassedThrough))
2483             return;
2484         ASSERT(mayHaveTypeCheck(highValue.useKind()));
2485         appendOSRExit(BadType, lowValue, highValue.node(), failCondition, direction, recovery);
2486         m_interpreter.filter(highValue, typesPassedThrough);
2487     }
2488     
2489     LValue lowInt32(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
2490     {
2491         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || (edge.useKind() == Int32Use || edge.useKind() == KnownInt32Use));
2492         
2493         if (edge->hasConstant()) {
2494             JSValue value = m_graph.valueOfJSConstant(edge.node());
2495             if (!value.isInt32()) {
2496                 terminate(Uncountable);
2497                 return m_out.int32Zero;
2498             }
2499             return m_out.constInt32(value.asInt32());
2500         }
2501         
2502         LoweredNodeValue value = m_int32Values.get(edge.node());
2503         if (isValid(value))
2504             return value.value();
2505         
2506         value = m_strictInt52Values.get(edge.node());
2507         if (isValid(value))
2508             return strictInt52ToInt32(edge, value.value());
2509         
2510         value = m_int52Values.get(edge.node());
2511         if (isValid(value))
2512             return strictInt52ToInt32(edge, int52ToStrictInt52(value.value()));
2513         
2514         value = m_jsValueValues.get(edge.node());
2515         if (isValid(value)) {
2516             LValue boxedResult = value.value();
2517             FTL_TYPE_CHECK(
2518                 jsValueValue(boxedResult), edge, SpecInt32, isNotInt32(boxedResult));
2519             LValue result = unboxInt32(boxedResult);
2520             setInt32(edge.node(), result);
2521             return result;
2522         }
2523
2524         RELEASE_ASSERT(!(m_state.forNode(edge).m_type & SpecInt32));
2525         terminate(Uncountable);
2526         return m_out.int32Zero;
2527     }
2528     
2529     enum Int52Kind { StrictInt52, Int52 };
2530     LValue lowInt52(Edge edge, Int52Kind kind, OperandSpeculationMode mode = AutomaticOperandSpeculation)
2531     {
2532         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == MachineIntUse);
2533         
2534         if (edge->hasConstant()) {
2535             JSValue value = m_graph.valueOfJSConstant(edge.node());
2536             if (!value.isMachineInt()) {
2537                 terminate(Uncountable);
2538                 return m_out.int64Zero;
2539             }
2540             int64_t result = value.asMachineInt();
2541             if (kind == Int52)
2542                 result <<= JSValue::int52ShiftAmount;
2543             return m_out.constInt64(result);
2544         }
2545         
2546         LoweredNodeValue value;
2547         
2548         switch (kind) {
2549         case Int52:
2550             value = m_int52Values.get(edge.node());
2551             if (isValid(value))
2552                 return value.value();
2553             
2554             value = m_strictInt52Values.get(edge.node());
2555             if (isValid(value))
2556                 return strictInt52ToInt52(value.value());
2557             break;
2558             
2559         case StrictInt52:
2560             value = m_strictInt52Values.get(edge.node());
2561             if (isValid(value))
2562                 return value.value();
2563             
2564             value = m_int52Values.get(edge.node());
2565             if (isValid(value))
2566                 return int52ToStrictInt52(value.value());
2567             break;
2568         }
2569         
2570         value = m_int32Values.get(edge.node());
2571         if (isValid(value)) {
2572             return setInt52WithStrictValue(
2573                 edge.node(), m_out.signExt(value.value(), m_out.int64), kind);
2574         }
2575         
2576         RELEASE_ASSERT(!(m_state.forNode(edge).m_type & SpecInt52));
2577         
2578         value = m_jsValueValues.get(edge.node());
2579         if (isValid(value)) {
2580             LValue boxedResult = value.value();
2581             FTL_TYPE_CHECK(
2582                 jsValueValue(boxedResult), edge, SpecMachineInt, isNotInt32(boxedResult));
2583             return setInt52WithStrictValue(
2584                 edge.node(), m_out.signExt(unboxInt32(boxedResult), m_out.int64), kind);
2585         }
2586         
2587         RELEASE_ASSERT(!(m_state.forNode(edge).m_type & SpecMachineInt));
2588         terminate(Uncountable);
2589         return m_out.int64Zero;
2590     }
2591     
2592     LValue lowInt52(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
2593     {
2594         return lowInt52(edge, Int52, mode);
2595     }
2596     
2597     LValue lowStrictInt52(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
2598     {
2599         return lowInt52(edge, StrictInt52, mode);
2600     }
2601     
2602     bool betterUseStrictInt52(Node* node)
2603     {
2604         return !isValid(m_int52Values.get(node));
2605     }
2606     bool betterUseStrictInt52(Edge edge)
2607     {
2608         return betterUseStrictInt52(edge.node());
2609     }
2610     template<typename T>
2611     Int52Kind bestInt52Kind(T node)
2612     {
2613         return betterUseStrictInt52(node) ? StrictInt52 : Int52;
2614     }
2615     Int52Kind opposite(Int52Kind kind)
2616     {
2617         switch (kind) {
2618         case Int52:
2619             return StrictInt52;
2620         case StrictInt52:
2621             return Int52;
2622         }
2623         RELEASE_ASSERT_NOT_REACHED();
2624     }
2625     
2626     LValue lowWhicheverInt52(Edge edge, Int52Kind& kind, OperandSpeculationMode mode = AutomaticOperandSpeculation)
2627     {
2628         kind = bestInt52Kind(edge);
2629         return lowInt52(edge, kind, mode);
2630     }
2631     
2632     LValue lowCell(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
2633     {
2634         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || isCell(edge.useKind()));
2635         
2636         if (edge->op() == JSConstant) {
2637             JSValue value = m_graph.valueOfJSConstant(edge.node());
2638             if (!value.isCell()) {
2639                 terminate(Uncountable);
2640                 return m_out.intPtrZero;
2641             }
2642             return m_out.constIntPtr(value.asCell());
2643         }
2644         
2645         LoweredNodeValue value = m_jsValueValues.get(edge.node());
2646         if (isValid(value)) {
2647             LValue uncheckedValue = value.value();
2648             FTL_TYPE_CHECK(
2649                 jsValueValue(uncheckedValue), edge, SpecCell, isNotCell(uncheckedValue));
2650             return uncheckedValue;
2651         }
2652         
2653         RELEASE_ASSERT(!(m_state.forNode(edge).m_type & SpecCell));
2654         terminate(Uncountable);
2655         return m_out.intPtrZero;
2656     }
2657     
2658     LValue lowObject(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
2659     {
2660         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == ObjectUse);
2661         
2662         LValue result = lowCell(edge, mode);
2663         speculateObject(edge, result);
2664         return result;
2665     }
2666     
2667     LValue lowString(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
2668     {
2669         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == StringUse || edge.useKind() == KnownStringUse);
2670         
2671         LValue result = lowCell(edge, mode);
2672         speculateString(edge, result);
2673         return result;
2674     }
2675     
2676     LValue lowNonNullObject(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
2677     {
2678         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == ObjectUse);
2679         
2680         LValue result = lowCell(edge, mode);
2681         speculateNonNullObject(edge, result);
2682         return result;
2683     }
2684     
2685     LValue lowBoolean(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
2686     {
2687         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == BooleanUse);
2688         
2689         if (edge->hasConstant()) {
2690             JSValue value = m_graph.valueOfJSConstant(edge.node());
2691             if (!value.isBoolean()) {
2692                 terminate(Uncountable);
2693                 return m_out.booleanFalse;
2694             }
2695             return m_out.constBool(value.asBoolean());
2696         }
2697         
2698         LoweredNodeValue value = m_booleanValues.get(edge.node());
2699         if (isValid(value))
2700             return value.value();
2701         
2702         value = m_jsValueValues.get(edge.node());
2703         if (isValid(value)) {
2704             LValue unboxedResult = value.value();
2705             FTL_TYPE_CHECK(
2706                 jsValueValue(unboxedResult), edge, SpecBoolean, isNotBoolean(unboxedResult));
2707             LValue result = unboxBoolean(unboxedResult);
2708             setBoolean(edge.node(), result);
2709             return result;
2710         }
2711         
2712         RELEASE_ASSERT(!(m_state.forNode(edge).m_type & SpecBoolean));
2713         terminate(Uncountable);
2714         return m_out.booleanFalse;
2715     }
2716     
2717     LValue lowDouble(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
2718     {
2719         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || isDouble(edge.useKind()));
2720         
2721         if (edge->hasConstant()) {
2722             JSValue value = m_graph.valueOfJSConstant(edge.node());
2723             if (!value.isNumber()) {
2724                 terminate(Uncountable);
2725                 return m_out.doubleZero;
2726             }
2727             return m_out.constDouble(value.asNumber());
2728         }
2729         
2730         LoweredNodeValue value = m_doubleValues.get(edge.node());
2731         if (isValid(value))
2732             return value.value();
2733         
2734         value = m_int32Values.get(edge.node());
2735         if (isValid(value)) {
2736             LValue result = m_out.intToDouble(value.value());
2737             setDouble(edge.node(), result);
2738             return result;
2739         }
2740         
2741         value = m_strictInt52Values.get(edge.node());
2742         if (isValid(value))
2743             return strictInt52ToDouble(edge, value.value());
2744         
2745         value = m_int52Values.get(edge.node());
2746         if (isValid(value))
2747             return strictInt52ToDouble(edge, int52ToStrictInt52(value.value()));
2748         
2749         value = m_jsValueValues.get(edge.node());
2750         if (isValid(value)) {
2751             LValue boxedResult = value.value();
2752             
2753             LBasicBlock intCase = FTL_NEW_BLOCK(m_out, ("Double unboxing int case"));
2754             LBasicBlock doubleCase = FTL_NEW_BLOCK(m_out, ("Double unboxing double case"));
2755             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("Double unboxing continuation"));
2756             
2757             m_out.branch(isNotInt32(boxedResult), doubleCase, intCase);
2758             
2759             LBasicBlock lastNext = m_out.appendTo(intCase, doubleCase);
2760             
2761             ValueFromBlock intToDouble = m_out.anchor(
2762                 m_out.intToDouble(unboxInt32(boxedResult)));
2763             m_out.jump(continuation);
2764             
2765             m_out.appendTo(doubleCase, continuation);
2766             
2767             FTL_TYPE_CHECK(
2768                 jsValueValue(boxedResult), edge, SpecFullNumber, isCellOrMisc(boxedResult));
2769             
2770             ValueFromBlock unboxedDouble = m_out.anchor(unboxDouble(boxedResult));
2771             m_out.jump(continuation);
2772             
2773             m_out.appendTo(continuation, lastNext);
2774             
2775             LValue result = m_out.phi(m_out.doubleType, intToDouble, unboxedDouble);
2776             
2777             setDouble(edge.node(), result);
2778             return result;
2779         }
2780         
2781         RELEASE_ASSERT(!(m_state.forNode(edge).m_type & SpecFullNumber));
2782         terminate(Uncountable);
2783         return m_out.doubleZero;
2784     }
2785     
2786     LValue lowJSValue(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
2787     {
2788         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == UntypedUse);
2789         
2790         if (edge->hasConstant())
2791             return m_out.constInt64(JSValue::encode(m_graph.valueOfJSConstant(edge.node())));
2792         
2793         LoweredNodeValue value = m_jsValueValues.get(edge.node());
2794         if (isValid(value))
2795             return value.value();
2796         
2797         value = m_int32Values.get(edge.node());
2798         if (isValid(value)) {
2799             LValue result = boxInt32(value.value());
2800             setJSValue(edge.node(), result);
2801             return result;
2802         }
2803         
2804         value = m_strictInt52Values.get(edge.node());
2805         if (isValid(value))
2806             return strictInt52ToJSValue(value.value());
2807         
2808         value = m_int52Values.get(edge.node());
2809         if (isValid(value))
2810             return strictInt52ToJSValue(int52ToStrictInt52(value.value()));
2811         
2812         value = m_booleanValues.get(edge.node());
2813         if (isValid(value)) {
2814             LValue result = boxBoolean(value.value());
2815             setJSValue(edge.node(), result);
2816             return result;
2817         }
2818         
2819         value = m_doubleValues.get(edge.node());
2820         if (isValid(value)) {
2821             LValue result = boxDouble(value.value());
2822             setJSValue(edge.node(), result);
2823             return result;
2824         }
2825         
2826         RELEASE_ASSERT_NOT_REACHED();
2827         return 0;
2828     }
2829     
2830     LValue lowStorage(Edge edge)
2831     {
2832         LoweredNodeValue value = m_storageValues.get(edge.node());
2833         if (isValid(value))
2834             return value.value();
2835         
2836         LValue result = lowCell(edge);
2837         setStorage(edge.node(), result);
2838         return result;
2839     }
2840     
2841     LValue strictInt52ToInt32(Edge edge, LValue value)
2842     {
2843         LValue result = m_out.castToInt32(value);
2844         FTL_TYPE_CHECK(
2845             noValue(), edge, SpecInt32,
2846             m_out.notEqual(m_out.signExt(result, m_out.int64), value));
2847         setInt32(edge.node(), result);
2848         return result;
2849     }
2850     
2851     LValue strictInt52ToDouble(Edge edge, LValue value)
2852     {
2853         LValue result = m_out.intToDouble(value);
2854         setDouble(edge.node(), result);
2855         return result;
2856     }
2857     
2858     LValue strictInt52ToJSValue(LValue value)
2859     {
2860         LBasicBlock isInt32 = FTL_NEW_BLOCK(m_out, ("strictInt52ToJSValue isInt32 case"));
2861         LBasicBlock isDouble = FTL_NEW_BLOCK(m_out, ("strictInt52ToJSValue isDouble case"));
2862         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("strictInt52ToJSValue continuation"));
2863         
2864         Vector<ValueFromBlock, 2> results;
2865             
2866         LValue int32Value = m_out.castToInt32(value);
2867         m_out.branch(
2868             m_out.equal(m_out.signExt(int32Value, m_out.int64), value),
2869             isInt32, isDouble);
2870         
2871         LBasicBlock lastNext = m_out.appendTo(isInt32, isDouble);
2872         
2873         results.append(m_out.anchor(boxInt32(int32Value)));
2874         m_out.jump(continuation);
2875         
2876         m_out.appendTo(isDouble, continuation);
2877         
2878         results.append(m_out.anchor(boxDouble(m_out.intToDouble(value))));
2879         m_out.jump(continuation);
2880         
2881         m_out.appendTo(continuation, lastNext);
2882         return m_out.phi(m_out.int64, results);
2883     }
2884     
2885     LValue setInt52WithStrictValue(Node* node, LValue value, Int52Kind kind)
2886     {
2887         switch (kind) {
2888         case StrictInt52:
2889             setStrictInt52(node, value);
2890             return value;
2891             
2892         case Int52:
2893             value = strictInt52ToInt52(value);
2894             setInt52(node, value);
2895             return value;
2896         }
2897         
2898         RELEASE_ASSERT_NOT_REACHED();
2899         return 0;
2900     }
2901
2902     LValue strictInt52ToInt52(LValue value)
2903     {
2904         return m_out.shl(value, m_out.constInt64(JSValue::int52ShiftAmount));
2905     }
2906     
2907     LValue int52ToStrictInt52(LValue value)
2908     {
2909         return m_out.aShr(value, m_out.constInt64(JSValue::int52ShiftAmount));
2910     }
2911     
2912     LValue isNotInt32(LValue jsValue)
2913     {
2914         return m_out.below(jsValue, m_tagTypeNumber);
2915     }
2916     LValue unboxInt32(LValue jsValue)
2917     {
2918         return m_out.castToInt32(jsValue);
2919     }
2920     LValue boxInt32(LValue value)
2921     {
2922         return m_out.add(m_out.zeroExt(value, m_out.int64), m_tagTypeNumber);
2923     }
2924     
2925     LValue isCellOrMisc(LValue jsValue)
2926     {
2927         return m_out.testIsZero64(jsValue, m_tagTypeNumber);
2928     }
2929     LValue unboxDouble(LValue jsValue)
2930     {
2931         return m_out.bitCast(m_out.add(jsValue, m_tagTypeNumber), m_out.doubleType);
2932     }
2933     LValue boxDouble(LValue doubleValue)
2934     {
2935         return m_out.sub(m_out.bitCast(doubleValue, m_out.int64), m_tagTypeNumber);
2936     }
2937     
2938     LValue isNotCell(LValue jsValue)
2939     {
2940         return m_out.testNonZero64(jsValue, m_tagMask);
2941     }
2942     
2943     LValue isNotBoolean(LValue jsValue)
2944     {
2945         return m_out.testNonZero64(
2946             m_out.bitXor(jsValue, m_out.constInt64(ValueFalse)),
2947             m_out.constInt64(~1));
2948     }
2949     LValue unboxBoolean(LValue jsValue)
2950     {
2951         // We want to use a cast that guarantees that LLVM knows that even the integer
2952         // value is just 0 or 1. But for now we do it the dumb way.
2953         return m_out.notZero64(m_out.bitAnd(jsValue, m_out.constInt64(1)));
2954     }
2955     LValue boxBoolean(LValue value)
2956     {
2957         return m_out.select(
2958             value, m_out.constInt64(ValueTrue), m_out.constInt64(ValueFalse));
2959     }
2960
2961     void speculate(Edge edge)
2962     {
2963         switch (edge.useKind()) {
2964         case UntypedUse:
2965             break;
2966         case KnownInt32Use:
2967         case KnownNumberUse:
2968             ASSERT(!m_interpreter.needsTypeCheck(edge));
2969             break;
2970         case Int32Use:
2971             speculateInt32(edge);
2972             break;
2973         case CellUse:
2974             speculateCell(edge);
2975             break;
2976         case KnownCellUse:
2977             ASSERT(!m_interpreter.needsTypeCheck(edge));
2978             break;
2979         case ObjectUse:
2980             speculateObject(edge);
2981             break;
2982         case ObjectOrOtherUse:
2983             speculateObjectOrOther(edge);
2984             break;
2985         case StringUse:
2986             speculateString(edge);
2987             break;
2988         case RealNumberUse:
2989             speculateRealNumber(edge);
2990             break;
2991         case NumberUse:
2992             speculateNumber(edge);
2993             break;
2994         case BooleanUse:
2995             speculateBoolean(edge);
2996             break;
2997         default:
2998             dataLog("Unsupported speculation use kind: ", edge.useKind(), "\n");
2999             RELEASE_ASSERT_NOT_REACHED();
3000         }
3001     }
3002     
3003     void speculate(Node*, Edge edge)
3004     {
3005         speculate(edge);
3006     }
3007     
3008     void speculateInt32(Edge edge)
3009     {
3010         lowInt32(edge);
3011     }
3012     
3013     void speculateCell(Edge edge)
3014     {
3015         lowCell(edge);
3016     }
3017     
3018     LValue isObject(LValue cell)
3019     {
3020         return m_out.notEqual(
3021             m_out.loadPtr(cell, m_heaps.JSCell_structure),
3022             m_out.constIntPtr(vm().stringStructure.get()));
3023     }
3024     
3025     LValue isNotString(LValue cell)
3026     {
3027         return isObject(cell);
3028     }
3029     
3030     LValue isString(LValue cell)
3031     {
3032         return m_out.equal(
3033             m_out.loadPtr(cell, m_heaps.JSCell_structure),
3034             m_out.constIntPtr(vm().stringStructure.get()));
3035     }
3036     
3037     LValue isNotObject(LValue cell)
3038     {
3039         return isString(cell);
3040     }
3041     
3042     LValue isArrayType(LValue cell, ArrayMode arrayMode)
3043     {
3044         switch (arrayMode.type()) {
3045         case Array::Int32:
3046         case Array::Double:
3047         case Array::Contiguous: {
3048             LValue indexingType = m_out.load8(
3049                 m_out.loadPtr(cell, m_heaps.JSCell_structure),
3050                 m_heaps.Structure_indexingType);
3051             
3052             switch (arrayMode.arrayClass()) {
3053             case Array::OriginalArray:
3054                 RELEASE_ASSERT_NOT_REACHED();
3055                 return 0;
3056                 
3057             case Array::Array:
3058                 return m_out.equal(
3059                     m_out.bitAnd(indexingType, m_out.constInt8(IsArray | IndexingShapeMask)),
3060                     m_out.constInt8(IsArray | arrayMode.shapeMask()));
3061                 
3062             default:
3063                 return m_out.equal(
3064                     m_out.bitAnd(indexingType, m_out.constInt8(IndexingShapeMask)),
3065                     m_out.constInt8(arrayMode.shapeMask()));
3066             }
3067         }
3068             
3069         default:
3070             return hasClassInfo(cell, classInfoForType(arrayMode.typedArrayType()));
3071         }
3072     }
3073     
3074     LValue hasClassInfo(LValue cell, const ClassInfo* classInfo)
3075     {
3076         return m_out.equal(
3077             m_out.loadPtr(
3078                 m_out.loadPtr(cell, m_heaps.JSCell_structure),
3079                 m_heaps.Structure_classInfo),
3080             m_out.constIntPtr(classInfo));
3081     }
3082     
3083     void speculateObject(Edge edge, LValue cell)
3084     {
3085         FTL_TYPE_CHECK(jsValueValue(cell), edge, SpecObject, isNotObject(cell));
3086     }
3087     
3088     void speculateObject(Edge edge)
3089     {
3090         speculateObject(edge, lowCell(edge));
3091     }
3092     
3093     void speculateObjectOrOther(Edge edge)
3094     {
3095         if (!m_interpreter.needsTypeCheck(edge))
3096             return;
3097         
3098         LValue value = lowJSValue(edge);
3099         
3100         LBasicBlock cellCase = FTL_NEW_BLOCK(m_out, ("speculateObjectOrOther cell case"));
3101         LBasicBlock primitiveCase = FTL_NEW_BLOCK(m_out, ("speculateObjectOrOther primitive case"));
3102         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("speculateObjectOrOther continuation"));
3103         
3104         m_out.branch(isNotCell(value), primitiveCase, cellCase);
3105         
3106         LBasicBlock lastNext = m_out.appendTo(cellCase, primitiveCase);
3107         
3108         FTL_TYPE_CHECK(
3109             jsValueValue(value), edge, (~SpecCell) | SpecObject,
3110             m_out.equal(
3111                 m_out.loadPtr(value, m_heaps.JSCell_structure),
3112                 m_out.constIntPtr(vm().stringStructure.get())));
3113         
3114         m_out.jump(continuation);
3115         
3116         m_out.appendTo(primitiveCase, continuation);
3117         
3118         FTL_TYPE_CHECK(
3119             jsValueValue(value), edge, SpecCell | SpecOther,
3120             m_out.notEqual(
3121                 m_out.bitAnd(value, m_out.constInt64(~TagBitUndefined)),
3122                 m_out.constInt64(ValueNull)));
3123