1aa15166ea211509dc5e6690e825a5179545e51e
[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);
589         m_op = PhantomNewFunction;
590         m_flags |= NodeMustGenerate;
591         m_opInfo = 0;
592         m_opInfo2 = 0;
593         children = AdjacencyList();
594     }
595
596     void convertToPhantomCreateActivation()
597     {
598         ASSERT(m_op == CreateActivation || m_op == MaterializeCreateActivation);
599         m_op = PhantomCreateActivation;
600         m_flags &= ~NodeHasVarArgs;
601         m_flags |= NodeMustGenerate;
602         m_opInfo = 0;
603         m_opInfo2 = 0;
604         children = AdjacencyList();
605     }
606
607     void convertPhantomToPhantomLocal()
608     {
609         ASSERT(m_op == Phantom && (child1()->op() == Phi || child1()->op() == SetLocal || child1()->op() == SetArgument));
610         m_op = PhantomLocal;
611         m_opInfo = child1()->m_opInfo; // Copy the variableAccessData.
612         children.setChild1(Edge());
613     }
614     
615     void convertFlushToPhantomLocal()
616     {
617         ASSERT(m_op == Flush);
618         m_op = PhantomLocal;
619         children = AdjacencyList();
620     }
621     
622     void convertToGetLocal(VariableAccessData* variable, Node* phi)
623     {
624         ASSERT(m_op == GetLocalUnlinked);
625         m_op = GetLocal;
626         m_opInfo = bitwise_cast<uintptr_t>(variable);
627         m_opInfo2 = 0;
628         children.setChild1(Edge(phi));
629     }
630     
631     void convertToToString()
632     {
633         ASSERT(m_op == ToPrimitive);
634         m_op = ToString;
635     }
636
637     void convertToArithSqrt()
638     {
639         ASSERT(m_op == ArithPow);
640         child2() = Edge();
641         m_op = ArithSqrt;
642     }
643     
644     JSValue asJSValue()
645     {
646         return constant()->value();
647     }
648      
649     bool isInt32Constant()
650     {
651         return isConstant() && constant()->value().isInt32();
652     }
653      
654     int32_t asInt32()
655     {
656         return asJSValue().asInt32();
657     }
658      
659     uint32_t asUInt32()
660     {
661         return asInt32();
662     }
663      
664     bool isDoubleConstant()
665     {
666         return isConstant() && constant()->value().isDouble();
667     }
668      
669     bool isNumberConstant()
670     {
671         return isConstant() && constant()->value().isNumber();
672     }
673     
674     double asNumber()
675     {
676         return asJSValue().asNumber();
677     }
678      
679     bool isMachineIntConstant()
680     {
681         return isConstant() && constant()->value().isMachineInt();
682     }
683      
684     int64_t asMachineInt()
685     {
686         return asJSValue().asMachineInt();
687     }
688      
689     bool isBooleanConstant()
690     {
691         return isConstant() && constant()->value().isBoolean();
692     }
693      
694     bool asBoolean()
695     {
696         return constant()->value().asBoolean();
697     }
698
699     bool isUndefinedOrNullConstant()
700     {
701         return isConstant() && constant()->value().isUndefinedOrNull();
702     }
703
704     bool isCellConstant()
705     {
706         return isConstant() && constant()->value() && constant()->value().isCell();
707     }
708      
709     JSCell* asCell()
710     {
711         return constant()->value().asCell();
712     }
713      
714     template<typename T>
715     T dynamicCastConstant()
716     {
717         if (!isCellConstant())
718             return nullptr;
719         return jsDynamicCast<T>(asCell());
720     }
721     
722     template<typename T>
723     T castConstant()
724     {
725         T result = dynamicCastConstant<T>();
726         RELEASE_ASSERT(result);
727         return result;
728     }
729
730     JSValue initializationValueForActivation() const
731     {
732         ASSERT(op() == CreateActivation);
733         return bitwise_cast<FrozenValue*>(m_opInfo2)->value();
734     }
735      
736     bool containsMovHint()
737     {
738         switch (op()) {
739         case MovHint:
740         case ZombieHint:
741             return true;
742         default:
743             return false;
744         }
745     }
746     
747     bool hasVariableAccessData(Graph&);
748     bool hasLocal(Graph& graph)
749     {
750         return hasVariableAccessData(graph);
751     }
752     
753     // This is useful for debugging code, where a node that should have a variable
754     // access data doesn't have one because it hasn't been initialized yet.
755     VariableAccessData* tryGetVariableAccessData()
756     {
757         VariableAccessData* result = reinterpret_cast<VariableAccessData*>(m_opInfo);
758         if (!result)
759             return 0;
760         return result->find();
761     }
762     
763     VariableAccessData* variableAccessData()
764     {
765         return reinterpret_cast<VariableAccessData*>(m_opInfo)->find();
766     }
767     
768     VirtualRegister local()
769     {
770         return variableAccessData()->local();
771     }
772     
773     VirtualRegister machineLocal()
774     {
775         return variableAccessData()->machineLocal();
776     }
777     
778     bool hasUnlinkedLocal()
779     {
780         switch (op()) {
781         case GetLocalUnlinked:
782         case ExtractOSREntryLocal:
783         case MovHint:
784         case ZombieHint:
785         case KillStack:
786             return true;
787         default:
788             return false;
789         }
790     }
791     
792     VirtualRegister unlinkedLocal()
793     {
794         ASSERT(hasUnlinkedLocal());
795         return static_cast<VirtualRegister>(m_opInfo);
796     }
797     
798     bool hasUnlinkedMachineLocal()
799     {
800         return op() == GetLocalUnlinked;
801     }
802     
803     void setUnlinkedMachineLocal(VirtualRegister reg)
804     {
805         ASSERT(hasUnlinkedMachineLocal());
806         m_opInfo2 = reg.offset();
807     }
808     
809     VirtualRegister unlinkedMachineLocal()
810     {
811         ASSERT(hasUnlinkedMachineLocal());
812         return VirtualRegister(m_opInfo2);
813     }
814     
815     bool hasStackAccessData()
816     {
817         switch (op()) {
818         case PutStack:
819         case GetStack:
820             return true;
821         default:
822             return false;
823         }
824     }
825     
826     StackAccessData* stackAccessData()
827     {
828         ASSERT(hasStackAccessData());
829         return bitwise_cast<StackAccessData*>(m_opInfo);
830     }
831     
832     bool hasPhi()
833     {
834         return op() == Upsilon;
835     }
836     
837     Node* phi()
838     {
839         ASSERT(hasPhi());
840         return bitwise_cast<Node*>(m_opInfo);
841     }
842
843     bool isStoreBarrier()
844     {
845         return op() == StoreBarrier;
846     }
847
848     bool hasIdentifier()
849     {
850         switch (op()) {
851         case GetById:
852         case GetByIdFlush:
853         case PutById:
854         case PutByIdFlush:
855         case PutByIdDirect:
856         case PutGetterById:
857         case PutSetterById:
858         case PutGetterSetterById:
859             return true;
860         default:
861             return false;
862         }
863     }
864
865     unsigned identifierNumber()
866     {
867         ASSERT(hasIdentifier());
868         return m_opInfo;
869     }
870
871     bool hasAccessorAttributes()
872     {
873         switch (op()) {
874         case PutGetterById:
875         case PutSetterById:
876         case PutGetterSetterById:
877         case PutGetterByVal:
878         case PutSetterByVal:
879             return true;
880         default:
881             return false;
882         }
883     }
884
885     int32_t accessorAttributes()
886     {
887         ASSERT(hasAccessorAttributes());
888         switch (op()) {
889         case PutGetterById:
890         case PutSetterById:
891         case PutGetterSetterById:
892             return m_opInfo2;
893         case PutGetterByVal:
894         case PutSetterByVal:
895             return m_opInfo;
896         default:
897             RELEASE_ASSERT_NOT_REACHED();
898             return 0;
899         }
900     }
901     
902     bool hasPromotedLocationDescriptor()
903     {
904         return op() == PutHint;
905     }
906     
907     PromotedLocationDescriptor promotedLocationDescriptor();
908     
909     // This corrects the arithmetic node flags, so that irrelevant bits are
910     // ignored. In particular, anything other than ArithMul does not need
911     // to know if it can speculate on negative zero.
912     NodeFlags arithNodeFlags()
913     {
914         NodeFlags result = m_flags & NodeArithFlagsMask;
915         if (op() == ArithMul || op() == ArithDiv || op() == ArithMod || op() == ArithNegate || op() == ArithPow || op() == ArithRound || op() == DoubleAsInt32)
916             return result;
917         return result & ~NodeBytecodeNeedsNegZero;
918     }
919     
920     bool hasConstantBuffer()
921     {
922         return op() == NewArrayBuffer;
923     }
924     
925     NewArrayBufferData* newArrayBufferData()
926     {
927         ASSERT(hasConstantBuffer());
928         return reinterpret_cast<NewArrayBufferData*>(m_opInfo);
929     }
930     
931     unsigned startConstant()
932     {
933         return newArrayBufferData()->startConstant;
934     }
935     
936     unsigned numConstants()
937     {
938         return newArrayBufferData()->numConstants;
939     }
940     
941     bool hasIndexingType()
942     {
943         switch (op()) {
944         case NewArray:
945         case NewArrayWithSize:
946         case NewArrayBuffer:
947             return true;
948         default:
949             return false;
950         }
951     }
952     
953     IndexingType indexingType()
954     {
955         ASSERT(hasIndexingType());
956         if (op() == NewArrayBuffer)
957             return newArrayBufferData()->indexingType;
958         return m_opInfo;
959     }
960     
961     bool hasTypedArrayType()
962     {
963         switch (op()) {
964         case NewTypedArray:
965             return true;
966         default:
967             return false;
968         }
969     }
970     
971     TypedArrayType typedArrayType()
972     {
973         ASSERT(hasTypedArrayType());
974         TypedArrayType result = static_cast<TypedArrayType>(m_opInfo);
975         ASSERT(isTypedView(result));
976         return result;
977     }
978     
979     bool hasInlineCapacity()
980     {
981         return op() == CreateThis;
982     }
983
984     unsigned inlineCapacity()
985     {
986         ASSERT(hasInlineCapacity());
987         return m_opInfo;
988     }
989
990     void setIndexingType(IndexingType indexingType)
991     {
992         ASSERT(hasIndexingType());
993         m_opInfo = indexingType;
994     }
995     
996     bool hasRegexpIndex()
997     {
998         return op() == NewRegexp;
999     }
1000     
1001     unsigned regexpIndex()
1002     {
1003         ASSERT(hasRegexpIndex());
1004         return m_opInfo;
1005     }
1006     
1007     bool hasScopeOffset()
1008     {
1009         return op() == GetClosureVar || op() == PutClosureVar;
1010     }
1011
1012     ScopeOffset scopeOffset()
1013     {
1014         ASSERT(hasScopeOffset());
1015         return ScopeOffset(m_opInfo);
1016     }
1017     
1018     bool hasDirectArgumentsOffset()
1019     {
1020         return op() == GetFromArguments || op() == PutToArguments;
1021     }
1022     
1023     DirectArgumentsOffset capturedArgumentsOffset()
1024     {
1025         ASSERT(hasDirectArgumentsOffset());
1026         return DirectArgumentsOffset(m_opInfo);
1027     }
1028     
1029     bool hasRegisterPointer()
1030     {
1031         return op() == GetGlobalVar || op() == GetGlobalLexicalVariable || op() == PutGlobalVariable;
1032     }
1033     
1034     WriteBarrier<Unknown>* variablePointer()
1035     {
1036         return bitwise_cast<WriteBarrier<Unknown>*>(m_opInfo);
1037     }
1038     
1039     bool hasCallVarargsData()
1040     {
1041         switch (op()) {
1042         case CallVarargs:
1043         case CallForwardVarargs:
1044         case TailCallVarargs:
1045         case TailCallForwardVarargs:
1046         case TailCallVarargsInlinedCaller:
1047         case TailCallForwardVarargsInlinedCaller:
1048         case ConstructVarargs:
1049         case ConstructForwardVarargs:
1050             return true;
1051         default:
1052             return false;
1053         }
1054     }
1055     
1056     CallVarargsData* callVarargsData()
1057     {
1058         ASSERT(hasCallVarargsData());
1059         return bitwise_cast<CallVarargsData*>(m_opInfo);
1060     }
1061     
1062     bool hasLoadVarargsData()
1063     {
1064         return op() == LoadVarargs || op() == ForwardVarargs;
1065     }
1066     
1067     LoadVarargsData* loadVarargsData()
1068     {
1069         ASSERT(hasLoadVarargsData());
1070         return bitwise_cast<LoadVarargsData*>(m_opInfo);
1071     }
1072     
1073     bool hasResult()
1074     {
1075         return !!result();
1076     }
1077
1078     bool hasInt32Result()
1079     {
1080         return result() == NodeResultInt32;
1081     }
1082     
1083     bool hasInt52Result()
1084     {
1085         return result() == NodeResultInt52;
1086     }
1087     
1088     bool hasNumberResult()
1089     {
1090         return result() == NodeResultNumber;
1091     }
1092     
1093     bool hasDoubleResult()
1094     {
1095         return result() == NodeResultDouble;
1096     }
1097     
1098     bool hasJSResult()
1099     {
1100         return result() == NodeResultJS;
1101     }
1102     
1103     bool hasBooleanResult()
1104     {
1105         return result() == NodeResultBoolean;
1106     }
1107
1108     bool hasStorageResult()
1109     {
1110         return result() == NodeResultStorage;
1111     }
1112     
1113     UseKind defaultUseKind()
1114     {
1115         return useKindForResult(result());
1116     }
1117     
1118     Edge defaultEdge()
1119     {
1120         return Edge(this, defaultUseKind());
1121     }
1122
1123     bool isJump()
1124     {
1125         return op() == Jump;
1126     }
1127
1128     bool isBranch()
1129     {
1130         return op() == Branch;
1131     }
1132     
1133     bool isSwitch()
1134     {
1135         return op() == Switch;
1136     }
1137
1138     bool isTerminal()
1139     {
1140         switch (op()) {
1141         case Jump:
1142         case Branch:
1143         case Switch:
1144         case Return:
1145         case TailCall:
1146         case TailCallVarargs:
1147         case TailCallForwardVarargs:
1148         case Unreachable:
1149             return true;
1150         default:
1151             return false;
1152         }
1153     }
1154
1155     bool isFunctionTerminal()
1156     {
1157         if (isTerminal() && !numSuccessors())
1158             return true;
1159
1160         return false;
1161     }
1162
1163     unsigned targetBytecodeOffsetDuringParsing()
1164     {
1165         ASSERT(isJump());
1166         return m_opInfo;
1167     }
1168
1169     BasicBlock*& targetBlock()
1170     {
1171         ASSERT(isJump());
1172         return *bitwise_cast<BasicBlock**>(&m_opInfo);
1173     }
1174     
1175     BranchData* branchData()
1176     {
1177         ASSERT(isBranch());
1178         return bitwise_cast<BranchData*>(m_opInfo);
1179     }
1180     
1181     SwitchData* switchData()
1182     {
1183         ASSERT(isSwitch());
1184         return bitwise_cast<SwitchData*>(m_opInfo);
1185     }
1186     
1187     unsigned numSuccessors()
1188     {
1189         switch (op()) {
1190         case Jump:
1191             return 1;
1192         case Branch:
1193             return 2;
1194         case Switch:
1195             return switchData()->cases.size() + 1;
1196         default:
1197             return 0;
1198         }
1199     }
1200     
1201     BasicBlock*& successor(unsigned index)
1202     {
1203         if (isSwitch()) {
1204             if (index < switchData()->cases.size())
1205                 return switchData()->cases[index].target.block;
1206             RELEASE_ASSERT(index == switchData()->cases.size());
1207             return switchData()->fallThrough.block;
1208         }
1209         switch (index) {
1210         case 0:
1211             if (isJump())
1212                 return targetBlock();
1213             return branchData()->taken.block;
1214         case 1:
1215             return branchData()->notTaken.block;
1216         default:
1217             RELEASE_ASSERT_NOT_REACHED();
1218             return targetBlock();
1219         }
1220     }
1221     
1222     class SuccessorsIterable {
1223     public:
1224         SuccessorsIterable()
1225             : m_terminal(nullptr)
1226         {
1227         }
1228         
1229         SuccessorsIterable(Node* terminal)
1230             : m_terminal(terminal)
1231         {
1232         }
1233         
1234         class iterator {
1235         public:
1236             iterator()
1237                 : m_terminal(nullptr)
1238                 , m_index(UINT_MAX)
1239             {
1240             }
1241             
1242             iterator(Node* terminal, unsigned index)
1243                 : m_terminal(terminal)
1244                 , m_index(index)
1245             {
1246             }
1247             
1248             BasicBlock* operator*()
1249             {
1250                 return m_terminal->successor(m_index);
1251             }
1252             
1253             iterator& operator++()
1254             {
1255                 m_index++;
1256                 return *this;
1257             }
1258             
1259             bool operator==(const iterator& other) const
1260             {
1261                 return m_index == other.m_index;
1262             }
1263             
1264             bool operator!=(const iterator& other) const
1265             {
1266                 return !(*this == other);
1267             }
1268         private:
1269             Node* m_terminal;
1270             unsigned m_index;
1271         };
1272         
1273         iterator begin()
1274         {
1275             return iterator(m_terminal, 0);
1276         }
1277         
1278         iterator end()
1279         {
1280             return iterator(m_terminal, m_terminal->numSuccessors());
1281         }
1282
1283         size_t size() const { return m_terminal->numSuccessors(); }
1284         BasicBlock* at(size_t index) const { return m_terminal->successor(index); }
1285         BasicBlock* operator[](size_t index) const { return at(index); }
1286         
1287     private:
1288         Node* m_terminal;
1289     };
1290     
1291     SuccessorsIterable successors()
1292     {
1293         return SuccessorsIterable(this);
1294     }
1295     
1296     BasicBlock*& successorForCondition(bool condition)
1297     {
1298         return branchData()->forCondition(condition);
1299     }
1300     
1301     bool hasHeapPrediction()
1302     {
1303         switch (op()) {
1304         case ArithRound:
1305         case GetDirectPname:
1306         case GetById:
1307         case GetByIdFlush:
1308         case GetByVal:
1309         case Call:
1310         case TailCallInlinedCaller:
1311         case Construct:
1312         case CallVarargs:
1313         case TailCallVarargsInlinedCaller:
1314         case ConstructVarargs:
1315         case CallForwardVarargs:
1316         case TailCallForwardVarargsInlinedCaller:
1317         case GetByOffset:
1318         case MultiGetByOffset:
1319         case GetClosureVar:
1320         case GetFromArguments:
1321         case ArrayPop:
1322         case ArrayPush:
1323         case RegExpExec:
1324         case RegExpTest:
1325         case GetGlobalVar:
1326         case GetGlobalLexicalVariable:
1327             return true;
1328         default:
1329             return false;
1330         }
1331     }
1332     
1333     SpeculatedType getHeapPrediction()
1334     {
1335         ASSERT(hasHeapPrediction());
1336         return static_cast<SpeculatedType>(m_opInfo2);
1337     }
1338
1339     void setHeapPrediction(SpeculatedType prediction)
1340     {
1341         ASSERT(hasHeapPrediction());
1342         m_opInfo2 = prediction;
1343     }
1344     
1345     bool hasCellOperand()
1346     {
1347         switch (op()) {
1348         case CheckCell:
1349         case NewFunction:
1350         case NewArrowFunction:
1351         case CreateActivation:
1352         case MaterializeCreateActivation:
1353             return true;
1354         default:
1355             return false;
1356         }
1357     }
1358
1359     FrozenValue* cellOperand()
1360     {
1361         ASSERT(hasCellOperand());
1362         return reinterpret_cast<FrozenValue*>(m_opInfo);
1363     }
1364     
1365     template<typename T>
1366     T castOperand()
1367     {
1368         return cellOperand()->cast<T>();
1369     }
1370     
1371     void setCellOperand(FrozenValue* value)
1372     {
1373         ASSERT(hasCellOperand());
1374         m_opInfo = bitwise_cast<uintptr_t>(value);
1375     }
1376     
1377     bool hasWatchpointSet()
1378     {
1379         return op() == NotifyWrite;
1380     }
1381     
1382     WatchpointSet* watchpointSet()
1383     {
1384         ASSERT(hasWatchpointSet());
1385         return reinterpret_cast<WatchpointSet*>(m_opInfo);
1386     }
1387     
1388     bool hasStoragePointer()
1389     {
1390         return op() == ConstantStoragePointer;
1391     }
1392     
1393     void* storagePointer()
1394     {
1395         ASSERT(hasStoragePointer());
1396         return reinterpret_cast<void*>(m_opInfo);
1397     }
1398
1399     bool hasUidOperand()
1400     {
1401         return op() == CheckIdent;
1402     }
1403
1404     UniquedStringImpl* uidOperand()
1405     {
1406         ASSERT(hasUidOperand());
1407         return reinterpret_cast<UniquedStringImpl*>(m_opInfo);
1408     }
1409
1410     bool hasTransition()
1411     {
1412         switch (op()) {
1413         case PutStructure:
1414         case AllocatePropertyStorage:
1415         case ReallocatePropertyStorage:
1416             return true;
1417         default:
1418             return false;
1419         }
1420     }
1421     
1422     Transition* transition()
1423     {
1424         ASSERT(hasTransition());
1425         return reinterpret_cast<Transition*>(m_opInfo);
1426     }
1427     
1428     bool hasStructureSet()
1429     {
1430         switch (op()) {
1431         case CheckStructure:
1432         case CheckStructureImmediate:
1433         case MaterializeNewObject:
1434             return true;
1435         default:
1436             return false;
1437         }
1438     }
1439     
1440     StructureSet& structureSet()
1441     {
1442         ASSERT(hasStructureSet());
1443         return *reinterpret_cast<StructureSet*>(m_opInfo);
1444     }
1445     
1446     bool hasStructure()
1447     {
1448         switch (op()) {
1449         case ArrayifyToStructure:
1450         case NewObject:
1451         case NewStringObject:
1452             return true;
1453         default:
1454             return false;
1455         }
1456     }
1457     
1458     Structure* structure()
1459     {
1460         ASSERT(hasStructure());
1461         return reinterpret_cast<Structure*>(m_opInfo);
1462     }
1463     
1464     bool hasStorageAccessData()
1465     {
1466         switch (op()) {
1467         case GetByOffset:
1468         case PutByOffset:
1469         case GetGetterSetterByOffset:
1470             return true;
1471         default:
1472             return false;
1473         }
1474     }
1475     
1476     StorageAccessData& storageAccessData()
1477     {
1478         ASSERT(hasStorageAccessData());
1479         return *bitwise_cast<StorageAccessData*>(m_opInfo);
1480     }
1481     
1482     bool hasMultiGetByOffsetData()
1483     {
1484         return op() == MultiGetByOffset;
1485     }
1486     
1487     MultiGetByOffsetData& multiGetByOffsetData()
1488     {
1489         ASSERT(hasMultiGetByOffsetData());
1490         return *reinterpret_cast<MultiGetByOffsetData*>(m_opInfo);
1491     }
1492     
1493     bool hasMultiPutByOffsetData()
1494     {
1495         return op() == MultiPutByOffset;
1496     }
1497     
1498     MultiPutByOffsetData& multiPutByOffsetData()
1499     {
1500         ASSERT(hasMultiPutByOffsetData());
1501         return *reinterpret_cast<MultiPutByOffsetData*>(m_opInfo);
1502     }
1503     
1504     bool hasObjectMaterializationData()
1505     {
1506         switch (op()) {
1507         case MaterializeNewObject:
1508         case MaterializeCreateActivation:
1509             return true;
1510
1511         default:
1512             return false;
1513         }
1514     }
1515     
1516     ObjectMaterializationData& objectMaterializationData()
1517     {
1518         ASSERT(hasObjectMaterializationData());
1519         return *reinterpret_cast<ObjectMaterializationData*>(m_opInfo2);
1520     }
1521
1522     bool isObjectAllocation()
1523     {
1524         switch (op()) {
1525         case NewObject:
1526         case MaterializeNewObject:
1527             return true;
1528         default:
1529             return false;
1530         }
1531     }
1532     
1533     bool isPhantomObjectAllocation()
1534     {
1535         switch (op()) {
1536         case PhantomNewObject:
1537             return true;
1538         default:
1539             return false;
1540         }
1541     }
1542     
1543     bool isActivationAllocation()
1544     {
1545         switch (op()) {
1546         case CreateActivation:
1547         case MaterializeCreateActivation:
1548             return true;
1549         default:
1550             return false;
1551         }
1552     }
1553
1554     bool isPhantomActivationAllocation()
1555     {
1556         switch (op()) {
1557         case PhantomCreateActivation:
1558             return true;
1559         default:
1560             return false;
1561         }
1562     }
1563
1564     bool isFunctionAllocation()
1565     {
1566         switch (op()) {
1567         case NewArrowFunction:
1568         case NewFunction:
1569             return true;
1570         default:
1571             return false;
1572         }
1573     }
1574
1575     bool isPhantomFunctionAllocation()
1576     {
1577         switch (op()) {
1578         case PhantomNewFunction:
1579             return true;
1580         default:
1581             return false;
1582         }
1583     }
1584
1585     bool isPhantomAllocation()
1586     {
1587         switch (op()) {
1588         case PhantomNewObject:
1589         case PhantomDirectArguments:
1590         case PhantomClonedArguments:
1591         case PhantomNewFunction:
1592         case PhantomCreateActivation:
1593             return true;
1594         default:
1595             return false;
1596         }
1597     }
1598     
1599     bool hasArrayMode()
1600     {
1601         switch (op()) {
1602         case GetIndexedPropertyStorage:
1603         case GetArrayLength:
1604         case PutByValDirect:
1605         case PutByVal:
1606         case PutByValAlias:
1607         case GetByVal:
1608         case StringCharAt:
1609         case StringCharCodeAt:
1610         case CheckArray:
1611         case Arrayify:
1612         case ArrayifyToStructure:
1613         case ArrayPush:
1614         case ArrayPop:
1615         case HasIndexedProperty:
1616             return true;
1617         default:
1618             return false;
1619         }
1620     }
1621     
1622     ArrayMode arrayMode()
1623     {
1624         ASSERT(hasArrayMode());
1625         if (op() == ArrayifyToStructure)
1626             return ArrayMode::fromWord(m_opInfo2);
1627         return ArrayMode::fromWord(m_opInfo);
1628     }
1629     
1630     bool setArrayMode(ArrayMode arrayMode)
1631     {
1632         ASSERT(hasArrayMode());
1633         if (this->arrayMode() == arrayMode)
1634             return false;
1635         m_opInfo = arrayMode.asWord();
1636         return true;
1637     }
1638     
1639     bool hasArithMode()
1640     {
1641         switch (op()) {
1642         case ArithAdd:
1643         case ArithSub:
1644         case ArithNegate:
1645         case ArithMul:
1646         case ArithDiv:
1647         case ArithMod:
1648         case UInt32ToNumber:
1649         case DoubleAsInt32:
1650             return true;
1651         default:
1652             return false;
1653         }
1654     }
1655
1656     Arith::Mode arithMode()
1657     {
1658         ASSERT(hasArithMode());
1659         return static_cast<Arith::Mode>(m_opInfo);
1660     }
1661     
1662     void setArithMode(Arith::Mode mode)
1663     {
1664         m_opInfo = mode;
1665     }
1666
1667     bool hasArithRoundingMode()
1668     {
1669         return op() == ArithRound;
1670     }
1671
1672     Arith::RoundingMode arithRoundingMode()
1673     {
1674         ASSERT(hasArithRoundingMode());
1675         return static_cast<Arith::RoundingMode>(m_opInfo);
1676     }
1677
1678     void setArithRoundingMode(Arith::RoundingMode mode)
1679     {
1680         ASSERT(hasArithRoundingMode());
1681         m_opInfo = static_cast<uintptr_t>(mode);
1682     }
1683     
1684     bool hasVirtualRegister()
1685     {
1686         return m_virtualRegister.isValid();
1687     }
1688     
1689     VirtualRegister virtualRegister()
1690     {
1691         ASSERT(hasResult());
1692         ASSERT(m_virtualRegister.isValid());
1693         return m_virtualRegister;
1694     }
1695     
1696     void setVirtualRegister(VirtualRegister virtualRegister)
1697     {
1698         ASSERT(hasResult());
1699         ASSERT(!m_virtualRegister.isValid());
1700         m_virtualRegister = virtualRegister;
1701     }
1702     
1703     bool hasExecutionCounter()
1704     {
1705         return op() == CountExecution;
1706     }
1707     
1708     Profiler::ExecutionCounter* executionCounter()
1709     {
1710         return bitwise_cast<Profiler::ExecutionCounter*>(m_opInfo);
1711     }
1712
1713     bool shouldGenerate()
1714     {
1715         return m_refCount;
1716     }
1717     
1718     bool isSemanticallySkippable()
1719     {
1720         return op() == CountExecution;
1721     }
1722
1723     unsigned refCount()
1724     {
1725         return m_refCount;
1726     }
1727
1728     unsigned postfixRef()
1729     {
1730         return m_refCount++;
1731     }
1732
1733     unsigned adjustedRefCount()
1734     {
1735         return mustGenerate() ? m_refCount - 1 : m_refCount;
1736     }
1737     
1738     void setRefCount(unsigned refCount)
1739     {
1740         m_refCount = refCount;
1741     }
1742     
1743     Edge& child1()
1744     {
1745         ASSERT(!(m_flags & NodeHasVarArgs));
1746         return children.child1();
1747     }
1748     
1749     // This is useful if you want to do a fast check on the first child
1750     // before also doing a check on the opcode. Use this with care and
1751     // avoid it if possible.
1752     Edge child1Unchecked()
1753     {
1754         return children.child1Unchecked();
1755     }
1756
1757     Edge& child2()
1758     {
1759         ASSERT(!(m_flags & NodeHasVarArgs));
1760         return children.child2();
1761     }
1762
1763     Edge& child3()
1764     {
1765         ASSERT(!(m_flags & NodeHasVarArgs));
1766         return children.child3();
1767     }
1768     
1769     unsigned firstChild()
1770     {
1771         ASSERT(m_flags & NodeHasVarArgs);
1772         return children.firstChild();
1773     }
1774     
1775     unsigned numChildren()
1776     {
1777         ASSERT(m_flags & NodeHasVarArgs);
1778         return children.numChildren();
1779     }
1780     
1781     UseKind binaryUseKind()
1782     {
1783         ASSERT(child1().useKind() == child2().useKind());
1784         return child1().useKind();
1785     }
1786     
1787     bool isBinaryUseKind(UseKind left, UseKind right)
1788     {
1789         return child1().useKind() == left && child2().useKind() == right;
1790     }
1791     
1792     bool isBinaryUseKind(UseKind useKind)
1793     {
1794         return isBinaryUseKind(useKind, useKind);
1795     }
1796     
1797     Edge childFor(UseKind useKind)
1798     {
1799         if (child1().useKind() == useKind)
1800             return child1();
1801         if (child2().useKind() == useKind)
1802             return child2();
1803         if (child3().useKind() == useKind)
1804             return child3();
1805         return Edge();
1806     }
1807     
1808     SpeculatedType prediction()
1809     {
1810         return m_prediction;
1811     }
1812     
1813     bool predict(SpeculatedType prediction)
1814     {
1815         return mergeSpeculation(m_prediction, prediction);
1816     }
1817     
1818     bool shouldSpeculateInt32()
1819     {
1820         return isInt32Speculation(prediction());
1821     }
1822     
1823     bool sawBooleans()
1824     {
1825         return !!(prediction() & SpecBoolean);
1826     }
1827     
1828     bool shouldSpeculateInt32OrBoolean()
1829     {
1830         return isInt32OrBooleanSpeculation(prediction());
1831     }
1832     
1833     bool shouldSpeculateInt32ForArithmetic()
1834     {
1835         return isInt32SpeculationForArithmetic(prediction());
1836     }
1837     
1838     bool shouldSpeculateInt32OrBooleanForArithmetic()
1839     {
1840         return isInt32OrBooleanSpeculationForArithmetic(prediction());
1841     }
1842     
1843     bool shouldSpeculateInt32OrBooleanExpectingDefined()
1844     {
1845         return isInt32OrBooleanSpeculationExpectingDefined(prediction());
1846     }
1847     
1848     bool shouldSpeculateMachineInt()
1849     {
1850         return isMachineIntSpeculation(prediction());
1851     }
1852     
1853     bool shouldSpeculateDouble()
1854     {
1855         return isDoubleSpeculation(prediction());
1856     }
1857     
1858     bool shouldSpeculateDoubleReal()
1859     {
1860         return isDoubleRealSpeculation(prediction());
1861     }
1862     
1863     bool shouldSpeculateNumber()
1864     {
1865         return isFullNumberSpeculation(prediction());
1866     }
1867     
1868     bool shouldSpeculateNumberOrBoolean()
1869     {
1870         return isFullNumberOrBooleanSpeculation(prediction());
1871     }
1872     
1873     bool shouldSpeculateNumberOrBooleanExpectingDefined()
1874     {
1875         return isFullNumberOrBooleanSpeculationExpectingDefined(prediction());
1876     }
1877     
1878     bool shouldSpeculateBoolean()
1879     {
1880         return isBooleanSpeculation(prediction());
1881     }
1882     
1883     bool shouldSpeculateOther()
1884     {
1885         return isOtherSpeculation(prediction());
1886     }
1887     
1888     bool shouldSpeculateMisc()
1889     {
1890         return isMiscSpeculation(prediction());
1891     }
1892    
1893     bool shouldSpeculateStringIdent()
1894     {
1895         return isStringIdentSpeculation(prediction());
1896     }
1897     
1898     bool shouldSpeculateNotStringVar()
1899     {
1900         return isNotStringVarSpeculation(prediction());
1901     }
1902  
1903     bool shouldSpeculateString()
1904     {
1905         return isStringSpeculation(prediction());
1906     }
1907  
1908     bool shouldSpeculateStringObject()
1909     {
1910         return isStringObjectSpeculation(prediction());
1911     }
1912     
1913     bool shouldSpeculateStringOrStringObject()
1914     {
1915         return isStringOrStringObjectSpeculation(prediction());
1916     }
1917
1918     bool shouldSpeculateSymbol()
1919     {
1920         return isSymbolSpeculation(prediction());
1921     }
1922     
1923     bool shouldSpeculateFinalObject()
1924     {
1925         return isFinalObjectSpeculation(prediction());
1926     }
1927     
1928     bool shouldSpeculateFinalObjectOrOther()
1929     {
1930         return isFinalObjectOrOtherSpeculation(prediction());
1931     }
1932     
1933     bool shouldSpeculateArray()
1934     {
1935         return isArraySpeculation(prediction());
1936     }
1937     
1938     bool shouldSpeculateDirectArguments()
1939     {
1940         return isDirectArgumentsSpeculation(prediction());
1941     }
1942     
1943     bool shouldSpeculateScopedArguments()
1944     {
1945         return isScopedArgumentsSpeculation(prediction());
1946     }
1947     
1948     bool shouldSpeculateInt8Array()
1949     {
1950         return isInt8ArraySpeculation(prediction());
1951     }
1952     
1953     bool shouldSpeculateInt16Array()
1954     {
1955         return isInt16ArraySpeculation(prediction());
1956     }
1957     
1958     bool shouldSpeculateInt32Array()
1959     {
1960         return isInt32ArraySpeculation(prediction());
1961     }
1962     
1963     bool shouldSpeculateUint8Array()
1964     {
1965         return isUint8ArraySpeculation(prediction());
1966     }
1967
1968     bool shouldSpeculateUint8ClampedArray()
1969     {
1970         return isUint8ClampedArraySpeculation(prediction());
1971     }
1972     
1973     bool shouldSpeculateUint16Array()
1974     {
1975         return isUint16ArraySpeculation(prediction());
1976     }
1977     
1978     bool shouldSpeculateUint32Array()
1979     {
1980         return isUint32ArraySpeculation(prediction());
1981     }
1982     
1983     bool shouldSpeculateFloat32Array()
1984     {
1985         return isFloat32ArraySpeculation(prediction());
1986     }
1987     
1988     bool shouldSpeculateFloat64Array()
1989     {
1990         return isFloat64ArraySpeculation(prediction());
1991     }
1992     
1993     bool shouldSpeculateArrayOrOther()
1994     {
1995         return isArrayOrOtherSpeculation(prediction());
1996     }
1997     
1998     bool shouldSpeculateObject()
1999     {
2000         return isObjectSpeculation(prediction());
2001     }
2002     
2003     bool shouldSpeculateObjectOrOther()
2004     {
2005         return isObjectOrOtherSpeculation(prediction());
2006     }
2007
2008     bool shouldSpeculateCell()
2009     {
2010         return isCellSpeculation(prediction());
2011     }
2012     
2013     bool shouldSpeculateNotCell()
2014     {
2015         return isNotCellSpeculation(prediction());
2016     }
2017     
2018     bool shouldSpeculateUntypedForArithmetic()
2019     {
2020         return isUntypedSpeculationForArithmetic(prediction());
2021     }
2022
2023     static bool shouldSpeculateUntypedForArithmetic(Node* op1, Node* op2)
2024     {
2025         return op1->shouldSpeculateUntypedForArithmetic() || op2->shouldSpeculateUntypedForArithmetic();
2026     }
2027     
2028     static bool shouldSpeculateBoolean(Node* op1, Node* op2)
2029     {
2030         return op1->shouldSpeculateBoolean() && op2->shouldSpeculateBoolean();
2031     }
2032     
2033     static bool shouldSpeculateInt32(Node* op1, Node* op2)
2034     {
2035         return op1->shouldSpeculateInt32() && op2->shouldSpeculateInt32();
2036     }
2037     
2038     static bool shouldSpeculateInt32OrBoolean(Node* op1, Node* op2)
2039     {
2040         return op1->shouldSpeculateInt32OrBoolean()
2041             && op2->shouldSpeculateInt32OrBoolean();
2042     }
2043     
2044     static bool shouldSpeculateInt32OrBooleanForArithmetic(Node* op1, Node* op2)
2045     {
2046         return op1->shouldSpeculateInt32OrBooleanForArithmetic()
2047             && op2->shouldSpeculateInt32OrBooleanForArithmetic();
2048     }
2049     
2050     static bool shouldSpeculateInt32OrBooleanExpectingDefined(Node* op1, Node* op2)
2051     {
2052         return op1->shouldSpeculateInt32OrBooleanExpectingDefined()
2053             && op2->shouldSpeculateInt32OrBooleanExpectingDefined();
2054     }
2055     
2056     static bool shouldSpeculateMachineInt(Node* op1, Node* op2)
2057     {
2058         return op1->shouldSpeculateMachineInt() && op2->shouldSpeculateMachineInt();
2059     }
2060     
2061     static bool shouldSpeculateNumber(Node* op1, Node* op2)
2062     {
2063         return op1->shouldSpeculateNumber() && op2->shouldSpeculateNumber();
2064     }
2065     
2066     static bool shouldSpeculateNumberOrBoolean(Node* op1, Node* op2)
2067     {
2068         return op1->shouldSpeculateNumberOrBoolean()
2069             && op2->shouldSpeculateNumberOrBoolean();
2070     }
2071     
2072     static bool shouldSpeculateNumberOrBooleanExpectingDefined(Node* op1, Node* op2)
2073     {
2074         return op1->shouldSpeculateNumberOrBooleanExpectingDefined()
2075             && op2->shouldSpeculateNumberOrBooleanExpectingDefined();
2076     }
2077
2078     static bool shouldSpeculateSymbol(Node* op1, Node* op2)
2079     {
2080         return op1->shouldSpeculateSymbol() && op2->shouldSpeculateSymbol();
2081     }
2082     
2083     static bool shouldSpeculateFinalObject(Node* op1, Node* op2)
2084     {
2085         return op1->shouldSpeculateFinalObject() && op2->shouldSpeculateFinalObject();
2086     }
2087
2088     static bool shouldSpeculateArray(Node* op1, Node* op2)
2089     {
2090         return op1->shouldSpeculateArray() && op2->shouldSpeculateArray();
2091     }
2092     
2093     bool canSpeculateInt32(RareCaseProfilingSource source)
2094     {
2095         return nodeCanSpeculateInt32(arithNodeFlags(), source);
2096     }
2097     
2098     bool canSpeculateInt52(RareCaseProfilingSource source)
2099     {
2100         return nodeCanSpeculateInt52(arithNodeFlags(), source);
2101     }
2102     
2103     RareCaseProfilingSource sourceFor(PredictionPass pass)
2104     {
2105         if (pass == PrimaryPass || child1()->sawBooleans() || (child2() && child2()->sawBooleans()))
2106             return DFGRareCase;
2107         return AllRareCases;
2108     }
2109     
2110     bool canSpeculateInt32(PredictionPass pass)
2111     {
2112         return canSpeculateInt32(sourceFor(pass));
2113     }
2114     
2115     bool canSpeculateInt52(PredictionPass pass)
2116     {
2117         return canSpeculateInt52(sourceFor(pass));
2118     }
2119
2120     bool hasTypeLocation()
2121     {
2122         return op() == ProfileType;
2123     }
2124
2125     TypeLocation* typeLocation()
2126     {
2127         ASSERT(hasTypeLocation());
2128         return reinterpret_cast<TypeLocation*>(m_opInfo);
2129     }
2130
2131     bool hasBasicBlockLocation()
2132     {
2133         return op() == ProfileControlFlow;
2134     }
2135
2136     BasicBlockLocation* basicBlockLocation()
2137     {
2138         ASSERT(hasBasicBlockLocation());
2139         return reinterpret_cast<BasicBlockLocation*>(m_opInfo);
2140     }
2141     
2142     Node* replacement() const
2143     {
2144         return m_misc.replacement;
2145     }
2146     
2147     void setReplacement(Node* replacement)
2148     {
2149         m_misc.replacement = replacement;
2150     }
2151     
2152     Epoch epoch() const
2153     {
2154         return Epoch::fromUnsigned(m_misc.epoch);
2155     }
2156     
2157     void setEpoch(Epoch epoch)
2158     {
2159         m_misc.epoch = epoch.toUnsigned();
2160     }
2161
2162     unsigned numberOfArgumentsToSkip()
2163     {
2164         ASSERT(op() == CopyRest || op() == GetRestLength);
2165         return static_cast<unsigned>(m_opInfo);
2166     }
2167
2168     void dumpChildren(PrintStream& out)
2169     {
2170         if (!child1())
2171             return;
2172         out.printf("@%u", child1()->index());
2173         if (!child2())
2174             return;
2175         out.printf(", @%u", child2()->index());
2176         if (!child3())
2177             return;
2178         out.printf(", @%u", child3()->index());
2179     }
2180     
2181     // NB. This class must have a trivial destructor.
2182
2183     NodeOrigin origin;
2184
2185     // References to up to 3 children, or links to a variable length set of children.
2186     AdjacencyList children;
2187
2188 private:
2189     unsigned m_op : 10; // real type is NodeType
2190     unsigned m_flags : 22;
2191     // The virtual register number (spill location) associated with this .
2192     VirtualRegister m_virtualRegister;
2193     // The number of uses of the result of this operation (+1 for 'must generate' nodes, which have side-effects).
2194     unsigned m_refCount;
2195     // The prediction ascribed to this node after propagation.
2196     SpeculatedType m_prediction;
2197     // Immediate values, accesses type-checked via accessors above. The first one is
2198     // big enough to store a pointer.
2199     uintptr_t m_opInfo;
2200     uintptr_t m_opInfo2;
2201
2202 public:
2203     // Fields used by various analyses.
2204     AbstractValue value;
2205     
2206     // Miscellaneous data that is usually meaningless, but can hold some analysis results
2207     // if you ask right. For example, if you do Graph::initializeNodeOwners(), Node::owner
2208     // will tell you which basic block a node belongs to. You cannot rely on this persisting
2209     // across transformations unless you do the maintenance work yourself. Other phases use
2210     // Node::replacement, but they do so manually: first you do Graph::clearReplacements()
2211     // and then you set, and use, replacement's yourself. Same thing for epoch.
2212     //
2213     // Bottom line: don't use these fields unless you initialize them yourself, or by
2214     // calling some appropriate methods that initialize them the way you want. Otherwise,
2215     // these fields are meaningless.
2216 private:
2217     union {
2218         Node* replacement;
2219         unsigned epoch;
2220     } m_misc;
2221 public:
2222     BasicBlock* owner;
2223 };
2224
2225 inline bool nodeComparator(Node* a, Node* b)
2226 {
2227     return a->index() < b->index();
2228 }
2229
2230 template<typename T>
2231 CString nodeListDump(const T& nodeList)
2232 {
2233     return sortedListDump(nodeList, nodeComparator);
2234 }
2235
2236 template<typename T>
2237 CString nodeMapDump(const T& nodeMap, DumpContext* context = 0)
2238 {
2239     Vector<typename T::KeyType> keys;
2240     for (
2241         typename T::const_iterator iter = nodeMap.begin();
2242         iter != nodeMap.end(); ++iter)
2243         keys.append(iter->key);
2244     std::sort(keys.begin(), keys.end(), nodeComparator);
2245     StringPrintStream out;
2246     CommaPrinter comma;
2247     for(unsigned i = 0; i < keys.size(); ++i)
2248         out.print(comma, keys[i], "=>", inContext(nodeMap.get(keys[i]), context));
2249     return out.toCString();
2250 }
2251
2252 } } // namespace JSC::DFG
2253
2254 namespace WTF {
2255
2256 void printInternal(PrintStream&, JSC::DFG::SwitchKind);
2257 void printInternal(PrintStream&, JSC::DFG::Node*);
2258
2259 inline JSC::DFG::Node* inContext(JSC::DFG::Node* node, JSC::DumpContext*) { return node; }
2260
2261 } // namespace WTF
2262
2263 using WTF::inContext;
2264
2265 #endif
2266 #endif