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