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