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