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