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