Object cycles should not prevent allocation elimination/sinking
[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. This is the first actual argument, not this.
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         return op() == StoreBarrier;
834     }
835
836     bool hasIdentifier()
837     {
838         switch (op()) {
839         case GetById:
840         case GetByIdFlush:
841         case PutById:
842         case PutByIdFlush:
843         case PutByIdDirect:
844             return true;
845         default:
846             return false;
847         }
848     }
849
850     unsigned identifierNumber()
851     {
852         ASSERT(hasIdentifier());
853         return m_opInfo;
854     }
855     
856     bool hasPromotedLocationDescriptor()
857     {
858         return op() == PutHint;
859     }
860     
861     PromotedLocationDescriptor promotedLocationDescriptor();
862     
863     // This corrects the arithmetic node flags, so that irrelevant bits are
864     // ignored. In particular, anything other than ArithMul does not need
865     // to know if it can speculate on negative zero.
866     NodeFlags arithNodeFlags()
867     {
868         NodeFlags result = m_flags & NodeArithFlagsMask;
869         if (op() == ArithMul || op() == ArithDiv || op() == ArithMod || op() == ArithNegate || op() == ArithPow || op() == ArithRound || op() == DoubleAsInt32)
870             return result;
871         return result & ~NodeBytecodeNeedsNegZero;
872     }
873     
874     bool hasConstantBuffer()
875     {
876         return op() == NewArrayBuffer;
877     }
878     
879     NewArrayBufferData* newArrayBufferData()
880     {
881         ASSERT(hasConstantBuffer());
882         return reinterpret_cast<NewArrayBufferData*>(m_opInfo);
883     }
884     
885     unsigned startConstant()
886     {
887         return newArrayBufferData()->startConstant;
888     }
889     
890     unsigned numConstants()
891     {
892         return newArrayBufferData()->numConstants;
893     }
894     
895     bool hasIndexingType()
896     {
897         switch (op()) {
898         case NewArray:
899         case NewArrayWithSize:
900         case NewArrayBuffer:
901             return true;
902         default:
903             return false;
904         }
905     }
906     
907     IndexingType indexingType()
908     {
909         ASSERT(hasIndexingType());
910         if (op() == NewArrayBuffer)
911             return newArrayBufferData()->indexingType;
912         return m_opInfo;
913     }
914     
915     bool hasTypedArrayType()
916     {
917         switch (op()) {
918         case NewTypedArray:
919             return true;
920         default:
921             return false;
922         }
923     }
924     
925     TypedArrayType typedArrayType()
926     {
927         ASSERT(hasTypedArrayType());
928         TypedArrayType result = static_cast<TypedArrayType>(m_opInfo);
929         ASSERT(isTypedView(result));
930         return result;
931     }
932     
933     bool hasInlineCapacity()
934     {
935         return op() == CreateThis;
936     }
937
938     unsigned inlineCapacity()
939     {
940         ASSERT(hasInlineCapacity());
941         return m_opInfo;
942     }
943
944     void setIndexingType(IndexingType indexingType)
945     {
946         ASSERT(hasIndexingType());
947         m_opInfo = indexingType;
948     }
949     
950     bool hasRegexpIndex()
951     {
952         return op() == NewRegexp;
953     }
954     
955     unsigned regexpIndex()
956     {
957         ASSERT(hasRegexpIndex());
958         return m_opInfo;
959     }
960     
961     bool hasScopeOffset()
962     {
963         return op() == GetClosureVar || op() == PutClosureVar;
964     }
965
966     ScopeOffset scopeOffset()
967     {
968         ASSERT(hasScopeOffset());
969         return ScopeOffset(m_opInfo);
970     }
971     
972     bool hasDirectArgumentsOffset()
973     {
974         return op() == GetFromArguments || op() == PutToArguments;
975     }
976     
977     DirectArgumentsOffset capturedArgumentsOffset()
978     {
979         ASSERT(hasDirectArgumentsOffset());
980         return DirectArgumentsOffset(m_opInfo);
981     }
982     
983     bool hasRegisterPointer()
984     {
985         return op() == GetGlobalVar || op() == PutGlobalVar;
986     }
987     
988     WriteBarrier<Unknown>* variablePointer()
989     {
990         return bitwise_cast<WriteBarrier<Unknown>*>(m_opInfo);
991     }
992     
993     bool hasCallVarargsData()
994     {
995         switch (op()) {
996         case CallVarargs:
997         case CallForwardVarargs:
998         case ConstructVarargs:
999         case ConstructForwardVarargs:
1000             return true;
1001         default:
1002             return false;
1003         }
1004     }
1005     
1006     CallVarargsData* callVarargsData()
1007     {
1008         ASSERT(hasCallVarargsData());
1009         return bitwise_cast<CallVarargsData*>(m_opInfo);
1010     }
1011     
1012     bool hasLoadVarargsData()
1013     {
1014         return op() == LoadVarargs || op() == ForwardVarargs;
1015     }
1016     
1017     LoadVarargsData* loadVarargsData()
1018     {
1019         ASSERT(hasLoadVarargsData());
1020         return bitwise_cast<LoadVarargsData*>(m_opInfo);
1021     }
1022     
1023     bool hasResult()
1024     {
1025         return !!result();
1026     }
1027
1028     bool hasInt32Result()
1029     {
1030         return result() == NodeResultInt32;
1031     }
1032     
1033     bool hasInt52Result()
1034     {
1035         return result() == NodeResultInt52;
1036     }
1037     
1038     bool hasNumberResult()
1039     {
1040         return result() == NodeResultNumber;
1041     }
1042     
1043     bool hasDoubleResult()
1044     {
1045         return result() == NodeResultDouble;
1046     }
1047     
1048     bool hasJSResult()
1049     {
1050         return result() == NodeResultJS;
1051     }
1052     
1053     bool hasBooleanResult()
1054     {
1055         return result() == NodeResultBoolean;
1056     }
1057
1058     bool hasStorageResult()
1059     {
1060         return result() == NodeResultStorage;
1061     }
1062     
1063     UseKind defaultUseKind()
1064     {
1065         return useKindForResult(result());
1066     }
1067     
1068     Edge defaultEdge()
1069     {
1070         return Edge(this, defaultUseKind());
1071     }
1072
1073     bool isJump()
1074     {
1075         return op() == Jump;
1076     }
1077
1078     bool isBranch()
1079     {
1080         return op() == Branch;
1081     }
1082     
1083     bool isSwitch()
1084     {
1085         return op() == Switch;
1086     }
1087
1088     bool isTerminal()
1089     {
1090         switch (op()) {
1091         case Jump:
1092         case Branch:
1093         case Switch:
1094         case Return:
1095         case Unreachable:
1096             return true;
1097         default:
1098             return false;
1099         }
1100     }
1101
1102     unsigned targetBytecodeOffsetDuringParsing()
1103     {
1104         ASSERT(isJump());
1105         return m_opInfo;
1106     }
1107
1108     BasicBlock*& targetBlock()
1109     {
1110         ASSERT(isJump());
1111         return *bitwise_cast<BasicBlock**>(&m_opInfo);
1112     }
1113     
1114     BranchData* branchData()
1115     {
1116         ASSERT(isBranch());
1117         return bitwise_cast<BranchData*>(m_opInfo);
1118     }
1119     
1120     SwitchData* switchData()
1121     {
1122         ASSERT(isSwitch());
1123         return bitwise_cast<SwitchData*>(m_opInfo);
1124     }
1125     
1126     unsigned numSuccessors()
1127     {
1128         switch (op()) {
1129         case Jump:
1130             return 1;
1131         case Branch:
1132             return 2;
1133         case Switch:
1134             return switchData()->cases.size() + 1;
1135         default:
1136             return 0;
1137         }
1138     }
1139     
1140     BasicBlock*& successor(unsigned index)
1141     {
1142         if (isSwitch()) {
1143             if (index < switchData()->cases.size())
1144                 return switchData()->cases[index].target.block;
1145             RELEASE_ASSERT(index == switchData()->cases.size());
1146             return switchData()->fallThrough.block;
1147         }
1148         switch (index) {
1149         case 0:
1150             if (isJump())
1151                 return targetBlock();
1152             return branchData()->taken.block;
1153         case 1:
1154             return branchData()->notTaken.block;
1155         default:
1156             RELEASE_ASSERT_NOT_REACHED();
1157             return targetBlock();
1158         }
1159     }
1160     
1161     class SuccessorsIterable {
1162     public:
1163         SuccessorsIterable()
1164             : m_terminal(nullptr)
1165         {
1166         }
1167         
1168         SuccessorsIterable(Node* terminal)
1169             : m_terminal(terminal)
1170         {
1171         }
1172         
1173         class iterator {
1174         public:
1175             iterator()
1176                 : m_terminal(nullptr)
1177                 , m_index(UINT_MAX)
1178             {
1179             }
1180             
1181             iterator(Node* terminal, unsigned index)
1182                 : m_terminal(terminal)
1183                 , m_index(index)
1184             {
1185             }
1186             
1187             BasicBlock* operator*()
1188             {
1189                 return m_terminal->successor(m_index);
1190             }
1191             
1192             iterator& operator++()
1193             {
1194                 m_index++;
1195                 return *this;
1196             }
1197             
1198             bool operator==(const iterator& other) const
1199             {
1200                 return m_index == other.m_index;
1201             }
1202             
1203             bool operator!=(const iterator& other) const
1204             {
1205                 return !(*this == other);
1206             }
1207         private:
1208             Node* m_terminal;
1209             unsigned m_index;
1210         };
1211         
1212         iterator begin()
1213         {
1214             return iterator(m_terminal, 0);
1215         }
1216         
1217         iterator end()
1218         {
1219             return iterator(m_terminal, m_terminal->numSuccessors());
1220         }
1221         
1222     private:
1223         Node* m_terminal;
1224     };
1225     
1226     SuccessorsIterable successors()
1227     {
1228         return SuccessorsIterable(this);
1229     }
1230     
1231     BasicBlock*& successorForCondition(bool condition)
1232     {
1233         return branchData()->forCondition(condition);
1234     }
1235     
1236     bool hasHeapPrediction()
1237     {
1238         switch (op()) {
1239         case ArithRound:
1240         case GetDirectPname:
1241         case GetById:
1242         case GetByIdFlush:
1243         case GetByVal:
1244         case Call:
1245         case Construct:
1246         case CallVarargs:
1247         case ConstructVarargs:
1248         case CallForwardVarargs:
1249         case NativeCall:
1250         case NativeConstruct:
1251         case GetByOffset:
1252         case MultiGetByOffset:
1253         case GetClosureVar:
1254         case GetFromArguments:
1255         case ArrayPop:
1256         case ArrayPush:
1257         case RegExpExec:
1258         case RegExpTest:
1259         case GetGlobalVar:
1260             return true;
1261         default:
1262             return false;
1263         }
1264     }
1265     
1266     SpeculatedType getHeapPrediction()
1267     {
1268         ASSERT(hasHeapPrediction());
1269         return static_cast<SpeculatedType>(m_opInfo2);
1270     }
1271
1272     void setHeapPrediction(SpeculatedType prediction)
1273     {
1274         ASSERT(hasHeapPrediction());
1275         m_opInfo2 = prediction;
1276     }
1277     
1278     bool hasCellOperand()
1279     {
1280         switch (op()) {
1281         case CheckCell:
1282         case NativeConstruct:
1283         case NativeCall:
1284         case NewFunction:
1285         case CreateActivation:
1286         case MaterializeCreateActivation:
1287             return true;
1288         default:
1289             return false;
1290         }
1291     }
1292
1293     FrozenValue* cellOperand()
1294     {
1295         ASSERT(hasCellOperand());
1296         return reinterpret_cast<FrozenValue*>(m_opInfo);
1297     }
1298     
1299     template<typename T>
1300     T castOperand()
1301     {
1302         return cellOperand()->cast<T>();
1303     }
1304     
1305     void setCellOperand(FrozenValue* value)
1306     {
1307         ASSERT(hasCellOperand());
1308         m_opInfo = bitwise_cast<uintptr_t>(value);
1309     }
1310     
1311     bool hasWatchpointSet()
1312     {
1313         return op() == NotifyWrite;
1314     }
1315     
1316     WatchpointSet* watchpointSet()
1317     {
1318         ASSERT(hasWatchpointSet());
1319         return reinterpret_cast<WatchpointSet*>(m_opInfo);
1320     }
1321     
1322     bool hasStoragePointer()
1323     {
1324         return op() == ConstantStoragePointer;
1325     }
1326     
1327     void* storagePointer()
1328     {
1329         ASSERT(hasStoragePointer());
1330         return reinterpret_cast<void*>(m_opInfo);
1331     }
1332
1333     bool hasTransition()
1334     {
1335         switch (op()) {
1336         case PutStructure:
1337         case AllocatePropertyStorage:
1338         case ReallocatePropertyStorage:
1339             return true;
1340         default:
1341             return false;
1342         }
1343     }
1344     
1345     Transition* transition()
1346     {
1347         ASSERT(hasTransition());
1348         return reinterpret_cast<Transition*>(m_opInfo);
1349     }
1350     
1351     bool hasStructureSet()
1352     {
1353         switch (op()) {
1354         case CheckStructure:
1355         case CheckStructureImmediate:
1356         case MaterializeNewObject:
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         ASSERT(hasMultiGetByOffsetData());
1413         return *reinterpret_cast<MultiGetByOffsetData*>(m_opInfo);
1414     }
1415     
1416     bool hasMultiPutByOffsetData()
1417     {
1418         return op() == MultiPutByOffset;
1419     }
1420     
1421     MultiPutByOffsetData& multiPutByOffsetData()
1422     {
1423         ASSERT(hasMultiPutByOffsetData());
1424         return *reinterpret_cast<MultiPutByOffsetData*>(m_opInfo);
1425     }
1426     
1427     bool hasObjectMaterializationData()
1428     {
1429         switch (op()) {
1430         case MaterializeNewObject:
1431         case MaterializeCreateActivation:
1432             return true;
1433
1434         default:
1435             return false;
1436         }
1437     }
1438     
1439     ObjectMaterializationData& objectMaterializationData()
1440     {
1441         ASSERT(hasObjectMaterializationData());
1442         return *reinterpret_cast<ObjectMaterializationData*>(m_opInfo2);
1443     }
1444
1445     bool isObjectAllocation()
1446     {
1447         switch (op()) {
1448         case NewObject:
1449         case MaterializeNewObject:
1450             return true;
1451         default:
1452             return false;
1453         }
1454     }
1455     
1456     bool isPhantomObjectAllocation()
1457     {
1458         switch (op()) {
1459         case PhantomNewObject:
1460             return true;
1461         default:
1462             return false;
1463         }
1464     }
1465     
1466     bool isActivationAllocation()
1467     {
1468         switch (op()) {
1469         case CreateActivation:
1470         case MaterializeCreateActivation:
1471             return true;
1472         default:
1473             return false;
1474         }
1475     }
1476
1477     bool isPhantomActivationAllocation()
1478     {
1479         switch (op()) {
1480         case PhantomCreateActivation:
1481             return true;
1482         default:
1483             return false;
1484         }
1485     }
1486
1487     bool isFunctionAllocation()
1488     {
1489         switch (op()) {
1490         case NewFunction:
1491             return true;
1492         default:
1493             return false;
1494         }
1495     }
1496
1497     bool isPhantomFunctionAllocation()
1498     {
1499         switch (op()) {
1500         case PhantomNewFunction:
1501             return true;
1502         default:
1503             return false;
1504         }
1505     }
1506
1507     bool isPhantomAllocation()
1508     {
1509         switch (op()) {
1510         case PhantomNewObject:
1511         case PhantomDirectArguments:
1512         case PhantomClonedArguments:
1513         case PhantomNewFunction:
1514         case PhantomCreateActivation:
1515             return true;
1516         default:
1517             return false;
1518         }
1519     }
1520     
1521     bool hasArrayMode()
1522     {
1523         switch (op()) {
1524         case GetIndexedPropertyStorage:
1525         case GetArrayLength:
1526         case PutByValDirect:
1527         case PutByVal:
1528         case PutByValAlias:
1529         case GetByVal:
1530         case StringCharAt:
1531         case StringCharCodeAt:
1532         case CheckArray:
1533         case Arrayify:
1534         case ArrayifyToStructure:
1535         case ArrayPush:
1536         case ArrayPop:
1537         case HasIndexedProperty:
1538             return true;
1539         default:
1540             return false;
1541         }
1542     }
1543     
1544     ArrayMode arrayMode()
1545     {
1546         ASSERT(hasArrayMode());
1547         if (op() == ArrayifyToStructure)
1548             return ArrayMode::fromWord(m_opInfo2);
1549         return ArrayMode::fromWord(m_opInfo);
1550     }
1551     
1552     bool setArrayMode(ArrayMode arrayMode)
1553     {
1554         ASSERT(hasArrayMode());
1555         if (this->arrayMode() == arrayMode)
1556             return false;
1557         m_opInfo = arrayMode.asWord();
1558         return true;
1559     }
1560     
1561     bool hasArithMode()
1562     {
1563         switch (op()) {
1564         case ArithAdd:
1565         case ArithSub:
1566         case ArithNegate:
1567         case ArithMul:
1568         case ArithDiv:
1569         case ArithMod:
1570         case UInt32ToNumber:
1571         case DoubleAsInt32:
1572             return true;
1573         default:
1574             return false;
1575         }
1576     }
1577
1578     Arith::Mode arithMode()
1579     {
1580         ASSERT(hasArithMode());
1581         return static_cast<Arith::Mode>(m_opInfo);
1582     }
1583     
1584     void setArithMode(Arith::Mode mode)
1585     {
1586         m_opInfo = mode;
1587     }
1588
1589     bool hasArithRoundingMode()
1590     {
1591         return op() == ArithRound;
1592     }
1593
1594     Arith::RoundingMode arithRoundingMode()
1595     {
1596         ASSERT(hasArithRoundingMode());
1597         return static_cast<Arith::RoundingMode>(m_opInfo);
1598     }
1599
1600     void setArithRoundingMode(Arith::RoundingMode mode)
1601     {
1602         ASSERT(hasArithRoundingMode());
1603         m_opInfo = static_cast<uintptr_t>(mode);
1604     }
1605     
1606     bool hasVirtualRegister()
1607     {
1608         return m_virtualRegister.isValid();
1609     }
1610     
1611     VirtualRegister virtualRegister()
1612     {
1613         ASSERT(hasResult());
1614         ASSERT(m_virtualRegister.isValid());
1615         return m_virtualRegister;
1616     }
1617     
1618     void setVirtualRegister(VirtualRegister virtualRegister)
1619     {
1620         ASSERT(hasResult());
1621         ASSERT(!m_virtualRegister.isValid());
1622         m_virtualRegister = virtualRegister;
1623     }
1624     
1625     bool hasExecutionCounter()
1626     {
1627         return op() == CountExecution;
1628     }
1629     
1630     Profiler::ExecutionCounter* executionCounter()
1631     {
1632         return bitwise_cast<Profiler::ExecutionCounter*>(m_opInfo);
1633     }
1634
1635     bool shouldGenerate()
1636     {
1637         return m_refCount;
1638     }
1639     
1640     bool isSemanticallySkippable()
1641     {
1642         return op() == CountExecution;
1643     }
1644
1645     unsigned refCount()
1646     {
1647         return m_refCount;
1648     }
1649
1650     unsigned postfixRef()
1651     {
1652         return m_refCount++;
1653     }
1654
1655     unsigned adjustedRefCount()
1656     {
1657         return mustGenerate() ? m_refCount - 1 : m_refCount;
1658     }
1659     
1660     void setRefCount(unsigned refCount)
1661     {
1662         m_refCount = refCount;
1663     }
1664     
1665     Edge& child1()
1666     {
1667         ASSERT(!(m_flags & NodeHasVarArgs));
1668         return children.child1();
1669     }
1670     
1671     // This is useful if you want to do a fast check on the first child
1672     // before also doing a check on the opcode. Use this with care and
1673     // avoid it if possible.
1674     Edge child1Unchecked()
1675     {
1676         return children.child1Unchecked();
1677     }
1678
1679     Edge& child2()
1680     {
1681         ASSERT(!(m_flags & NodeHasVarArgs));
1682         return children.child2();
1683     }
1684
1685     Edge& child3()
1686     {
1687         ASSERT(!(m_flags & NodeHasVarArgs));
1688         return children.child3();
1689     }
1690     
1691     unsigned firstChild()
1692     {
1693         ASSERT(m_flags & NodeHasVarArgs);
1694         return children.firstChild();
1695     }
1696     
1697     unsigned numChildren()
1698     {
1699         ASSERT(m_flags & NodeHasVarArgs);
1700         return children.numChildren();
1701     }
1702     
1703     UseKind binaryUseKind()
1704     {
1705         ASSERT(child1().useKind() == child2().useKind());
1706         return child1().useKind();
1707     }
1708     
1709     bool isBinaryUseKind(UseKind left, UseKind right)
1710     {
1711         return child1().useKind() == left && child2().useKind() == right;
1712     }
1713     
1714     bool isBinaryUseKind(UseKind useKind)
1715     {
1716         return isBinaryUseKind(useKind, useKind);
1717     }
1718     
1719     Edge childFor(UseKind useKind)
1720     {
1721         if (child1().useKind() == useKind)
1722             return child1();
1723         if (child2().useKind() == useKind)
1724             return child2();
1725         if (child3().useKind() == useKind)
1726             return child3();
1727         return Edge();
1728     }
1729     
1730     SpeculatedType prediction()
1731     {
1732         return m_prediction;
1733     }
1734     
1735     bool predict(SpeculatedType prediction)
1736     {
1737         return mergeSpeculation(m_prediction, prediction);
1738     }
1739     
1740     bool shouldSpeculateInt32()
1741     {
1742         return isInt32Speculation(prediction());
1743     }
1744     
1745     bool sawBooleans()
1746     {
1747         return !!(prediction() & SpecBoolean);
1748     }
1749     
1750     bool shouldSpeculateInt32OrBoolean()
1751     {
1752         return isInt32OrBooleanSpeculation(prediction());
1753     }
1754     
1755     bool shouldSpeculateInt32ForArithmetic()
1756     {
1757         return isInt32SpeculationForArithmetic(prediction());
1758     }
1759     
1760     bool shouldSpeculateInt32OrBooleanForArithmetic()
1761     {
1762         return isInt32OrBooleanSpeculationForArithmetic(prediction());
1763     }
1764     
1765     bool shouldSpeculateInt32OrBooleanExpectingDefined()
1766     {
1767         return isInt32OrBooleanSpeculationExpectingDefined(prediction());
1768     }
1769     
1770     bool shouldSpeculateMachineInt()
1771     {
1772         return isMachineIntSpeculation(prediction());
1773     }
1774     
1775     bool shouldSpeculateDouble()
1776     {
1777         return isDoubleSpeculation(prediction());
1778     }
1779     
1780     bool shouldSpeculateDoubleReal()
1781     {
1782         return isDoubleRealSpeculation(prediction());
1783     }
1784     
1785     bool shouldSpeculateNumber()
1786     {
1787         return isFullNumberSpeculation(prediction());
1788     }
1789     
1790     bool shouldSpeculateNumberOrBoolean()
1791     {
1792         return isFullNumberOrBooleanSpeculation(prediction());
1793     }
1794     
1795     bool shouldSpeculateNumberOrBooleanExpectingDefined()
1796     {
1797         return isFullNumberOrBooleanSpeculationExpectingDefined(prediction());
1798     }
1799     
1800     bool shouldSpeculateBoolean()
1801     {
1802         return isBooleanSpeculation(prediction());
1803     }
1804     
1805     bool shouldSpeculateOther()
1806     {
1807         return isOtherSpeculation(prediction());
1808     }
1809     
1810     bool shouldSpeculateMisc()
1811     {
1812         return isMiscSpeculation(prediction());
1813     }
1814    
1815     bool shouldSpeculateStringIdent()
1816     {
1817         return isStringIdentSpeculation(prediction());
1818     }
1819     
1820     bool shouldSpeculateNotStringVar()
1821     {
1822         return isNotStringVarSpeculation(prediction());
1823     }
1824  
1825     bool shouldSpeculateString()
1826     {
1827         return isStringSpeculation(prediction());
1828     }
1829  
1830     bool shouldSpeculateStringObject()
1831     {
1832         return isStringObjectSpeculation(prediction());
1833     }
1834     
1835     bool shouldSpeculateStringOrStringObject()
1836     {
1837         return isStringOrStringObjectSpeculation(prediction());
1838     }
1839     
1840     bool shouldSpeculateFinalObject()
1841     {
1842         return isFinalObjectSpeculation(prediction());
1843     }
1844     
1845     bool shouldSpeculateFinalObjectOrOther()
1846     {
1847         return isFinalObjectOrOtherSpeculation(prediction());
1848     }
1849     
1850     bool shouldSpeculateArray()
1851     {
1852         return isArraySpeculation(prediction());
1853     }
1854     
1855     bool shouldSpeculateDirectArguments()
1856     {
1857         return isDirectArgumentsSpeculation(prediction());
1858     }
1859     
1860     bool shouldSpeculateScopedArguments()
1861     {
1862         return isScopedArgumentsSpeculation(prediction());
1863     }
1864     
1865     bool shouldSpeculateInt8Array()
1866     {
1867         return isInt8ArraySpeculation(prediction());
1868     }
1869     
1870     bool shouldSpeculateInt16Array()
1871     {
1872         return isInt16ArraySpeculation(prediction());
1873     }
1874     
1875     bool shouldSpeculateInt32Array()
1876     {
1877         return isInt32ArraySpeculation(prediction());
1878     }
1879     
1880     bool shouldSpeculateUint8Array()
1881     {
1882         return isUint8ArraySpeculation(prediction());
1883     }
1884
1885     bool shouldSpeculateUint8ClampedArray()
1886     {
1887         return isUint8ClampedArraySpeculation(prediction());
1888     }
1889     
1890     bool shouldSpeculateUint16Array()
1891     {
1892         return isUint16ArraySpeculation(prediction());
1893     }
1894     
1895     bool shouldSpeculateUint32Array()
1896     {
1897         return isUint32ArraySpeculation(prediction());
1898     }
1899     
1900     bool shouldSpeculateFloat32Array()
1901     {
1902         return isFloat32ArraySpeculation(prediction());
1903     }
1904     
1905     bool shouldSpeculateFloat64Array()
1906     {
1907         return isFloat64ArraySpeculation(prediction());
1908     }
1909     
1910     bool shouldSpeculateArrayOrOther()
1911     {
1912         return isArrayOrOtherSpeculation(prediction());
1913     }
1914     
1915     bool shouldSpeculateObject()
1916     {
1917         return isObjectSpeculation(prediction());
1918     }
1919     
1920     bool shouldSpeculateObjectOrOther()
1921     {
1922         return isObjectOrOtherSpeculation(prediction());
1923     }
1924
1925     bool shouldSpeculateCell()
1926     {
1927         return isCellSpeculation(prediction());
1928     }
1929     
1930     bool shouldSpeculateNotCell()
1931     {
1932         return isNotCellSpeculation(prediction());
1933     }
1934     
1935     static bool shouldSpeculateBoolean(Node* op1, Node* op2)
1936     {
1937         return op1->shouldSpeculateBoolean() && op2->shouldSpeculateBoolean();
1938     }
1939     
1940     static bool shouldSpeculateInt32(Node* op1, Node* op2)
1941     {
1942         return op1->shouldSpeculateInt32() && op2->shouldSpeculateInt32();
1943     }
1944     
1945     static bool shouldSpeculateInt32OrBoolean(Node* op1, Node* op2)
1946     {
1947         return op1->shouldSpeculateInt32OrBoolean()
1948             && op2->shouldSpeculateInt32OrBoolean();
1949     }
1950     
1951     static bool shouldSpeculateInt32OrBooleanForArithmetic(Node* op1, Node* op2)
1952     {
1953         return op1->shouldSpeculateInt32OrBooleanForArithmetic()
1954             && op2->shouldSpeculateInt32OrBooleanForArithmetic();
1955     }
1956     
1957     static bool shouldSpeculateInt32OrBooleanExpectingDefined(Node* op1, Node* op2)
1958     {
1959         return op1->shouldSpeculateInt32OrBooleanExpectingDefined()
1960             && op2->shouldSpeculateInt32OrBooleanExpectingDefined();
1961     }
1962     
1963     static bool shouldSpeculateMachineInt(Node* op1, Node* op2)
1964     {
1965         return op1->shouldSpeculateMachineInt() && op2->shouldSpeculateMachineInt();
1966     }
1967     
1968     static bool shouldSpeculateNumber(Node* op1, Node* op2)
1969     {
1970         return op1->shouldSpeculateNumber() && op2->shouldSpeculateNumber();
1971     }
1972     
1973     static bool shouldSpeculateNumberOrBoolean(Node* op1, Node* op2)
1974     {
1975         return op1->shouldSpeculateNumberOrBoolean()
1976             && op2->shouldSpeculateNumberOrBoolean();
1977     }
1978     
1979     static bool shouldSpeculateNumberOrBooleanExpectingDefined(Node* op1, Node* op2)
1980     {
1981         return op1->shouldSpeculateNumberOrBooleanExpectingDefined()
1982             && op2->shouldSpeculateNumberOrBooleanExpectingDefined();
1983     }
1984     
1985     static bool shouldSpeculateFinalObject(Node* op1, Node* op2)
1986     {
1987         return op1->shouldSpeculateFinalObject() && op2->shouldSpeculateFinalObject();
1988     }
1989
1990     static bool shouldSpeculateArray(Node* op1, Node* op2)
1991     {
1992         return op1->shouldSpeculateArray() && op2->shouldSpeculateArray();
1993     }
1994     
1995     bool canSpeculateInt32(RareCaseProfilingSource source)
1996     {
1997         return nodeCanSpeculateInt32(arithNodeFlags(), source);
1998     }
1999     
2000     bool canSpeculateInt52(RareCaseProfilingSource source)
2001     {
2002         return nodeCanSpeculateInt52(arithNodeFlags(), source);
2003     }
2004     
2005     RareCaseProfilingSource sourceFor(PredictionPass pass)
2006     {
2007         if (pass == PrimaryPass || child1()->sawBooleans() || (child2() && child2()->sawBooleans()))
2008             return DFGRareCase;
2009         return AllRareCases;
2010     }
2011     
2012     bool canSpeculateInt32(PredictionPass pass)
2013     {
2014         return canSpeculateInt32(sourceFor(pass));
2015     }
2016     
2017     bool canSpeculateInt52(PredictionPass pass)
2018     {
2019         return canSpeculateInt52(sourceFor(pass));
2020     }
2021
2022     bool hasTypeLocation()
2023     {
2024         return op() == ProfileType;
2025     }
2026
2027     TypeLocation* typeLocation()
2028     {
2029         ASSERT(hasTypeLocation());
2030         return reinterpret_cast<TypeLocation*>(m_opInfo);
2031     }
2032
2033     bool hasBasicBlockLocation()
2034     {
2035         return op() == ProfileControlFlow;
2036     }
2037
2038     BasicBlockLocation* basicBlockLocation()
2039     {
2040         ASSERT(hasBasicBlockLocation());
2041         return reinterpret_cast<BasicBlockLocation*>(m_opInfo);
2042     }
2043     
2044     Node* replacement() const
2045     {
2046         return m_misc.replacement;
2047     }
2048     
2049     void setReplacement(Node* replacement)
2050     {
2051         m_misc.replacement = replacement;
2052     }
2053     
2054     Epoch epoch() const
2055     {
2056         return Epoch::fromUnsigned(m_misc.epoch);
2057     }
2058     
2059     void setEpoch(Epoch epoch)
2060     {
2061         m_misc.epoch = epoch.toUnsigned();
2062     }
2063     
2064     void dumpChildren(PrintStream& out)
2065     {
2066         if (!child1())
2067             return;
2068         out.printf("@%u", child1()->index());
2069         if (!child2())
2070             return;
2071         out.printf(", @%u", child2()->index());
2072         if (!child3())
2073             return;
2074         out.printf(", @%u", child3()->index());
2075     }
2076     
2077     // NB. This class must have a trivial destructor.
2078
2079     NodeOrigin origin;
2080
2081     // References to up to 3 children, or links to a variable length set of children.
2082     AdjacencyList children;
2083
2084 private:
2085     unsigned m_op : 10; // real type is NodeType
2086     unsigned m_flags : 22;
2087     // The virtual register number (spill location) associated with this .
2088     VirtualRegister m_virtualRegister;
2089     // The number of uses of the result of this operation (+1 for 'must generate' nodes, which have side-effects).
2090     unsigned m_refCount;
2091     // The prediction ascribed to this node after propagation.
2092     SpeculatedType m_prediction;
2093     // Immediate values, accesses type-checked via accessors above. The first one is
2094     // big enough to store a pointer.
2095     uintptr_t m_opInfo;
2096     uintptr_t m_opInfo2;
2097
2098 public:
2099     // Fields used by various analyses.
2100     AbstractValue value;
2101     
2102     // Miscellaneous data that is usually meaningless, but can hold some analysis results
2103     // if you ask right. For example, if you do Graph::initializeNodeOwners(), Node::owner
2104     // will tell you which basic block a node belongs to. You cannot rely on this persisting
2105     // across transformations unless you do the maintenance work yourself. Other phases use
2106     // Node::replacement, but they do so manually: first you do Graph::clearReplacements()
2107     // and then you set, and use, replacement's yourself. Same thing for epoch.
2108     //
2109     // Bottom line: don't use these fields unless you initialize them yourself, or by
2110     // calling some appropriate methods that initialize them the way you want. Otherwise,
2111     // these fields are meaningless.
2112 private:
2113     union {
2114         Node* replacement;
2115         unsigned epoch;
2116     } m_misc;
2117 public:
2118     BasicBlock* owner;
2119 };
2120
2121 inline bool nodeComparator(Node* a, Node* b)
2122 {
2123     return a->index() < b->index();
2124 }
2125
2126 template<typename T>
2127 CString nodeListDump(const T& nodeList)
2128 {
2129     return sortedListDump(nodeList, nodeComparator);
2130 }
2131
2132 template<typename T>
2133 CString nodeMapDump(const T& nodeMap, DumpContext* context = 0)
2134 {
2135     Vector<typename T::KeyType> keys;
2136     for (
2137         typename T::const_iterator iter = nodeMap.begin();
2138         iter != nodeMap.end(); ++iter)
2139         keys.append(iter->key);
2140     std::sort(keys.begin(), keys.end(), nodeComparator);
2141     StringPrintStream out;
2142     CommaPrinter comma;
2143     for(unsigned i = 0; i < keys.size(); ++i)
2144         out.print(comma, keys[i], "=>", inContext(nodeMap.get(keys[i]), context));
2145     return out.toCString();
2146 }
2147
2148 } } // namespace JSC::DFG
2149
2150 namespace WTF {
2151
2152 void printInternal(PrintStream&, JSC::DFG::SwitchKind);
2153 void printInternal(PrintStream&, JSC::DFG::Node*);
2154
2155 inline JSC::DFG::Node* inContext(JSC::DFG::Node* node, JSC::DumpContext*) { return node; }
2156
2157 } // namespace WTF
2158
2159 using WTF::inContext;
2160
2161 #endif
2162 #endif