FTL should be able to run everything in Octane/regexp
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGNode.h
1 /*
2  * Copyright (C) 2011-2015 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 #ifndef DFGNode_h
27 #define DFGNode_h
28
29 #if ENABLE(DFG_JIT)
30
31 #include "BasicBlockLocation.h"
32 #include "CodeBlock.h"
33 #include "DFGAbstractValue.h"
34 #include "DFGAdjacencyList.h"
35 #include "DFGArithMode.h"
36 #include "DFGArrayMode.h"
37 #include "DFGCommon.h"
38 #include "DFGEpoch.h"
39 #include "DFGLazyJSValue.h"
40 #include "DFGMultiGetByOffsetData.h"
41 #include "DFGNodeFlags.h"
42 #include "DFGNodeOrigin.h"
43 #include "DFGNodeType.h"
44 #include "DFGObjectMaterializationData.h"
45 #include "DFGTransition.h"
46 #include "DFGUseKind.h"
47 #include "DFGVariableAccessData.h"
48 #include "GetByIdVariant.h"
49 #include "JSCJSValue.h"
50 #include "Operands.h"
51 #include "PutByIdVariant.h"
52 #include "SpeculatedType.h"
53 #include "StructureSet.h"
54 #include "TypeLocation.h"
55 #include "ValueProfile.h"
56 #include <wtf/ListDump.h>
57
58 namespace JSC { namespace DFG {
59
60 class Graph;
61 class PromotedLocationDescriptor;
62 struct BasicBlock;
63
64 struct StorageAccessData {
65     PropertyOffset offset;
66     unsigned identifierNumber;
67
68     // This needs to know the inferred type. For puts, this is necessary because we need to remember
69     // what check is needed. For gets, this is necessary because otherwise AI might forget what type is
70     // guaranteed.
71     InferredType::Descriptor inferredType;
72 };
73
74 struct MultiPutByOffsetData {
75     unsigned identifierNumber;
76     Vector<PutByIdVariant, 2> variants;
77     
78     bool writesStructures() const;
79     bool reallocatesStorage() const;
80 };
81
82 struct NewArrayBufferData {
83     unsigned startConstant;
84     unsigned numConstants;
85     IndexingType indexingType;
86 };
87
88 struct BranchTarget {
89     BranchTarget()
90         : block(0)
91         , count(PNaN)
92     {
93     }
94     
95     explicit BranchTarget(BasicBlock* block)
96         : block(block)
97         , count(PNaN)
98     {
99     }
100     
101     void setBytecodeIndex(unsigned bytecodeIndex)
102     {
103         block = bitwise_cast<BasicBlock*>(static_cast<uintptr_t>(bytecodeIndex));
104     }
105     unsigned bytecodeIndex() const { return bitwise_cast<uintptr_t>(block); }
106     
107     void dump(PrintStream&) const;
108     
109     BasicBlock* block;
110     float count;
111 };
112
113 struct BranchData {
114     static BranchData withBytecodeIndices(
115         unsigned takenBytecodeIndex, unsigned notTakenBytecodeIndex)
116     {
117         BranchData result;
118         result.taken.block = bitwise_cast<BasicBlock*>(static_cast<uintptr_t>(takenBytecodeIndex));
119         result.notTaken.block = bitwise_cast<BasicBlock*>(static_cast<uintptr_t>(notTakenBytecodeIndex));
120         return result;
121     }
122     
123     unsigned takenBytecodeIndex() const { return taken.bytecodeIndex(); }
124     unsigned notTakenBytecodeIndex() const { return notTaken.bytecodeIndex(); }
125     
126     BasicBlock*& forCondition(bool condition)
127     {
128         if (condition)
129             return taken.block;
130         return notTaken.block;
131     }
132     
133     BranchTarget taken;
134     BranchTarget notTaken;
135 };
136
137 // The SwitchData and associated data structures duplicate the information in
138 // JumpTable. The DFG may ultimately end up using the JumpTable, though it may
139 // instead decide to do something different - this is entirely up to the DFG.
140 // These data structures give the DFG a higher-level semantic description of
141 // what is going on, which will allow it to make the right decision.
142 //
143 // Note that there will never be multiple SwitchCases in SwitchData::cases that
144 // have the same SwitchCase::value, since the bytecode's JumpTables never have
145 // duplicates - since the JumpTable maps a value to a target. It's a
146 // one-to-many mapping. So we may have duplicate targets, but never duplicate
147 // values.
148 struct SwitchCase {
149     SwitchCase()
150     {
151     }
152     
153     SwitchCase(LazyJSValue value, BasicBlock* target)
154         : value(value)
155         , target(target)
156     {
157     }
158     
159     static SwitchCase withBytecodeIndex(LazyJSValue value, unsigned bytecodeIndex)
160     {
161         SwitchCase result;
162         result.value = value;
163         result.target.setBytecodeIndex(bytecodeIndex);
164         return result;
165     }
166     
167     LazyJSValue value;
168     BranchTarget target;
169 };
170
171 struct SwitchData {
172     // Initializes most fields to obviously invalid values. Anyone
173     // constructing this should make sure to initialize everything they
174     // care about manually.
175     SwitchData()
176         : kind(static_cast<SwitchKind>(-1))
177         , switchTableIndex(UINT_MAX)
178         , didUseJumpTable(false)
179     {
180     }
181     
182     Vector<SwitchCase> cases;
183     BranchTarget fallThrough;
184     SwitchKind kind;
185     unsigned switchTableIndex;
186     bool didUseJumpTable;
187 };
188
189 struct CallVarargsData {
190     int firstVarArgOffset;
191 };
192
193 struct LoadVarargsData {
194     VirtualRegister start; // Local for the first element. This is the first actual argument, not this.
195     VirtualRegister count; // Local for the count.
196     VirtualRegister machineStart;
197     VirtualRegister machineCount;
198     unsigned offset; // Which array element to start with. Usually this is 0.
199     unsigned mandatoryMinimum; // The number of elements on the stack that must be initialized; if the array is too short then the missing elements must get undefined. Does not include "this".
200     unsigned limit; // Maximum number of elements to load. Includes "this".
201 };
202
203 struct StackAccessData {
204     StackAccessData()
205         : format(DeadFlush)
206     {
207     }
208     
209     StackAccessData(VirtualRegister local, FlushFormat format)
210         : local(local)
211         , format(format)
212     {
213     }
214     
215     VirtualRegister local;
216     VirtualRegister machineLocal;
217     FlushFormat format;
218     
219     FlushedAt flushedAt() { return FlushedAt(format, machineLocal); }
220 };
221
222 // This type used in passing an immediate argument to Node constructor;
223 // distinguishes an immediate value (typically an index into a CodeBlock data structure - 
224 // a constant index, argument, or identifier) from a Node*.
225 struct OpInfo {
226     OpInfo() : m_value(0) { }
227     explicit OpInfo(int32_t value) : m_value(static_cast<uintptr_t>(value)) { }
228     explicit OpInfo(uint32_t value) : m_value(static_cast<uintptr_t>(value)) { }
229 #if OS(DARWIN) || USE(JSVALUE64)
230     explicit OpInfo(size_t value) : m_value(static_cast<uintptr_t>(value)) { }
231 #endif
232     explicit OpInfo(void* value) : m_value(reinterpret_cast<uintptr_t>(value)) { }
233     uintptr_t m_value;
234 };
235
236 // === Node ===
237 //
238 // Node represents a single operation in the data flow graph.
239 struct Node {
240     enum VarArgTag { VarArg };
241     
242     Node() { }
243     
244     Node(NodeType op, NodeOrigin nodeOrigin, const AdjacencyList& children)
245         : origin(nodeOrigin)
246         , children(children)
247         , m_virtualRegister(VirtualRegister())
248         , m_refCount(1)
249         , m_prediction(SpecNone)
250         , owner(nullptr)
251     {
252         m_misc.replacement = nullptr;
253         setOpAndDefaultFlags(op);
254     }
255     
256     // Construct a node with up to 3 children, no immediate value.
257     Node(NodeType op, NodeOrigin nodeOrigin, Edge child1 = Edge(), Edge child2 = Edge(), Edge child3 = Edge())
258         : origin(nodeOrigin)
259         , children(AdjacencyList::Fixed, child1, child2, child3)
260         , m_virtualRegister(VirtualRegister())
261         , m_refCount(1)
262         , m_prediction(SpecNone)
263         , m_opInfo(0)
264         , m_opInfo2(0)
265         , owner(nullptr)
266     {
267         m_misc.replacement = nullptr;
268         setOpAndDefaultFlags(op);
269         ASSERT(!(m_flags & NodeHasVarArgs));
270     }
271
272     // Construct a node with up to 3 children, no immediate value.
273     Node(NodeFlags result, NodeType op, NodeOrigin nodeOrigin, Edge child1 = Edge(), Edge child2 = Edge(), Edge child3 = Edge())
274         : origin(nodeOrigin)
275         , children(AdjacencyList::Fixed, child1, child2, child3)
276         , m_virtualRegister(VirtualRegister())
277         , m_refCount(1)
278         , m_prediction(SpecNone)
279         , m_opInfo(0)
280         , m_opInfo2(0)
281         , owner(nullptr)
282     {
283         m_misc.replacement = nullptr;
284         setOpAndDefaultFlags(op);
285         setResult(result);
286         ASSERT(!(m_flags & NodeHasVarArgs));
287     }
288
289     // Construct a node with up to 3 children and an immediate value.
290     Node(NodeType op, NodeOrigin nodeOrigin, OpInfo imm, Edge child1 = Edge(), Edge child2 = Edge(), Edge child3 = Edge())
291         : origin(nodeOrigin)
292         , children(AdjacencyList::Fixed, child1, child2, child3)
293         , m_virtualRegister(VirtualRegister())
294         , m_refCount(1)
295         , m_prediction(SpecNone)
296         , m_opInfo(imm.m_value)
297         , m_opInfo2(0)
298         , owner(nullptr)
299     {
300         m_misc.replacement = nullptr;
301         setOpAndDefaultFlags(op);
302         ASSERT(!(m_flags & NodeHasVarArgs));
303     }
304
305     // Construct a node with up to 3 children and an immediate value.
306     Node(NodeFlags result, NodeType op, NodeOrigin nodeOrigin, OpInfo imm, Edge child1 = Edge(), Edge child2 = Edge(), Edge child3 = Edge())
307         : origin(nodeOrigin)
308         , children(AdjacencyList::Fixed, child1, child2, child3)
309         , m_virtualRegister(VirtualRegister())
310         , m_refCount(1)
311         , m_prediction(SpecNone)
312         , m_opInfo(imm.m_value)
313         , m_opInfo2(0)
314         , owner(nullptr)
315     {
316         m_misc.replacement = nullptr;
317         setOpAndDefaultFlags(op);
318         setResult(result);
319         ASSERT(!(m_flags & NodeHasVarArgs));
320     }
321
322     // Construct a node with up to 3 children and two immediate values.
323     Node(NodeType op, NodeOrigin nodeOrigin, OpInfo imm1, OpInfo imm2, Edge child1 = Edge(), Edge child2 = Edge(), Edge child3 = Edge())
324         : origin(nodeOrigin)
325         , children(AdjacencyList::Fixed, child1, child2, child3)
326         , m_virtualRegister(VirtualRegister())
327         , m_refCount(1)
328         , m_prediction(SpecNone)
329         , m_opInfo(imm1.m_value)
330         , m_opInfo2(imm2.m_value)
331         , owner(nullptr)
332     {
333         m_misc.replacement = nullptr;
334         setOpAndDefaultFlags(op);
335         ASSERT(!(m_flags & NodeHasVarArgs));
336     }
337     
338     // Construct a node with a variable number of children and two immediate values.
339     Node(VarArgTag, NodeType op, NodeOrigin nodeOrigin, OpInfo imm1, OpInfo imm2, unsigned firstChild, unsigned numChildren)
340         : origin(nodeOrigin)
341         , children(AdjacencyList::Variable, firstChild, numChildren)
342         , m_virtualRegister(VirtualRegister())
343         , m_refCount(1)
344         , m_prediction(SpecNone)
345         , m_opInfo(imm1.m_value)
346         , m_opInfo2(imm2.m_value)
347         , owner(nullptr)
348     {
349         m_misc.replacement = nullptr;
350         setOpAndDefaultFlags(op);
351         ASSERT(m_flags & NodeHasVarArgs);
352     }
353     
354     NodeType op() const { return static_cast<NodeType>(m_op); }
355     NodeFlags flags() const { return m_flags; }
356     
357     // This is not a fast method.
358     unsigned index() const;
359     
360     void setOp(NodeType op)
361     {
362         m_op = op;
363     }
364     
365     void setFlags(NodeFlags flags)
366     {
367         m_flags = flags;
368     }
369     
370     bool mergeFlags(NodeFlags flags)
371     {
372         NodeFlags newFlags = m_flags | flags;
373         if (newFlags == m_flags)
374             return false;
375         m_flags = newFlags;
376         return true;
377     }
378     
379     bool filterFlags(NodeFlags flags)
380     {
381         NodeFlags newFlags = m_flags & flags;
382         if (newFlags == m_flags)
383             return false;
384         m_flags = newFlags;
385         return true;
386     }
387     
388     bool clearFlags(NodeFlags flags)
389     {
390         return filterFlags(~flags);
391     }
392     
393     void setResult(NodeFlags result)
394     {
395         ASSERT(!(result & ~NodeResultMask));
396         clearFlags(NodeResultMask);
397         mergeFlags(result);
398     }
399     
400     NodeFlags result() const
401     {
402         return flags() & NodeResultMask;
403     }
404     
405     void setOpAndDefaultFlags(NodeType op)
406     {
407         m_op = op;
408         m_flags = defaultFlags(op);
409     }
410
411     void remove();
412
413     void convertToCheckStructure(StructureSet* set)
414     {
415         setOpAndDefaultFlags(CheckStructure);
416         m_opInfo = bitwise_cast<uintptr_t>(set); 
417     }
418
419     void convertToCheckStructureImmediate(Node* structure)
420     {
421         ASSERT(op() == CheckStructure);
422         m_op = CheckStructureImmediate;
423         children.setChild1(Edge(structure, CellUse));
424     }
425     
426     void replaceWith(Node* other)
427     {
428         remove();
429         setReplacement(other);
430     }
431
432     void convertToIdentity();
433     void convertToIdentityOn(Node*);
434
435     bool mustGenerate()
436     {
437         return m_flags & NodeMustGenerate;
438     }
439     
440     bool isConstant()
441     {
442         switch (op()) {
443         case JSConstant:
444         case DoubleConstant:
445         case Int52Constant:
446             return true;
447         default:
448             return false;
449         }
450     }
451     
452     bool hasConstant()
453     {
454         switch (op()) {
455         case JSConstant:
456         case DoubleConstant:
457         case Int52Constant:
458             return true;
459             
460         case PhantomDirectArguments:
461         case PhantomClonedArguments:
462             // These pretend to be the empty value constant for the benefit of the DFG backend, which
463             // otherwise wouldn't take kindly to a node that doesn't compute a value.
464             return true;
465             
466         default:
467             return false;
468         }
469     }
470
471     FrozenValue* constant()
472     {
473         ASSERT(hasConstant());
474         
475         if (op() == PhantomDirectArguments || op() == PhantomClonedArguments) {
476             // These pretend to be the empty value constant for the benefit of the DFG backend, which
477             // otherwise wouldn't take kindly to a node that doesn't compute a value.
478             return FrozenValue::emptySingleton();
479         }
480         
481         return bitwise_cast<FrozenValue*>(m_opInfo);
482     }
483     
484     // Don't call this directly - use Graph::convertToConstant() instead!
485     void convertToConstant(FrozenValue* value)
486     {
487         if (hasDoubleResult())
488             m_op = DoubleConstant;
489         else if (hasInt52Result())
490             m_op = Int52Constant;
491         else
492             m_op = JSConstant;
493         m_flags &= ~NodeMustGenerate;
494         m_opInfo = bitwise_cast<uintptr_t>(value);
495         children.reset();
496     }
497     
498     void convertToConstantStoragePointer(void* pointer)
499     {
500         ASSERT(op() == GetIndexedPropertyStorage);
501         m_op = ConstantStoragePointer;
502         m_opInfo = bitwise_cast<uintptr_t>(pointer);
503         children.reset();
504     }
505     
506     void convertToGetLocalUnlinked(VirtualRegister local)
507     {
508         m_op = GetLocalUnlinked;
509         m_flags &= ~NodeMustGenerate;
510         m_opInfo = local.offset();
511         m_opInfo2 = VirtualRegister().offset();
512         children.reset();
513     }
514     
515     void convertToPutStack(StackAccessData* data)
516     {
517         m_op = PutStack;
518         m_flags |= NodeMustGenerate;
519         m_opInfo = bitwise_cast<uintptr_t>(data);
520         m_opInfo2 = 0;
521     }
522     
523     void convertToGetStack(StackAccessData* data)
524     {
525         m_op = GetStack;
526         m_flags &= ~NodeMustGenerate;
527         m_opInfo = bitwise_cast<uintptr_t>(data);
528         m_opInfo2 = 0;
529         children.reset();
530     }
531     
532     void convertToGetByOffset(StorageAccessData& data, Edge storage)
533     {
534         ASSERT(m_op == GetById || m_op == GetByIdFlush || m_op == MultiGetByOffset);
535         m_opInfo = bitwise_cast<uintptr_t>(&data);
536         children.setChild2(children.child1());
537         children.child2().setUseKind(KnownCellUse);
538         children.setChild1(storage);
539         m_op = GetByOffset;
540         m_flags &= ~NodeMustGenerate;
541     }
542     
543     void convertToMultiGetByOffset(MultiGetByOffsetData* data)
544     {
545         ASSERT(m_op == GetById || m_op == GetByIdFlush);
546         m_opInfo = bitwise_cast<intptr_t>(data);
547         child1().setUseKind(CellUse);
548         m_op = MultiGetByOffset;
549         ASSERT(m_flags & NodeMustGenerate);
550     }
551     
552     void convertToPutByOffset(StorageAccessData& data, Edge storage)
553     {
554         ASSERT(m_op == PutById || m_op == PutByIdDirect || m_op == PutByIdFlush || m_op == MultiPutByOffset);
555         m_opInfo = bitwise_cast<uintptr_t>(&data);
556         children.setChild3(children.child2());
557         children.setChild2(children.child1());
558         children.setChild1(storage);
559         m_op = PutByOffset;
560     }
561     
562     void convertToMultiPutByOffset(MultiPutByOffsetData* data)
563     {
564         ASSERT(m_op == PutById || m_op == PutByIdDirect || m_op == PutByIdFlush);
565         m_opInfo = bitwise_cast<intptr_t>(data);
566         m_op = MultiPutByOffset;
567     }
568     
569     void convertToPutHint(const PromotedLocationDescriptor&, Node* base, Node* value);
570     
571     void convertToPutByOffsetHint();
572     void convertToPutStructureHint(Node* structure);
573     void convertToPutClosureVarHint();
574     
575     void convertToPhantomNewObject()
576     {
577         ASSERT(m_op == NewObject || m_op == MaterializeNewObject);
578         m_op = PhantomNewObject;
579         m_flags &= ~NodeHasVarArgs;
580         m_flags |= NodeMustGenerate;
581         m_opInfo = 0;
582         m_opInfo2 = 0;
583         children = AdjacencyList();
584     }
585
586     void convertToPhantomNewFunction()
587     {
588         ASSERT(m_op == NewFunction || m_op == NewArrowFunction || m_op == NewGeneratorFunction);
589         m_op = PhantomNewFunction;
590         m_flags |= NodeMustGenerate;
591         m_opInfo = 0;
592         m_opInfo2 = 0;
593         children = AdjacencyList();
594     }
595
596     void convertToPhantomNewGeneratorFunction()
597     {
598         ASSERT(m_op == NewGeneratorFunction);
599         m_op = PhantomNewGeneratorFunction;
600         m_flags |= NodeMustGenerate;
601         m_opInfo = 0;
602         m_opInfo2 = 0;
603         children = AdjacencyList();
604     }
605
606     void convertToPhantomCreateActivation()
607     {
608         ASSERT(m_op == CreateActivation || m_op == MaterializeCreateActivation);
609         m_op = PhantomCreateActivation;
610         m_flags &= ~NodeHasVarArgs;
611         m_flags |= NodeMustGenerate;
612         m_opInfo = 0;
613         m_opInfo2 = 0;
614         children = AdjacencyList();
615     }
616
617     void convertPhantomToPhantomLocal()
618     {
619         ASSERT(m_op == Phantom && (child1()->op() == Phi || child1()->op() == SetLocal || child1()->op() == SetArgument));
620         m_op = PhantomLocal;
621         m_opInfo = child1()->m_opInfo; // Copy the variableAccessData.
622         children.setChild1(Edge());
623     }
624     
625     void convertFlushToPhantomLocal()
626     {
627         ASSERT(m_op == Flush);
628         m_op = PhantomLocal;
629         children = AdjacencyList();
630     }
631     
632     void convertToGetLocal(VariableAccessData* variable, Node* phi)
633     {
634         ASSERT(m_op == GetLocalUnlinked);
635         m_op = GetLocal;
636         m_opInfo = bitwise_cast<uintptr_t>(variable);
637         m_opInfo2 = 0;
638         children.setChild1(Edge(phi));
639     }
640     
641     void convertToToString()
642     {
643         ASSERT(m_op == ToPrimitive);
644         m_op = ToString;
645     }
646
647     void convertToArithSqrt()
648     {
649         ASSERT(m_op == ArithPow);
650         child2() = Edge();
651         m_op = ArithSqrt;
652     }
653
654     void convertToArithNegate()
655     {
656         ASSERT(m_op == ArithAbs && child1().useKind() == Int32Use);
657         m_op = ArithNegate;
658     }
659     
660     JSValue asJSValue()
661     {
662         return constant()->value();
663     }
664      
665     bool isInt32Constant()
666     {
667         return isConstant() && constant()->value().isInt32();
668     }
669      
670     int32_t asInt32()
671     {
672         return asJSValue().asInt32();
673     }
674      
675     uint32_t asUInt32()
676     {
677         return asInt32();
678     }
679      
680     bool isDoubleConstant()
681     {
682         return isConstant() && constant()->value().isDouble();
683     }
684      
685     bool isNumberConstant()
686     {
687         return isConstant() && constant()->value().isNumber();
688     }
689     
690     double asNumber()
691     {
692         return asJSValue().asNumber();
693     }
694      
695     bool isMachineIntConstant()
696     {
697         return isConstant() && constant()->value().isMachineInt();
698     }
699      
700     int64_t asMachineInt()
701     {
702         return asJSValue().asMachineInt();
703     }
704      
705     bool isBooleanConstant()
706     {
707         return isConstant() && constant()->value().isBoolean();
708     }
709      
710     bool asBoolean()
711     {
712         return constant()->value().asBoolean();
713     }
714
715     bool isUndefinedOrNullConstant()
716     {
717         return isConstant() && constant()->value().isUndefinedOrNull();
718     }
719
720     bool isCellConstant()
721     {
722         return isConstant() && constant()->value() && constant()->value().isCell();
723     }
724      
725     JSCell* asCell()
726     {
727         return constant()->value().asCell();
728     }
729      
730     template<typename T>
731     T dynamicCastConstant()
732     {
733         if (!isCellConstant())
734             return nullptr;
735         return jsDynamicCast<T>(asCell());
736     }
737     
738     template<typename T>
739     T castConstant()
740     {
741         T result = dynamicCastConstant<T>();
742         RELEASE_ASSERT(result);
743         return result;
744     }
745
746     JSValue initializationValueForActivation() const
747     {
748         ASSERT(op() == CreateActivation);
749         return bitwise_cast<FrozenValue*>(m_opInfo2)->value();
750     }
751      
752     bool containsMovHint()
753     {
754         switch (op()) {
755         case MovHint:
756         case ZombieHint:
757             return true;
758         default:
759             return false;
760         }
761     }
762     
763     bool hasVariableAccessData(Graph&);
764     bool hasLocal(Graph& graph)
765     {
766         return hasVariableAccessData(graph);
767     }
768     
769     // This is useful for debugging code, where a node that should have a variable
770     // access data doesn't have one because it hasn't been initialized yet.
771     VariableAccessData* tryGetVariableAccessData()
772     {
773         VariableAccessData* result = reinterpret_cast<VariableAccessData*>(m_opInfo);
774         if (!result)
775             return 0;
776         return result->find();
777     }
778     
779     VariableAccessData* variableAccessData()
780     {
781         return reinterpret_cast<VariableAccessData*>(m_opInfo)->find();
782     }
783     
784     VirtualRegister local()
785     {
786         return variableAccessData()->local();
787     }
788     
789     VirtualRegister machineLocal()
790     {
791         return variableAccessData()->machineLocal();
792     }
793     
794     bool hasUnlinkedLocal()
795     {
796         switch (op()) {
797         case GetLocalUnlinked:
798         case ExtractOSREntryLocal:
799         case MovHint:
800         case ZombieHint:
801         case KillStack:
802             return true;
803         default:
804             return false;
805         }
806     }
807     
808     VirtualRegister unlinkedLocal()
809     {
810         ASSERT(hasUnlinkedLocal());
811         return static_cast<VirtualRegister>(m_opInfo);
812     }
813     
814     bool hasUnlinkedMachineLocal()
815     {
816         return op() == GetLocalUnlinked;
817     }
818     
819     void setUnlinkedMachineLocal(VirtualRegister reg)
820     {
821         ASSERT(hasUnlinkedMachineLocal());
822         m_opInfo2 = reg.offset();
823     }
824     
825     VirtualRegister unlinkedMachineLocal()
826     {
827         ASSERT(hasUnlinkedMachineLocal());
828         return VirtualRegister(m_opInfo2);
829     }
830     
831     bool hasStackAccessData()
832     {
833         switch (op()) {
834         case PutStack:
835         case GetStack:
836             return true;
837         default:
838             return false;
839         }
840     }
841     
842     StackAccessData* stackAccessData()
843     {
844         ASSERT(hasStackAccessData());
845         return bitwise_cast<StackAccessData*>(m_opInfo);
846     }
847     
848     bool hasPhi()
849     {
850         return op() == Upsilon;
851     }
852     
853     Node* phi()
854     {
855         ASSERT(hasPhi());
856         return bitwise_cast<Node*>(m_opInfo);
857     }
858
859     bool isStoreBarrier()
860     {
861         return op() == StoreBarrier;
862     }
863
864     bool hasIdentifier()
865     {
866         switch (op()) {
867         case GetById:
868         case GetByIdFlush:
869         case PutById:
870         case PutByIdFlush:
871         case PutByIdDirect:
872         case PutGetterById:
873         case PutSetterById:
874         case PutGetterSetterById:
875             return true;
876         default:
877             return false;
878         }
879     }
880
881     unsigned identifierNumber()
882     {
883         ASSERT(hasIdentifier());
884         return m_opInfo;
885     }
886
887     bool hasAccessorAttributes()
888     {
889         switch (op()) {
890         case PutGetterById:
891         case PutSetterById:
892         case PutGetterSetterById:
893         case PutGetterByVal:
894         case PutSetterByVal:
895             return true;
896         default:
897             return false;
898         }
899     }
900
901     int32_t accessorAttributes()
902     {
903         ASSERT(hasAccessorAttributes());
904         switch (op()) {
905         case PutGetterById:
906         case PutSetterById:
907         case PutGetterSetterById:
908             return m_opInfo2;
909         case PutGetterByVal:
910         case PutSetterByVal:
911             return m_opInfo;
912         default:
913             RELEASE_ASSERT_NOT_REACHED();
914             return 0;
915         }
916     }
917     
918     bool hasPromotedLocationDescriptor()
919     {
920         return op() == PutHint;
921     }
922     
923     PromotedLocationDescriptor promotedLocationDescriptor();
924     
925     // This corrects the arithmetic node flags, so that irrelevant bits are
926     // ignored. In particular, anything other than ArithMul does not need
927     // to know if it can speculate on negative zero.
928     NodeFlags arithNodeFlags()
929     {
930         NodeFlags result = m_flags & NodeArithFlagsMask;
931         if (op() == ArithMul || op() == ArithDiv || op() == ArithMod || op() == ArithNegate || op() == ArithPow || op() == ArithRound || op() == DoubleAsInt32)
932             return result;
933         return result & ~NodeBytecodeNeedsNegZero;
934     }
935
936     bool mayHaveNonIntResult()
937     {
938         return m_flags & NodeMayHaveNonIntResult;
939     }
940
941     bool hasConstantBuffer()
942     {
943         return op() == NewArrayBuffer;
944     }
945     
946     NewArrayBufferData* newArrayBufferData()
947     {
948         ASSERT(hasConstantBuffer());
949         return reinterpret_cast<NewArrayBufferData*>(m_opInfo);
950     }
951     
952     unsigned startConstant()
953     {
954         return newArrayBufferData()->startConstant;
955     }
956     
957     unsigned numConstants()
958     {
959         return newArrayBufferData()->numConstants;
960     }
961     
962     bool hasIndexingType()
963     {
964         switch (op()) {
965         case NewArray:
966         case NewArrayWithSize:
967         case NewArrayBuffer:
968             return true;
969         default:
970             return false;
971         }
972     }
973
974     // Return the indexing type that an array allocation *wants* to use. It may end up using a different
975     // type if we're having a bad time. You can determine the actual indexing type by asking the global
976     // object:
977     //
978     //     m_graph.globalObjectFor(node->origin.semantic)->arrayStructureForIndexingTypeDuringAllocation(node->indexingType())
979     //
980     // This will give you a Structure*, and that will have some indexing type that may be different from
981     // the this one.
982     IndexingType indexingType()
983     {
984         ASSERT(hasIndexingType());
985         if (op() == NewArrayBuffer)
986             return newArrayBufferData()->indexingType;
987         return m_opInfo;
988     }
989     
990     bool hasTypedArrayType()
991     {
992         switch (op()) {
993         case NewTypedArray:
994             return true;
995         default:
996             return false;
997         }
998     }
999     
1000     TypedArrayType typedArrayType()
1001     {
1002         ASSERT(hasTypedArrayType());
1003         TypedArrayType result = static_cast<TypedArrayType>(m_opInfo);
1004         ASSERT(isTypedView(result));
1005         return result;
1006     }
1007     
1008     bool hasInlineCapacity()
1009     {
1010         return op() == CreateThis;
1011     }
1012
1013     unsigned inlineCapacity()
1014     {
1015         ASSERT(hasInlineCapacity());
1016         return m_opInfo;
1017     }
1018
1019     void setIndexingType(IndexingType indexingType)
1020     {
1021         ASSERT(hasIndexingType());
1022         m_opInfo = indexingType;
1023     }
1024     
1025     // FIXME: We really should be able to inline code that uses NewRegexp. That means
1026     // using something other than the index into the CodeBlock here.
1027     // https://bugs.webkit.org/show_bug.cgi?id=154808
1028     bool hasRegexpIndex()
1029     {
1030         return op() == NewRegexp;
1031     }
1032     
1033     unsigned regexpIndex()
1034     {
1035         ASSERT(hasRegexpIndex());
1036         return m_opInfo;
1037     }
1038     
1039     bool hasScopeOffset()
1040     {
1041         return op() == GetClosureVar || op() == PutClosureVar;
1042     }
1043
1044     ScopeOffset scopeOffset()
1045     {
1046         ASSERT(hasScopeOffset());
1047         return ScopeOffset(m_opInfo);
1048     }
1049     
1050     bool hasDirectArgumentsOffset()
1051     {
1052         return op() == GetFromArguments || op() == PutToArguments;
1053     }
1054     
1055     DirectArgumentsOffset capturedArgumentsOffset()
1056     {
1057         ASSERT(hasDirectArgumentsOffset());
1058         return DirectArgumentsOffset(m_opInfo);
1059     }
1060     
1061     bool hasRegisterPointer()
1062     {
1063         return op() == GetGlobalVar || op() == GetGlobalLexicalVariable || op() == PutGlobalVariable;
1064     }
1065     
1066     WriteBarrier<Unknown>* variablePointer()
1067     {
1068         return bitwise_cast<WriteBarrier<Unknown>*>(m_opInfo);
1069     }
1070     
1071     bool hasCallVarargsData()
1072     {
1073         switch (op()) {
1074         case CallVarargs:
1075         case CallForwardVarargs:
1076         case TailCallVarargs:
1077         case TailCallForwardVarargs:
1078         case TailCallVarargsInlinedCaller:
1079         case TailCallForwardVarargsInlinedCaller:
1080         case ConstructVarargs:
1081         case ConstructForwardVarargs:
1082             return true;
1083         default:
1084             return false;
1085         }
1086     }
1087     
1088     CallVarargsData* callVarargsData()
1089     {
1090         ASSERT(hasCallVarargsData());
1091         return bitwise_cast<CallVarargsData*>(m_opInfo);
1092     }
1093     
1094     bool hasLoadVarargsData()
1095     {
1096         return op() == LoadVarargs || op() == ForwardVarargs;
1097     }
1098     
1099     LoadVarargsData* loadVarargsData()
1100     {
1101         ASSERT(hasLoadVarargsData());
1102         return bitwise_cast<LoadVarargsData*>(m_opInfo);
1103     }
1104     
1105     bool hasResult()
1106     {
1107         return !!result();
1108     }
1109
1110     bool hasInt32Result()
1111     {
1112         return result() == NodeResultInt32;
1113     }
1114     
1115     bool hasInt52Result()
1116     {
1117         return result() == NodeResultInt52;
1118     }
1119     
1120     bool hasNumberResult()
1121     {
1122         return result() == NodeResultNumber;
1123     }
1124     
1125     bool hasDoubleResult()
1126     {
1127         return result() == NodeResultDouble;
1128     }
1129     
1130     bool hasJSResult()
1131     {
1132         return result() == NodeResultJS;
1133     }
1134     
1135     bool hasBooleanResult()
1136     {
1137         return result() == NodeResultBoolean;
1138     }
1139
1140     bool hasStorageResult()
1141     {
1142         return result() == NodeResultStorage;
1143     }
1144     
1145     UseKind defaultUseKind()
1146     {
1147         return useKindForResult(result());
1148     }
1149     
1150     Edge defaultEdge()
1151     {
1152         return Edge(this, defaultUseKind());
1153     }
1154
1155     bool isJump()
1156     {
1157         return op() == Jump;
1158     }
1159
1160     bool isBranch()
1161     {
1162         return op() == Branch;
1163     }
1164     
1165     bool isSwitch()
1166     {
1167         return op() == Switch;
1168     }
1169
1170     bool isTerminal()
1171     {
1172         switch (op()) {
1173         case Jump:
1174         case Branch:
1175         case Switch:
1176         case Return:
1177         case TailCall:
1178         case TailCallVarargs:
1179         case TailCallForwardVarargs:
1180         case Unreachable:
1181             return true;
1182         default:
1183             return false;
1184         }
1185     }
1186
1187     bool isFunctionTerminal()
1188     {
1189         if (isTerminal() && !numSuccessors())
1190             return true;
1191
1192         return false;
1193     }
1194
1195     unsigned targetBytecodeOffsetDuringParsing()
1196     {
1197         ASSERT(isJump());
1198         return m_opInfo;
1199     }
1200
1201     BasicBlock*& targetBlock()
1202     {
1203         ASSERT(isJump());
1204         return *bitwise_cast<BasicBlock**>(&m_opInfo);
1205     }
1206     
1207     BranchData* branchData()
1208     {
1209         ASSERT(isBranch());
1210         return bitwise_cast<BranchData*>(m_opInfo);
1211     }
1212     
1213     SwitchData* switchData()
1214     {
1215         ASSERT(isSwitch());
1216         return bitwise_cast<SwitchData*>(m_opInfo);
1217     }
1218     
1219     unsigned numSuccessors()
1220     {
1221         switch (op()) {
1222         case Jump:
1223             return 1;
1224         case Branch:
1225             return 2;
1226         case Switch:
1227             return switchData()->cases.size() + 1;
1228         default:
1229             return 0;
1230         }
1231     }
1232     
1233     BasicBlock*& successor(unsigned index)
1234     {
1235         if (isSwitch()) {
1236             if (index < switchData()->cases.size())
1237                 return switchData()->cases[index].target.block;
1238             RELEASE_ASSERT(index == switchData()->cases.size());
1239             return switchData()->fallThrough.block;
1240         }
1241         switch (index) {
1242         case 0:
1243             if (isJump())
1244                 return targetBlock();
1245             return branchData()->taken.block;
1246         case 1:
1247             return branchData()->notTaken.block;
1248         default:
1249             RELEASE_ASSERT_NOT_REACHED();
1250             return targetBlock();
1251         }
1252     }
1253     
1254     class SuccessorsIterable {
1255     public:
1256         SuccessorsIterable()
1257             : m_terminal(nullptr)
1258         {
1259         }
1260         
1261         SuccessorsIterable(Node* terminal)
1262             : m_terminal(terminal)
1263         {
1264         }
1265         
1266         class iterator {
1267         public:
1268             iterator()
1269                 : m_terminal(nullptr)
1270                 , m_index(UINT_MAX)
1271             {
1272             }
1273             
1274             iterator(Node* terminal, unsigned index)
1275                 : m_terminal(terminal)
1276                 , m_index(index)
1277             {
1278             }
1279             
1280             BasicBlock* operator*()
1281             {
1282                 return m_terminal->successor(m_index);
1283             }
1284             
1285             iterator& operator++()
1286             {
1287                 m_index++;
1288                 return *this;
1289             }
1290             
1291             bool operator==(const iterator& other) const
1292             {
1293                 return m_index == other.m_index;
1294             }
1295             
1296             bool operator!=(const iterator& other) const
1297             {
1298                 return !(*this == other);
1299             }
1300         private:
1301             Node* m_terminal;
1302             unsigned m_index;
1303         };
1304         
1305         iterator begin()
1306         {
1307             return iterator(m_terminal, 0);
1308         }
1309         
1310         iterator end()
1311         {
1312             return iterator(m_terminal, m_terminal->numSuccessors());
1313         }
1314
1315         size_t size() const { return m_terminal->numSuccessors(); }
1316         BasicBlock* at(size_t index) const { return m_terminal->successor(index); }
1317         BasicBlock* operator[](size_t index) const { return at(index); }
1318         
1319     private:
1320         Node* m_terminal;
1321     };
1322     
1323     SuccessorsIterable successors()
1324     {
1325         return SuccessorsIterable(this);
1326     }
1327     
1328     BasicBlock*& successorForCondition(bool condition)
1329     {
1330         return branchData()->forCondition(condition);
1331     }
1332     
1333     bool hasHeapPrediction()
1334     {
1335         switch (op()) {
1336         case ArithRound:
1337         case GetDirectPname:
1338         case GetById:
1339         case GetByIdFlush:
1340         case GetByVal:
1341         case Call:
1342         case TailCallInlinedCaller:
1343         case Construct:
1344         case CallVarargs:
1345         case TailCallVarargsInlinedCaller:
1346         case ConstructVarargs:
1347         case CallForwardVarargs:
1348         case TailCallForwardVarargsInlinedCaller:
1349         case GetByOffset:
1350         case MultiGetByOffset:
1351         case GetClosureVar:
1352         case GetFromArguments:
1353         case ArrayPop:
1354         case ArrayPush:
1355         case RegExpExec:
1356         case RegExpTest:
1357         case GetGlobalVar:
1358         case GetGlobalLexicalVariable:
1359             return true;
1360         default:
1361             return false;
1362         }
1363     }
1364     
1365     SpeculatedType getHeapPrediction()
1366     {
1367         ASSERT(hasHeapPrediction());
1368         return static_cast<SpeculatedType>(m_opInfo2);
1369     }
1370
1371     void setHeapPrediction(SpeculatedType prediction)
1372     {
1373         ASSERT(hasHeapPrediction());
1374         m_opInfo2 = prediction;
1375     }
1376     
1377     bool hasCellOperand()
1378     {
1379         switch (op()) {
1380         case CheckCell:
1381         case OverridesHasInstance:
1382         case NewFunction:
1383         case NewArrowFunction:
1384         case NewGeneratorFunction:
1385         case CreateActivation:
1386         case MaterializeCreateActivation:
1387             return true;
1388         default:
1389             return false;
1390         }
1391     }
1392
1393     FrozenValue* cellOperand()
1394     {
1395         ASSERT(hasCellOperand());
1396         return reinterpret_cast<FrozenValue*>(m_opInfo);
1397     }
1398     
1399     template<typename T>
1400     T castOperand()
1401     {
1402         return cellOperand()->cast<T>();
1403     }
1404     
1405     void setCellOperand(FrozenValue* value)
1406     {
1407         ASSERT(hasCellOperand());
1408         m_opInfo = bitwise_cast<uintptr_t>(value);
1409     }
1410     
1411     bool hasWatchpointSet()
1412     {
1413         return op() == NotifyWrite;
1414     }
1415     
1416     WatchpointSet* watchpointSet()
1417     {
1418         ASSERT(hasWatchpointSet());
1419         return reinterpret_cast<WatchpointSet*>(m_opInfo);
1420     }
1421     
1422     bool hasStoragePointer()
1423     {
1424         return op() == ConstantStoragePointer;
1425     }
1426     
1427     void* storagePointer()
1428     {
1429         ASSERT(hasStoragePointer());
1430         return reinterpret_cast<void*>(m_opInfo);
1431     }
1432
1433     bool hasUidOperand()
1434     {
1435         return op() == CheckIdent;
1436     }
1437
1438     UniquedStringImpl* uidOperand()
1439     {
1440         ASSERT(hasUidOperand());
1441         return reinterpret_cast<UniquedStringImpl*>(m_opInfo);
1442     }
1443
1444     bool hasTypeInfoOperand()
1445     {
1446         return op() == CheckTypeInfoFlags;
1447     }
1448
1449     unsigned typeInfoOperand()
1450     {
1451         ASSERT(hasTypeInfoOperand() && m_opInfo <= UCHAR_MAX);
1452         return static_cast<unsigned>(m_opInfo);
1453     }
1454
1455     bool hasTransition()
1456     {
1457         switch (op()) {
1458         case PutStructure:
1459         case AllocatePropertyStorage:
1460         case ReallocatePropertyStorage:
1461             return true;
1462         default:
1463             return false;
1464         }
1465     }
1466     
1467     Transition* transition()
1468     {
1469         ASSERT(hasTransition());
1470         return reinterpret_cast<Transition*>(m_opInfo);
1471     }
1472     
1473     bool hasStructureSet()
1474     {
1475         switch (op()) {
1476         case CheckStructure:
1477         case CheckStructureImmediate:
1478         case MaterializeNewObject:
1479             return true;
1480         default:
1481             return false;
1482         }
1483     }
1484     
1485     StructureSet& structureSet()
1486     {
1487         ASSERT(hasStructureSet());
1488         return *reinterpret_cast<StructureSet*>(m_opInfo);
1489     }
1490     
1491     bool hasStructure()
1492     {
1493         switch (op()) {
1494         case ArrayifyToStructure:
1495         case NewObject:
1496         case NewStringObject:
1497             return true;
1498         default:
1499             return false;
1500         }
1501     }
1502     
1503     Structure* structure()
1504     {
1505         ASSERT(hasStructure());
1506         return reinterpret_cast<Structure*>(m_opInfo);
1507     }
1508     
1509     bool hasStorageAccessData()
1510     {
1511         switch (op()) {
1512         case GetByOffset:
1513         case PutByOffset:
1514         case GetGetterSetterByOffset:
1515             return true;
1516         default:
1517             return false;
1518         }
1519     }
1520     
1521     StorageAccessData& storageAccessData()
1522     {
1523         ASSERT(hasStorageAccessData());
1524         return *bitwise_cast<StorageAccessData*>(m_opInfo);
1525     }
1526     
1527     bool hasMultiGetByOffsetData()
1528     {
1529         return op() == MultiGetByOffset;
1530     }
1531     
1532     MultiGetByOffsetData& multiGetByOffsetData()
1533     {
1534         ASSERT(hasMultiGetByOffsetData());
1535         return *reinterpret_cast<MultiGetByOffsetData*>(m_opInfo);
1536     }
1537     
1538     bool hasMultiPutByOffsetData()
1539     {
1540         return op() == MultiPutByOffset;
1541     }
1542     
1543     MultiPutByOffsetData& multiPutByOffsetData()
1544     {
1545         ASSERT(hasMultiPutByOffsetData());
1546         return *reinterpret_cast<MultiPutByOffsetData*>(m_opInfo);
1547     }
1548     
1549     bool hasObjectMaterializationData()
1550     {
1551         switch (op()) {
1552         case MaterializeNewObject:
1553         case MaterializeCreateActivation:
1554             return true;
1555
1556         default:
1557             return false;
1558         }
1559     }
1560     
1561     ObjectMaterializationData& objectMaterializationData()
1562     {
1563         ASSERT(hasObjectMaterializationData());
1564         return *reinterpret_cast<ObjectMaterializationData*>(m_opInfo2);
1565     }
1566
1567     bool isObjectAllocation()
1568     {
1569         switch (op()) {
1570         case NewObject:
1571         case MaterializeNewObject:
1572             return true;
1573         default:
1574             return false;
1575         }
1576     }
1577     
1578     bool isPhantomObjectAllocation()
1579     {
1580         switch (op()) {
1581         case PhantomNewObject:
1582             return true;
1583         default:
1584             return false;
1585         }
1586     }
1587     
1588     bool isActivationAllocation()
1589     {
1590         switch (op()) {
1591         case CreateActivation:
1592         case MaterializeCreateActivation:
1593             return true;
1594         default:
1595             return false;
1596         }
1597     }
1598
1599     bool isPhantomActivationAllocation()
1600     {
1601         switch (op()) {
1602         case PhantomCreateActivation:
1603             return true;
1604         default:
1605             return false;
1606         }
1607     }
1608
1609     bool isFunctionAllocation()
1610     {
1611         switch (op()) {
1612         case NewArrowFunction:
1613         case NewFunction:
1614         case NewGeneratorFunction:
1615             return true;
1616         default:
1617             return false;
1618         }
1619     }
1620
1621     bool isPhantomFunctionAllocation()
1622     {
1623         switch (op()) {
1624         case PhantomNewFunction:
1625         case PhantomNewGeneratorFunction:
1626             return true;
1627         default:
1628             return false;
1629         }
1630     }
1631
1632     bool isPhantomAllocation()
1633     {
1634         switch (op()) {
1635         case PhantomNewObject:
1636         case PhantomDirectArguments:
1637         case PhantomClonedArguments:
1638         case PhantomNewFunction:
1639         case PhantomNewGeneratorFunction:
1640         case PhantomCreateActivation:
1641             return true;
1642         default:
1643             return false;
1644         }
1645     }
1646     
1647     bool hasArrayMode()
1648     {
1649         switch (op()) {
1650         case GetIndexedPropertyStorage:
1651         case GetArrayLength:
1652         case PutByValDirect:
1653         case PutByVal:
1654         case PutByValAlias:
1655         case GetByVal:
1656         case StringCharAt:
1657         case StringCharCodeAt:
1658         case CheckArray:
1659         case Arrayify:
1660         case ArrayifyToStructure:
1661         case ArrayPush:
1662         case ArrayPop:
1663         case HasIndexedProperty:
1664             return true;
1665         default:
1666             return false;
1667         }
1668     }
1669     
1670     ArrayMode arrayMode()
1671     {
1672         ASSERT(hasArrayMode());
1673         if (op() == ArrayifyToStructure)
1674             return ArrayMode::fromWord(m_opInfo2);
1675         return ArrayMode::fromWord(m_opInfo);
1676     }
1677     
1678     bool setArrayMode(ArrayMode arrayMode)
1679     {
1680         ASSERT(hasArrayMode());
1681         if (this->arrayMode() == arrayMode)
1682             return false;
1683         m_opInfo = arrayMode.asWord();
1684         return true;
1685     }
1686     
1687     bool hasArithMode()
1688     {
1689         switch (op()) {
1690         case ArithAbs:
1691         case ArithAdd:
1692         case ArithSub:
1693         case ArithNegate:
1694         case ArithMul:
1695         case ArithDiv:
1696         case ArithMod:
1697         case UInt32ToNumber:
1698         case DoubleAsInt32:
1699             return true;
1700         default:
1701             return false;
1702         }
1703     }
1704
1705     Arith::Mode arithMode()
1706     {
1707         ASSERT(hasArithMode());
1708         return static_cast<Arith::Mode>(m_opInfo);
1709     }
1710     
1711     void setArithMode(Arith::Mode mode)
1712     {
1713         m_opInfo = mode;
1714     }
1715
1716     bool hasArithRoundingMode()
1717     {
1718         return op() == ArithRound;
1719     }
1720
1721     Arith::RoundingMode arithRoundingMode()
1722     {
1723         ASSERT(hasArithRoundingMode());
1724         return static_cast<Arith::RoundingMode>(m_opInfo);
1725     }
1726
1727     void setArithRoundingMode(Arith::RoundingMode mode)
1728     {
1729         ASSERT(hasArithRoundingMode());
1730         m_opInfo = static_cast<uintptr_t>(mode);
1731     }
1732     
1733     bool hasVirtualRegister()
1734     {
1735         return m_virtualRegister.isValid();
1736     }
1737     
1738     VirtualRegister virtualRegister()
1739     {
1740         ASSERT(hasResult());
1741         ASSERT(m_virtualRegister.isValid());
1742         return m_virtualRegister;
1743     }
1744     
1745     void setVirtualRegister(VirtualRegister virtualRegister)
1746     {
1747         ASSERT(hasResult());
1748         ASSERT(!m_virtualRegister.isValid());
1749         m_virtualRegister = virtualRegister;
1750     }
1751     
1752     bool hasExecutionCounter()
1753     {
1754         return op() == CountExecution;
1755     }
1756     
1757     Profiler::ExecutionCounter* executionCounter()
1758     {
1759         return bitwise_cast<Profiler::ExecutionCounter*>(m_opInfo);
1760     }
1761
1762     bool shouldGenerate()
1763     {
1764         return m_refCount;
1765     }
1766     
1767     bool isSemanticallySkippable()
1768     {
1769         return op() == CountExecution;
1770     }
1771
1772     unsigned refCount()
1773     {
1774         return m_refCount;
1775     }
1776
1777     unsigned postfixRef()
1778     {
1779         return m_refCount++;
1780     }
1781
1782     unsigned adjustedRefCount()
1783     {
1784         return mustGenerate() ? m_refCount - 1 : m_refCount;
1785     }
1786     
1787     void setRefCount(unsigned refCount)
1788     {
1789         m_refCount = refCount;
1790     }
1791     
1792     Edge& child1()
1793     {
1794         ASSERT(!(m_flags & NodeHasVarArgs));
1795         return children.child1();
1796     }
1797     
1798     // This is useful if you want to do a fast check on the first child
1799     // before also doing a check on the opcode. Use this with care and
1800     // avoid it if possible.
1801     Edge child1Unchecked()
1802     {
1803         return children.child1Unchecked();
1804     }
1805
1806     Edge& child2()
1807     {
1808         ASSERT(!(m_flags & NodeHasVarArgs));
1809         return children.child2();
1810     }
1811
1812     Edge& child3()
1813     {
1814         ASSERT(!(m_flags & NodeHasVarArgs));
1815         return children.child3();
1816     }
1817     
1818     unsigned firstChild()
1819     {
1820         ASSERT(m_flags & NodeHasVarArgs);
1821         return children.firstChild();
1822     }
1823     
1824     unsigned numChildren()
1825     {
1826         ASSERT(m_flags & NodeHasVarArgs);
1827         return children.numChildren();
1828     }
1829     
1830     UseKind binaryUseKind()
1831     {
1832         ASSERT(child1().useKind() == child2().useKind());
1833         return child1().useKind();
1834     }
1835     
1836     bool isBinaryUseKind(UseKind left, UseKind right)
1837     {
1838         return child1().useKind() == left && child2().useKind() == right;
1839     }
1840     
1841     bool isBinaryUseKind(UseKind useKind)
1842     {
1843         return isBinaryUseKind(useKind, useKind);
1844     }
1845     
1846     Edge childFor(UseKind useKind)
1847     {
1848         if (child1().useKind() == useKind)
1849             return child1();
1850         if (child2().useKind() == useKind)
1851             return child2();
1852         if (child3().useKind() == useKind)
1853             return child3();
1854         return Edge();
1855     }
1856     
1857     SpeculatedType prediction()
1858     {
1859         return m_prediction;
1860     }
1861     
1862     bool predict(SpeculatedType prediction)
1863     {
1864         return mergeSpeculation(m_prediction, prediction);
1865     }
1866     
1867     bool shouldSpeculateInt32()
1868     {
1869         return isInt32Speculation(prediction());
1870     }
1871     
1872     bool sawBooleans()
1873     {
1874         return !!(prediction() & SpecBoolean);
1875     }
1876     
1877     bool shouldSpeculateInt32OrBoolean()
1878     {
1879         return isInt32OrBooleanSpeculation(prediction());
1880     }
1881     
1882     bool shouldSpeculateInt32ForArithmetic()
1883     {
1884         return isInt32SpeculationForArithmetic(prediction());
1885     }
1886     
1887     bool shouldSpeculateInt32OrBooleanForArithmetic()
1888     {
1889         return isInt32OrBooleanSpeculationForArithmetic(prediction());
1890     }
1891     
1892     bool shouldSpeculateInt32OrBooleanExpectingDefined()
1893     {
1894         return isInt32OrBooleanSpeculationExpectingDefined(prediction());
1895     }
1896     
1897     bool shouldSpeculateMachineInt()
1898     {
1899         return isMachineIntSpeculation(prediction());
1900     }
1901     
1902     bool shouldSpeculateDouble()
1903     {
1904         return isDoubleSpeculation(prediction());
1905     }
1906     
1907     bool shouldSpeculateDoubleReal()
1908     {
1909         return isDoubleRealSpeculation(prediction());
1910     }
1911     
1912     bool shouldSpeculateNumber()
1913     {
1914         return isFullNumberSpeculation(prediction());
1915     }
1916     
1917     bool shouldSpeculateNumberOrBoolean()
1918     {
1919         return isFullNumberOrBooleanSpeculation(prediction());
1920     }
1921     
1922     bool shouldSpeculateNumberOrBooleanExpectingDefined()
1923     {
1924         return isFullNumberOrBooleanSpeculationExpectingDefined(prediction());
1925     }
1926     
1927     bool shouldSpeculateBoolean()
1928     {
1929         return isBooleanSpeculation(prediction());
1930     }
1931     
1932     bool shouldSpeculateOther()
1933     {
1934         return isOtherSpeculation(prediction());
1935     }
1936     
1937     bool shouldSpeculateMisc()
1938     {
1939         return isMiscSpeculation(prediction());
1940     }
1941    
1942     bool shouldSpeculateStringIdent()
1943     {
1944         return isStringIdentSpeculation(prediction());
1945     }
1946     
1947     bool shouldSpeculateNotStringVar()
1948     {
1949         return isNotStringVarSpeculation(prediction());
1950     }
1951  
1952     bool shouldSpeculateString()
1953     {
1954         return isStringSpeculation(prediction());
1955     }
1956  
1957     bool shouldSpeculateStringObject()
1958     {
1959         return isStringObjectSpeculation(prediction());
1960     }
1961     
1962     bool shouldSpeculateStringOrStringObject()
1963     {
1964         return isStringOrStringObjectSpeculation(prediction());
1965     }
1966
1967     bool shouldSpeculateSymbol()
1968     {
1969         return isSymbolSpeculation(prediction());
1970     }
1971     
1972     bool shouldSpeculateFinalObject()
1973     {
1974         return isFinalObjectSpeculation(prediction());
1975     }
1976     
1977     bool shouldSpeculateFinalObjectOrOther()
1978     {
1979         return isFinalObjectOrOtherSpeculation(prediction());
1980     }
1981     
1982     bool shouldSpeculateArray()
1983     {
1984         return isArraySpeculation(prediction());
1985     }
1986     
1987     bool shouldSpeculateDirectArguments()
1988     {
1989         return isDirectArgumentsSpeculation(prediction());
1990     }
1991     
1992     bool shouldSpeculateScopedArguments()
1993     {
1994         return isScopedArgumentsSpeculation(prediction());
1995     }
1996     
1997     bool shouldSpeculateInt8Array()
1998     {
1999         return isInt8ArraySpeculation(prediction());
2000     }
2001     
2002     bool shouldSpeculateInt16Array()
2003     {
2004         return isInt16ArraySpeculation(prediction());
2005     }
2006     
2007     bool shouldSpeculateInt32Array()
2008     {
2009         return isInt32ArraySpeculation(prediction());
2010     }
2011     
2012     bool shouldSpeculateUint8Array()
2013     {
2014         return isUint8ArraySpeculation(prediction());
2015     }
2016
2017     bool shouldSpeculateUint8ClampedArray()
2018     {
2019         return isUint8ClampedArraySpeculation(prediction());
2020     }
2021     
2022     bool shouldSpeculateUint16Array()
2023     {
2024         return isUint16ArraySpeculation(prediction());
2025     }
2026     
2027     bool shouldSpeculateUint32Array()
2028     {
2029         return isUint32ArraySpeculation(prediction());
2030     }
2031     
2032     bool shouldSpeculateFloat32Array()
2033     {
2034         return isFloat32ArraySpeculation(prediction());
2035     }
2036     
2037     bool shouldSpeculateFloat64Array()
2038     {
2039         return isFloat64ArraySpeculation(prediction());
2040     }
2041     
2042     bool shouldSpeculateArrayOrOther()
2043     {
2044         return isArrayOrOtherSpeculation(prediction());
2045     }
2046     
2047     bool shouldSpeculateObject()
2048     {
2049         return isObjectSpeculation(prediction());
2050     }
2051     
2052     bool shouldSpeculateObjectOrOther()
2053     {
2054         return isObjectOrOtherSpeculation(prediction());
2055     }
2056
2057     bool shouldSpeculateCell()
2058     {
2059         return isCellSpeculation(prediction());
2060     }
2061     
2062     bool shouldSpeculateNotCell()
2063     {
2064         return isNotCellSpeculation(prediction());
2065     }
2066     
2067     bool shouldSpeculateUntypedForArithmetic()
2068     {
2069         return isUntypedSpeculationForArithmetic(prediction());
2070     }
2071
2072     static bool shouldSpeculateUntypedForArithmetic(Node* op1, Node* op2)
2073     {
2074         return op1->shouldSpeculateUntypedForArithmetic() || op2->shouldSpeculateUntypedForArithmetic();
2075     }
2076     
2077     bool shouldSpeculateUntypedForBitOps()
2078     {
2079         return isUntypedSpeculationForBitOps(prediction());
2080     }
2081     
2082     static bool shouldSpeculateUntypedForBitOps(Node* op1, Node* op2)
2083     {
2084         return op1->shouldSpeculateUntypedForBitOps() || op2->shouldSpeculateUntypedForBitOps();
2085     }
2086     
2087     static bool shouldSpeculateBoolean(Node* op1, Node* op2)
2088     {
2089         return op1->shouldSpeculateBoolean() && op2->shouldSpeculateBoolean();
2090     }
2091     
2092     static bool shouldSpeculateInt32(Node* op1, Node* op2)
2093     {
2094         return op1->shouldSpeculateInt32() && op2->shouldSpeculateInt32();
2095     }
2096     
2097     static bool shouldSpeculateInt32OrBoolean(Node* op1, Node* op2)
2098     {
2099         return op1->shouldSpeculateInt32OrBoolean()
2100             && op2->shouldSpeculateInt32OrBoolean();
2101     }
2102     
2103     static bool shouldSpeculateInt32OrBooleanForArithmetic(Node* op1, Node* op2)
2104     {
2105         return op1->shouldSpeculateInt32OrBooleanForArithmetic()
2106             && op2->shouldSpeculateInt32OrBooleanForArithmetic();
2107     }
2108     
2109     static bool shouldSpeculateInt32OrBooleanExpectingDefined(Node* op1, Node* op2)
2110     {
2111         return op1->shouldSpeculateInt32OrBooleanExpectingDefined()
2112             && op2->shouldSpeculateInt32OrBooleanExpectingDefined();
2113     }
2114     
2115     static bool shouldSpeculateMachineInt(Node* op1, Node* op2)
2116     {
2117         return op1->shouldSpeculateMachineInt() && op2->shouldSpeculateMachineInt();
2118     }
2119     
2120     static bool shouldSpeculateNumber(Node* op1, Node* op2)
2121     {
2122         return op1->shouldSpeculateNumber() && op2->shouldSpeculateNumber();
2123     }
2124     
2125     static bool shouldSpeculateNumberOrBoolean(Node* op1, Node* op2)
2126     {
2127         return op1->shouldSpeculateNumberOrBoolean()
2128             && op2->shouldSpeculateNumberOrBoolean();
2129     }
2130     
2131     static bool shouldSpeculateNumberOrBooleanExpectingDefined(Node* op1, Node* op2)
2132     {
2133         return op1->shouldSpeculateNumberOrBooleanExpectingDefined()
2134             && op2->shouldSpeculateNumberOrBooleanExpectingDefined();
2135     }
2136
2137     static bool shouldSpeculateSymbol(Node* op1, Node* op2)
2138     {
2139         return op1->shouldSpeculateSymbol() && op2->shouldSpeculateSymbol();
2140     }
2141     
2142     static bool shouldSpeculateFinalObject(Node* op1, Node* op2)
2143     {
2144         return op1->shouldSpeculateFinalObject() && op2->shouldSpeculateFinalObject();
2145     }
2146
2147     static bool shouldSpeculateArray(Node* op1, Node* op2)
2148     {
2149         return op1->shouldSpeculateArray() && op2->shouldSpeculateArray();
2150     }
2151     
2152     bool canSpeculateInt32(RareCaseProfilingSource source)
2153     {
2154         return nodeCanSpeculateInt32(arithNodeFlags(), source);
2155     }
2156     
2157     bool canSpeculateInt52(RareCaseProfilingSource source)
2158     {
2159         return nodeCanSpeculateInt52(arithNodeFlags(), source);
2160     }
2161     
2162     RareCaseProfilingSource sourceFor(PredictionPass pass)
2163     {
2164         if (pass == PrimaryPass || child1()->sawBooleans() || (child2() && child2()->sawBooleans()))
2165             return DFGRareCase;
2166         return AllRareCases;
2167     }
2168     
2169     bool canSpeculateInt32(PredictionPass pass)
2170     {
2171         return canSpeculateInt32(sourceFor(pass));
2172     }
2173     
2174     bool canSpeculateInt52(PredictionPass pass)
2175     {
2176         return canSpeculateInt52(sourceFor(pass));
2177     }
2178
2179     bool hasTypeLocation()
2180     {
2181         return op() == ProfileType;
2182     }
2183
2184     TypeLocation* typeLocation()
2185     {
2186         ASSERT(hasTypeLocation());
2187         return reinterpret_cast<TypeLocation*>(m_opInfo);
2188     }
2189
2190     bool hasBasicBlockLocation()
2191     {
2192         return op() == ProfileControlFlow;
2193     }
2194
2195     BasicBlockLocation* basicBlockLocation()
2196     {
2197         ASSERT(hasBasicBlockLocation());
2198         return reinterpret_cast<BasicBlockLocation*>(m_opInfo);
2199     }
2200     
2201     Node* replacement() const
2202     {
2203         return m_misc.replacement;
2204     }
2205     
2206     void setReplacement(Node* replacement)
2207     {
2208         m_misc.replacement = replacement;
2209     }
2210     
2211     Epoch epoch() const
2212     {
2213         return Epoch::fromUnsigned(m_misc.epoch);
2214     }
2215     
2216     void setEpoch(Epoch epoch)
2217     {
2218         m_misc.epoch = epoch.toUnsigned();
2219     }
2220
2221     unsigned numberOfArgumentsToSkip()
2222     {
2223         ASSERT(op() == CopyRest || op() == GetRestLength);
2224         return static_cast<unsigned>(m_opInfo);
2225     }
2226
2227     void dumpChildren(PrintStream& out)
2228     {
2229         if (!child1())
2230             return;
2231         out.printf("@%u", child1()->index());
2232         if (!child2())
2233             return;
2234         out.printf(", @%u", child2()->index());
2235         if (!child3())
2236             return;
2237         out.printf(", @%u", child3()->index());
2238     }
2239     
2240     // NB. This class must have a trivial destructor.
2241
2242     NodeOrigin origin;
2243
2244     // References to up to 3 children, or links to a variable length set of children.
2245     AdjacencyList children;
2246
2247 private:
2248     unsigned m_op : 10; // real type is NodeType
2249     unsigned m_flags : 22;
2250     // The virtual register number (spill location) associated with this .
2251     VirtualRegister m_virtualRegister;
2252     // The number of uses of the result of this operation (+1 for 'must generate' nodes, which have side-effects).
2253     unsigned m_refCount;
2254     // The prediction ascribed to this node after propagation.
2255     SpeculatedType m_prediction;
2256     // Immediate values, accesses type-checked via accessors above. The first one is
2257     // big enough to store a pointer.
2258     uintptr_t m_opInfo;
2259     uintptr_t m_opInfo2;
2260
2261 public:
2262     // Fields used by various analyses.
2263     AbstractValue value;
2264     
2265     // Miscellaneous data that is usually meaningless, but can hold some analysis results
2266     // if you ask right. For example, if you do Graph::initializeNodeOwners(), Node::owner
2267     // will tell you which basic block a node belongs to. You cannot rely on this persisting
2268     // across transformations unless you do the maintenance work yourself. Other phases use
2269     // Node::replacement, but they do so manually: first you do Graph::clearReplacements()
2270     // and then you set, and use, replacement's yourself. Same thing for epoch.
2271     //
2272     // Bottom line: don't use these fields unless you initialize them yourself, or by
2273     // calling some appropriate methods that initialize them the way you want. Otherwise,
2274     // these fields are meaningless.
2275 private:
2276     union {
2277         Node* replacement;
2278         unsigned epoch;
2279     } m_misc;
2280 public:
2281     BasicBlock* owner;
2282 };
2283
2284 inline bool nodeComparator(Node* a, Node* b)
2285 {
2286     return a->index() < b->index();
2287 }
2288
2289 template<typename T>
2290 CString nodeListDump(const T& nodeList)
2291 {
2292     return sortedListDump(nodeList, nodeComparator);
2293 }
2294
2295 template<typename T>
2296 CString nodeMapDump(const T& nodeMap, DumpContext* context = 0)
2297 {
2298     Vector<typename T::KeyType> keys;
2299     for (
2300         typename T::const_iterator iter = nodeMap.begin();
2301         iter != nodeMap.end(); ++iter)
2302         keys.append(iter->key);
2303     std::sort(keys.begin(), keys.end(), nodeComparator);
2304     StringPrintStream out;
2305     CommaPrinter comma;
2306     for(unsigned i = 0; i < keys.size(); ++i)
2307         out.print(comma, keys[i], "=>", inContext(nodeMap.get(keys[i]), context));
2308     return out.toCString();
2309 }
2310
2311 } } // namespace JSC::DFG
2312
2313 namespace WTF {
2314
2315 void printInternal(PrintStream&, JSC::DFG::SwitchKind);
2316 void printInternal(PrintStream&, JSC::DFG::Node*);
2317
2318 inline JSC::DFG::Node* inContext(JSC::DFG::Node* node, JSC::DumpContext*) { return node; }
2319
2320 } // namespace WTF
2321
2322 using WTF::inContext;
2323
2324 #endif
2325 #endif