Turn String.prototype.replace into an intrinsic
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGNode.h
1 /*
2  * Copyright (C) 2011-2016 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() == ArithFloor || op() == ArithCeil || 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     // FIXME: We really should be able to inline code that uses NewRegexp. That means
1026     // using something other than the index into the CodeBlock here.
1027     // https://bugs.webkit.org/show_bug.cgi?id=154808
1028     bool hasRegexpIndex()
1029     {
1030         return op() == NewRegexp;
1031     }
1032     
1033     unsigned regexpIndex()
1034     {
1035         ASSERT(hasRegexpIndex());
1036         return m_opInfo;
1037     }
1038     
1039     bool hasScopeOffset()
1040     {
1041         return op() == GetClosureVar || op() == PutClosureVar;
1042     }
1043
1044     ScopeOffset scopeOffset()
1045     {
1046         ASSERT(hasScopeOffset());
1047         return ScopeOffset(m_opInfo);
1048     }
1049     
1050     bool hasDirectArgumentsOffset()
1051     {
1052         return op() == GetFromArguments || op() == PutToArguments;
1053     }
1054     
1055     DirectArgumentsOffset capturedArgumentsOffset()
1056     {
1057         ASSERT(hasDirectArgumentsOffset());
1058         return DirectArgumentsOffset(m_opInfo);
1059     }
1060     
1061     bool hasRegisterPointer()
1062     {
1063         return op() == GetGlobalVar || op() == GetGlobalLexicalVariable || op() == PutGlobalVariable;
1064     }
1065     
1066     WriteBarrier<Unknown>* variablePointer()
1067     {
1068         return bitwise_cast<WriteBarrier<Unknown>*>(m_opInfo);
1069     }
1070     
1071     bool hasCallVarargsData()
1072     {
1073         switch (op()) {
1074         case CallVarargs:
1075         case CallForwardVarargs:
1076         case TailCallVarargs:
1077         case TailCallForwardVarargs:
1078         case TailCallVarargsInlinedCaller:
1079         case TailCallForwardVarargsInlinedCaller:
1080         case ConstructVarargs:
1081         case ConstructForwardVarargs:
1082             return true;
1083         default:
1084             return false;
1085         }
1086     }
1087     
1088     CallVarargsData* callVarargsData()
1089     {
1090         ASSERT(hasCallVarargsData());
1091         return bitwise_cast<CallVarargsData*>(m_opInfo);
1092     }
1093     
1094     bool hasLoadVarargsData()
1095     {
1096         return op() == LoadVarargs || op() == ForwardVarargs;
1097     }
1098     
1099     LoadVarargsData* loadVarargsData()
1100     {
1101         ASSERT(hasLoadVarargsData());
1102         return bitwise_cast<LoadVarargsData*>(m_opInfo);
1103     }
1104     
1105     bool hasResult()
1106     {
1107         return !!result();
1108     }
1109
1110     bool hasInt32Result()
1111     {
1112         return result() == NodeResultInt32;
1113     }
1114     
1115     bool hasInt52Result()
1116     {
1117         return result() == NodeResultInt52;
1118     }
1119     
1120     bool hasNumberResult()
1121     {
1122         return result() == NodeResultNumber;
1123     }
1124     
1125     bool hasDoubleResult()
1126     {
1127         return result() == NodeResultDouble;
1128     }
1129     
1130     bool hasJSResult()
1131     {
1132         return result() == NodeResultJS;
1133     }
1134     
1135     bool hasBooleanResult()
1136     {
1137         return result() == NodeResultBoolean;
1138     }
1139
1140     bool hasStorageResult()
1141     {
1142         return result() == NodeResultStorage;
1143     }
1144     
1145     UseKind defaultUseKind()
1146     {
1147         return useKindForResult(result());
1148     }
1149     
1150     Edge defaultEdge()
1151     {
1152         return Edge(this, defaultUseKind());
1153     }
1154
1155     bool isJump()
1156     {
1157         return op() == Jump;
1158     }
1159
1160     bool isBranch()
1161     {
1162         return op() == Branch;
1163     }
1164     
1165     bool isSwitch()
1166     {
1167         return op() == Switch;
1168     }
1169
1170     bool isTerminal()
1171     {
1172         switch (op()) {
1173         case Jump:
1174         case Branch:
1175         case Switch:
1176         case Return:
1177         case TailCall:
1178         case TailCallVarargs:
1179         case TailCallForwardVarargs:
1180         case Unreachable:
1181             return true;
1182         default:
1183             return false;
1184         }
1185     }
1186
1187     bool isFunctionTerminal()
1188     {
1189         if (isTerminal() && !numSuccessors())
1190             return true;
1191
1192         return false;
1193     }
1194
1195     unsigned targetBytecodeOffsetDuringParsing()
1196     {
1197         ASSERT(isJump());
1198         return m_opInfo;
1199     }
1200
1201     BasicBlock*& targetBlock()
1202     {
1203         ASSERT(isJump());
1204         return *bitwise_cast<BasicBlock**>(&m_opInfo);
1205     }
1206     
1207     BranchData* branchData()
1208     {
1209         ASSERT(isBranch());
1210         return bitwise_cast<BranchData*>(m_opInfo);
1211     }
1212     
1213     SwitchData* switchData()
1214     {
1215         ASSERT(isSwitch());
1216         return bitwise_cast<SwitchData*>(m_opInfo);
1217     }
1218     
1219     unsigned numSuccessors()
1220     {
1221         switch (op()) {
1222         case Jump:
1223             return 1;
1224         case Branch:
1225             return 2;
1226         case Switch:
1227             return switchData()->cases.size() + 1;
1228         default:
1229             return 0;
1230         }
1231     }
1232     
1233     BasicBlock*& successor(unsigned index)
1234     {
1235         if (isSwitch()) {
1236             if (index < switchData()->cases.size())
1237                 return switchData()->cases[index].target.block;
1238             RELEASE_ASSERT(index == switchData()->cases.size());
1239             return switchData()->fallThrough.block;
1240         }
1241         switch (index) {
1242         case 0:
1243             if (isJump())
1244                 return targetBlock();
1245             return branchData()->taken.block;
1246         case 1:
1247             return branchData()->notTaken.block;
1248         default:
1249             RELEASE_ASSERT_NOT_REACHED();
1250             return targetBlock();
1251         }
1252     }
1253     
1254     class SuccessorsIterable {
1255     public:
1256         SuccessorsIterable()
1257             : m_terminal(nullptr)
1258         {
1259         }
1260         
1261         SuccessorsIterable(Node* terminal)
1262             : m_terminal(terminal)
1263         {
1264         }
1265         
1266         class iterator {
1267         public:
1268             iterator()
1269                 : m_terminal(nullptr)
1270                 , m_index(UINT_MAX)
1271             {
1272             }
1273             
1274             iterator(Node* terminal, unsigned index)
1275                 : m_terminal(terminal)
1276                 , m_index(index)
1277             {
1278             }
1279             
1280             BasicBlock* operator*()
1281             {
1282                 return m_terminal->successor(m_index);
1283             }
1284             
1285             iterator& operator++()
1286             {
1287                 m_index++;
1288                 return *this;
1289             }
1290             
1291             bool operator==(const iterator& other) const
1292             {
1293                 return m_index == other.m_index;
1294             }
1295             
1296             bool operator!=(const iterator& other) const
1297             {
1298                 return !(*this == other);
1299             }
1300         private:
1301             Node* m_terminal;
1302             unsigned m_index;
1303         };
1304         
1305         iterator begin()
1306         {
1307             return iterator(m_terminal, 0);
1308         }
1309         
1310         iterator end()
1311         {
1312             return iterator(m_terminal, m_terminal->numSuccessors());
1313         }
1314
1315         size_t size() const { return m_terminal->numSuccessors(); }
1316         BasicBlock* at(size_t index) const { return m_terminal->successor(index); }
1317         BasicBlock* operator[](size_t index) const { return at(index); }
1318         
1319     private:
1320         Node* m_terminal;
1321     };
1322     
1323     SuccessorsIterable successors()
1324     {
1325         return SuccessorsIterable(this);
1326     }
1327     
1328     BasicBlock*& successorForCondition(bool condition)
1329     {
1330         return branchData()->forCondition(condition);
1331     }
1332     
1333     bool hasHeapPrediction()
1334     {
1335         switch (op()) {
1336         case ArithRound:
1337         case ArithFloor:
1338         case ArithCeil:
1339         case GetDirectPname:
1340         case GetById:
1341         case GetByIdFlush:
1342         case GetByVal:
1343         case Call:
1344         case TailCallInlinedCaller:
1345         case Construct:
1346         case CallVarargs:
1347         case TailCallVarargsInlinedCaller:
1348         case ConstructVarargs:
1349         case CallForwardVarargs:
1350         case TailCallForwardVarargsInlinedCaller:
1351         case GetByOffset:
1352         case MultiGetByOffset:
1353         case GetClosureVar:
1354         case GetFromArguments:
1355         case ArrayPop:
1356         case ArrayPush:
1357         case RegExpExec:
1358         case RegExpTest:
1359         case GetGlobalVar:
1360         case GetGlobalLexicalVariable:
1361         case StringReplace:
1362             return true;
1363         default:
1364             return false;
1365         }
1366     }
1367     
1368     SpeculatedType getHeapPrediction()
1369     {
1370         ASSERT(hasHeapPrediction());
1371         return static_cast<SpeculatedType>(m_opInfo2);
1372     }
1373
1374     void setHeapPrediction(SpeculatedType prediction)
1375     {
1376         ASSERT(hasHeapPrediction());
1377         m_opInfo2 = prediction;
1378     }
1379     
1380     bool hasCellOperand()
1381     {
1382         switch (op()) {
1383         case CheckCell:
1384         case OverridesHasInstance:
1385         case NewFunction:
1386         case NewArrowFunction:
1387         case NewGeneratorFunction:
1388         case CreateActivation:
1389         case MaterializeCreateActivation:
1390             return true;
1391         default:
1392             return false;
1393         }
1394     }
1395
1396     FrozenValue* cellOperand()
1397     {
1398         ASSERT(hasCellOperand());
1399         return reinterpret_cast<FrozenValue*>(m_opInfo);
1400     }
1401     
1402     template<typename T>
1403     T castOperand()
1404     {
1405         return cellOperand()->cast<T>();
1406     }
1407     
1408     void setCellOperand(FrozenValue* value)
1409     {
1410         ASSERT(hasCellOperand());
1411         m_opInfo = bitwise_cast<uintptr_t>(value);
1412     }
1413     
1414     bool hasWatchpointSet()
1415     {
1416         return op() == NotifyWrite;
1417     }
1418     
1419     WatchpointSet* watchpointSet()
1420     {
1421         ASSERT(hasWatchpointSet());
1422         return reinterpret_cast<WatchpointSet*>(m_opInfo);
1423     }
1424     
1425     bool hasStoragePointer()
1426     {
1427         return op() == ConstantStoragePointer;
1428     }
1429     
1430     void* storagePointer()
1431     {
1432         ASSERT(hasStoragePointer());
1433         return reinterpret_cast<void*>(m_opInfo);
1434     }
1435
1436     bool hasUidOperand()
1437     {
1438         return op() == CheckIdent;
1439     }
1440
1441     UniquedStringImpl* uidOperand()
1442     {
1443         ASSERT(hasUidOperand());
1444         return reinterpret_cast<UniquedStringImpl*>(m_opInfo);
1445     }
1446
1447     bool hasTypeInfoOperand()
1448     {
1449         return op() == CheckTypeInfoFlags;
1450     }
1451
1452     unsigned typeInfoOperand()
1453     {
1454         ASSERT(hasTypeInfoOperand() && m_opInfo <= UCHAR_MAX);
1455         return static_cast<unsigned>(m_opInfo);
1456     }
1457
1458     bool hasTransition()
1459     {
1460         switch (op()) {
1461         case PutStructure:
1462         case AllocatePropertyStorage:
1463         case ReallocatePropertyStorage:
1464             return true;
1465         default:
1466             return false;
1467         }
1468     }
1469     
1470     Transition* transition()
1471     {
1472         ASSERT(hasTransition());
1473         return reinterpret_cast<Transition*>(m_opInfo);
1474     }
1475     
1476     bool hasStructureSet()
1477     {
1478         switch (op()) {
1479         case CheckStructure:
1480         case CheckStructureImmediate:
1481         case MaterializeNewObject:
1482             return true;
1483         default:
1484             return false;
1485         }
1486     }
1487     
1488     StructureSet& structureSet()
1489     {
1490         ASSERT(hasStructureSet());
1491         return *reinterpret_cast<StructureSet*>(m_opInfo);
1492     }
1493     
1494     bool hasStructure()
1495     {
1496         switch (op()) {
1497         case ArrayifyToStructure:
1498         case NewObject:
1499         case NewStringObject:
1500             return true;
1501         default:
1502             return false;
1503         }
1504     }
1505     
1506     Structure* structure()
1507     {
1508         ASSERT(hasStructure());
1509         return reinterpret_cast<Structure*>(m_opInfo);
1510     }
1511     
1512     bool hasStorageAccessData()
1513     {
1514         switch (op()) {
1515         case GetByOffset:
1516         case PutByOffset:
1517         case GetGetterSetterByOffset:
1518             return true;
1519         default:
1520             return false;
1521         }
1522     }
1523     
1524     StorageAccessData& storageAccessData()
1525     {
1526         ASSERT(hasStorageAccessData());
1527         return *bitwise_cast<StorageAccessData*>(m_opInfo);
1528     }
1529     
1530     bool hasMultiGetByOffsetData()
1531     {
1532         return op() == MultiGetByOffset;
1533     }
1534     
1535     MultiGetByOffsetData& multiGetByOffsetData()
1536     {
1537         ASSERT(hasMultiGetByOffsetData());
1538         return *reinterpret_cast<MultiGetByOffsetData*>(m_opInfo);
1539     }
1540     
1541     bool hasMultiPutByOffsetData()
1542     {
1543         return op() == MultiPutByOffset;
1544     }
1545     
1546     MultiPutByOffsetData& multiPutByOffsetData()
1547     {
1548         ASSERT(hasMultiPutByOffsetData());
1549         return *reinterpret_cast<MultiPutByOffsetData*>(m_opInfo);
1550     }
1551     
1552     bool hasObjectMaterializationData()
1553     {
1554         switch (op()) {
1555         case MaterializeNewObject:
1556         case MaterializeCreateActivation:
1557             return true;
1558
1559         default:
1560             return false;
1561         }
1562     }
1563     
1564     ObjectMaterializationData& objectMaterializationData()
1565     {
1566         ASSERT(hasObjectMaterializationData());
1567         return *reinterpret_cast<ObjectMaterializationData*>(m_opInfo2);
1568     }
1569
1570     bool isObjectAllocation()
1571     {
1572         switch (op()) {
1573         case NewObject:
1574         case MaterializeNewObject:
1575             return true;
1576         default:
1577             return false;
1578         }
1579     }
1580     
1581     bool isPhantomObjectAllocation()
1582     {
1583         switch (op()) {
1584         case PhantomNewObject:
1585             return true;
1586         default:
1587             return false;
1588         }
1589     }
1590     
1591     bool isActivationAllocation()
1592     {
1593         switch (op()) {
1594         case CreateActivation:
1595         case MaterializeCreateActivation:
1596             return true;
1597         default:
1598             return false;
1599         }
1600     }
1601
1602     bool isPhantomActivationAllocation()
1603     {
1604         switch (op()) {
1605         case PhantomCreateActivation:
1606             return true;
1607         default:
1608             return false;
1609         }
1610     }
1611
1612     bool isFunctionAllocation()
1613     {
1614         switch (op()) {
1615         case NewArrowFunction:
1616         case NewFunction:
1617         case NewGeneratorFunction:
1618             return true;
1619         default:
1620             return false;
1621         }
1622     }
1623
1624     bool isPhantomFunctionAllocation()
1625     {
1626         switch (op()) {
1627         case PhantomNewFunction:
1628         case PhantomNewGeneratorFunction:
1629             return true;
1630         default:
1631             return false;
1632         }
1633     }
1634
1635     bool isPhantomAllocation()
1636     {
1637         switch (op()) {
1638         case PhantomNewObject:
1639         case PhantomDirectArguments:
1640         case PhantomClonedArguments:
1641         case PhantomNewFunction:
1642         case PhantomNewGeneratorFunction:
1643         case PhantomCreateActivation:
1644             return true;
1645         default:
1646             return false;
1647         }
1648     }
1649     
1650     bool hasArrayMode()
1651     {
1652         switch (op()) {
1653         case GetIndexedPropertyStorage:
1654         case GetArrayLength:
1655         case PutByValDirect:
1656         case PutByVal:
1657         case PutByValAlias:
1658         case GetByVal:
1659         case StringCharAt:
1660         case StringCharCodeAt:
1661         case CheckArray:
1662         case Arrayify:
1663         case ArrayifyToStructure:
1664         case ArrayPush:
1665         case ArrayPop:
1666         case HasIndexedProperty:
1667             return true;
1668         default:
1669             return false;
1670         }
1671     }
1672     
1673     ArrayMode arrayMode()
1674     {
1675         ASSERT(hasArrayMode());
1676         if (op() == ArrayifyToStructure)
1677             return ArrayMode::fromWord(m_opInfo2);
1678         return ArrayMode::fromWord(m_opInfo);
1679     }
1680     
1681     bool setArrayMode(ArrayMode arrayMode)
1682     {
1683         ASSERT(hasArrayMode());
1684         if (this->arrayMode() == arrayMode)
1685             return false;
1686         m_opInfo = arrayMode.asWord();
1687         return true;
1688     }
1689     
1690     bool hasArithMode()
1691     {
1692         switch (op()) {
1693         case ArithAbs:
1694         case ArithAdd:
1695         case ArithSub:
1696         case ArithNegate:
1697         case ArithMul:
1698         case ArithDiv:
1699         case ArithMod:
1700         case UInt32ToNumber:
1701         case DoubleAsInt32:
1702             return true;
1703         default:
1704             return false;
1705         }
1706     }
1707
1708     Arith::Mode arithMode()
1709     {
1710         ASSERT(hasArithMode());
1711         return static_cast<Arith::Mode>(m_opInfo);
1712     }
1713     
1714     void setArithMode(Arith::Mode mode)
1715     {
1716         m_opInfo = mode;
1717     }
1718
1719     bool hasArithRoundingMode()
1720     {
1721         return op() == ArithRound || op() == ArithFloor || op() == ArithCeil;
1722     }
1723
1724     Arith::RoundingMode arithRoundingMode()
1725     {
1726         ASSERT(hasArithRoundingMode());
1727         return static_cast<Arith::RoundingMode>(m_opInfo);
1728     }
1729
1730     void setArithRoundingMode(Arith::RoundingMode mode)
1731     {
1732         ASSERT(hasArithRoundingMode());
1733         m_opInfo = static_cast<uintptr_t>(mode);
1734     }
1735     
1736     bool hasVirtualRegister()
1737     {
1738         return m_virtualRegister.isValid();
1739     }
1740     
1741     VirtualRegister virtualRegister()
1742     {
1743         ASSERT(hasResult());
1744         ASSERT(m_virtualRegister.isValid());
1745         return m_virtualRegister;
1746     }
1747     
1748     void setVirtualRegister(VirtualRegister virtualRegister)
1749     {
1750         ASSERT(hasResult());
1751         ASSERT(!m_virtualRegister.isValid());
1752         m_virtualRegister = virtualRegister;
1753     }
1754     
1755     bool hasExecutionCounter()
1756     {
1757         return op() == CountExecution;
1758     }
1759     
1760     Profiler::ExecutionCounter* executionCounter()
1761     {
1762         return bitwise_cast<Profiler::ExecutionCounter*>(m_opInfo);
1763     }
1764
1765     bool shouldGenerate()
1766     {
1767         return m_refCount;
1768     }
1769     
1770     bool isSemanticallySkippable()
1771     {
1772         return op() == CountExecution;
1773     }
1774
1775     unsigned refCount()
1776     {
1777         return m_refCount;
1778     }
1779
1780     unsigned postfixRef()
1781     {
1782         return m_refCount++;
1783     }
1784
1785     unsigned adjustedRefCount()
1786     {
1787         return mustGenerate() ? m_refCount - 1 : m_refCount;
1788     }
1789     
1790     void setRefCount(unsigned refCount)
1791     {
1792         m_refCount = refCount;
1793     }
1794     
1795     Edge& child1()
1796     {
1797         ASSERT(!(m_flags & NodeHasVarArgs));
1798         return children.child1();
1799     }
1800     
1801     // This is useful if you want to do a fast check on the first child
1802     // before also doing a check on the opcode. Use this with care and
1803     // avoid it if possible.
1804     Edge child1Unchecked()
1805     {
1806         return children.child1Unchecked();
1807     }
1808
1809     Edge& child2()
1810     {
1811         ASSERT(!(m_flags & NodeHasVarArgs));
1812         return children.child2();
1813     }
1814
1815     Edge& child3()
1816     {
1817         ASSERT(!(m_flags & NodeHasVarArgs));
1818         return children.child3();
1819     }
1820     
1821     unsigned firstChild()
1822     {
1823         ASSERT(m_flags & NodeHasVarArgs);
1824         return children.firstChild();
1825     }
1826     
1827     unsigned numChildren()
1828     {
1829         ASSERT(m_flags & NodeHasVarArgs);
1830         return children.numChildren();
1831     }
1832     
1833     UseKind binaryUseKind()
1834     {
1835         ASSERT(child1().useKind() == child2().useKind());
1836         return child1().useKind();
1837     }
1838     
1839     bool isBinaryUseKind(UseKind left, UseKind right)
1840     {
1841         return child1().useKind() == left && child2().useKind() == right;
1842     }
1843     
1844     bool isBinaryUseKind(UseKind useKind)
1845     {
1846         return isBinaryUseKind(useKind, useKind);
1847     }
1848     
1849     Edge childFor(UseKind useKind)
1850     {
1851         if (child1().useKind() == useKind)
1852             return child1();
1853         if (child2().useKind() == useKind)
1854             return child2();
1855         if (child3().useKind() == useKind)
1856             return child3();
1857         return Edge();
1858     }
1859     
1860     SpeculatedType prediction()
1861     {
1862         return m_prediction;
1863     }
1864     
1865     bool predict(SpeculatedType prediction)
1866     {
1867         return mergeSpeculation(m_prediction, prediction);
1868     }
1869     
1870     bool shouldSpeculateInt32()
1871     {
1872         return isInt32Speculation(prediction());
1873     }
1874     
1875     bool sawBooleans()
1876     {
1877         return !!(prediction() & SpecBoolean);
1878     }
1879     
1880     bool shouldSpeculateInt32OrBoolean()
1881     {
1882         return isInt32OrBooleanSpeculation(prediction());
1883     }
1884     
1885     bool shouldSpeculateInt32ForArithmetic()
1886     {
1887         return isInt32SpeculationForArithmetic(prediction());
1888     }
1889     
1890     bool shouldSpeculateInt32OrBooleanForArithmetic()
1891     {
1892         return isInt32OrBooleanSpeculationForArithmetic(prediction());
1893     }
1894     
1895     bool shouldSpeculateInt32OrBooleanExpectingDefined()
1896     {
1897         return isInt32OrBooleanSpeculationExpectingDefined(prediction());
1898     }
1899     
1900     bool shouldSpeculateMachineInt()
1901     {
1902         return isMachineIntSpeculation(prediction());
1903     }
1904     
1905     bool shouldSpeculateDouble()
1906     {
1907         return isDoubleSpeculation(prediction());
1908     }
1909     
1910     bool shouldSpeculateDoubleReal()
1911     {
1912         return isDoubleRealSpeculation(prediction());
1913     }
1914     
1915     bool shouldSpeculateNumber()
1916     {
1917         return isFullNumberSpeculation(prediction());
1918     }
1919     
1920     bool shouldSpeculateNumberOrBoolean()
1921     {
1922         return isFullNumberOrBooleanSpeculation(prediction());
1923     }
1924     
1925     bool shouldSpeculateNumberOrBooleanExpectingDefined()
1926     {
1927         return isFullNumberOrBooleanSpeculationExpectingDefined(prediction());
1928     }
1929     
1930     bool shouldSpeculateBoolean()
1931     {
1932         return isBooleanSpeculation(prediction());
1933     }
1934     
1935     bool shouldSpeculateOther()
1936     {
1937         return isOtherSpeculation(prediction());
1938     }
1939     
1940     bool shouldSpeculateMisc()
1941     {
1942         return isMiscSpeculation(prediction());
1943     }
1944    
1945     bool shouldSpeculateStringIdent()
1946     {
1947         return isStringIdentSpeculation(prediction());
1948     }
1949     
1950     bool shouldSpeculateNotStringVar()
1951     {
1952         return isNotStringVarSpeculation(prediction());
1953     }
1954  
1955     bool shouldSpeculateString()
1956     {
1957         return isStringSpeculation(prediction());
1958     }
1959  
1960     bool shouldSpeculateStringObject()
1961     {
1962         return isStringObjectSpeculation(prediction());
1963     }
1964     
1965     bool shouldSpeculateStringOrStringObject()
1966     {
1967         return isStringOrStringObjectSpeculation(prediction());
1968     }
1969
1970     bool shouldSpeculateRegExpObject()
1971     {
1972         return isRegExpObjectSpeculation(prediction());
1973     }
1974     
1975     bool shouldSpeculateSymbol()
1976     {
1977         return isSymbolSpeculation(prediction());
1978     }
1979     
1980     bool shouldSpeculateFinalObject()
1981     {
1982         return isFinalObjectSpeculation(prediction());
1983     }
1984     
1985     bool shouldSpeculateFinalObjectOrOther()
1986     {
1987         return isFinalObjectOrOtherSpeculation(prediction());
1988     }
1989     
1990     bool shouldSpeculateArray()
1991     {
1992         return isArraySpeculation(prediction());
1993     }
1994     
1995     bool shouldSpeculateDirectArguments()
1996     {
1997         return isDirectArgumentsSpeculation(prediction());
1998     }
1999     
2000     bool shouldSpeculateScopedArguments()
2001     {
2002         return isScopedArgumentsSpeculation(prediction());
2003     }
2004     
2005     bool shouldSpeculateInt8Array()
2006     {
2007         return isInt8ArraySpeculation(prediction());
2008     }
2009     
2010     bool shouldSpeculateInt16Array()
2011     {
2012         return isInt16ArraySpeculation(prediction());
2013     }
2014     
2015     bool shouldSpeculateInt32Array()
2016     {
2017         return isInt32ArraySpeculation(prediction());
2018     }
2019     
2020     bool shouldSpeculateUint8Array()
2021     {
2022         return isUint8ArraySpeculation(prediction());
2023     }
2024
2025     bool shouldSpeculateUint8ClampedArray()
2026     {
2027         return isUint8ClampedArraySpeculation(prediction());
2028     }
2029     
2030     bool shouldSpeculateUint16Array()
2031     {
2032         return isUint16ArraySpeculation(prediction());
2033     }
2034     
2035     bool shouldSpeculateUint32Array()
2036     {
2037         return isUint32ArraySpeculation(prediction());
2038     }
2039     
2040     bool shouldSpeculateFloat32Array()
2041     {
2042         return isFloat32ArraySpeculation(prediction());
2043     }
2044     
2045     bool shouldSpeculateFloat64Array()
2046     {
2047         return isFloat64ArraySpeculation(prediction());
2048     }
2049     
2050     bool shouldSpeculateArrayOrOther()
2051     {
2052         return isArrayOrOtherSpeculation(prediction());
2053     }
2054     
2055     bool shouldSpeculateObject()
2056     {
2057         return isObjectSpeculation(prediction());
2058     }
2059     
2060     bool shouldSpeculateObjectOrOther()
2061     {
2062         return isObjectOrOtherSpeculation(prediction());
2063     }
2064
2065     bool shouldSpeculateCell()
2066     {
2067         return isCellSpeculation(prediction());
2068     }
2069     
2070     bool shouldSpeculateNotCell()
2071     {
2072         return isNotCellSpeculation(prediction());
2073     }
2074     
2075     bool shouldSpeculateUntypedForArithmetic()
2076     {
2077         return isUntypedSpeculationForArithmetic(prediction());
2078     }
2079
2080     static bool shouldSpeculateUntypedForArithmetic(Node* op1, Node* op2)
2081     {
2082         return op1->shouldSpeculateUntypedForArithmetic() || op2->shouldSpeculateUntypedForArithmetic();
2083     }
2084     
2085     bool shouldSpeculateUntypedForBitOps()
2086     {
2087         return isUntypedSpeculationForBitOps(prediction());
2088     }
2089     
2090     static bool shouldSpeculateUntypedForBitOps(Node* op1, Node* op2)
2091     {
2092         return op1->shouldSpeculateUntypedForBitOps() || op2->shouldSpeculateUntypedForBitOps();
2093     }
2094     
2095     static bool shouldSpeculateBoolean(Node* op1, Node* op2)
2096     {
2097         return op1->shouldSpeculateBoolean() && op2->shouldSpeculateBoolean();
2098     }
2099     
2100     static bool shouldSpeculateInt32(Node* op1, Node* op2)
2101     {
2102         return op1->shouldSpeculateInt32() && op2->shouldSpeculateInt32();
2103     }
2104     
2105     static bool shouldSpeculateInt32OrBoolean(Node* op1, Node* op2)
2106     {
2107         return op1->shouldSpeculateInt32OrBoolean()
2108             && op2->shouldSpeculateInt32OrBoolean();
2109     }
2110     
2111     static bool shouldSpeculateInt32OrBooleanForArithmetic(Node* op1, Node* op2)
2112     {
2113         return op1->shouldSpeculateInt32OrBooleanForArithmetic()
2114             && op2->shouldSpeculateInt32OrBooleanForArithmetic();
2115     }
2116     
2117     static bool shouldSpeculateInt32OrBooleanExpectingDefined(Node* op1, Node* op2)
2118     {
2119         return op1->shouldSpeculateInt32OrBooleanExpectingDefined()
2120             && op2->shouldSpeculateInt32OrBooleanExpectingDefined();
2121     }
2122     
2123     static bool shouldSpeculateMachineInt(Node* op1, Node* op2)
2124     {
2125         return op1->shouldSpeculateMachineInt() && op2->shouldSpeculateMachineInt();
2126     }
2127     
2128     static bool shouldSpeculateNumber(Node* op1, Node* op2)
2129     {
2130         return op1->shouldSpeculateNumber() && op2->shouldSpeculateNumber();
2131     }
2132     
2133     static bool shouldSpeculateNumberOrBoolean(Node* op1, Node* op2)
2134     {
2135         return op1->shouldSpeculateNumberOrBoolean()
2136             && op2->shouldSpeculateNumberOrBoolean();
2137     }
2138     
2139     static bool shouldSpeculateNumberOrBooleanExpectingDefined(Node* op1, Node* op2)
2140     {
2141         return op1->shouldSpeculateNumberOrBooleanExpectingDefined()
2142             && op2->shouldSpeculateNumberOrBooleanExpectingDefined();
2143     }
2144
2145     static bool shouldSpeculateSymbol(Node* op1, Node* op2)
2146     {
2147         return op1->shouldSpeculateSymbol() && op2->shouldSpeculateSymbol();
2148     }
2149     
2150     static bool shouldSpeculateFinalObject(Node* op1, Node* op2)
2151     {
2152         return op1->shouldSpeculateFinalObject() && op2->shouldSpeculateFinalObject();
2153     }
2154
2155     static bool shouldSpeculateArray(Node* op1, Node* op2)
2156     {
2157         return op1->shouldSpeculateArray() && op2->shouldSpeculateArray();
2158     }
2159     
2160     bool canSpeculateInt32(RareCaseProfilingSource source)
2161     {
2162         return nodeCanSpeculateInt32(arithNodeFlags(), source);
2163     }
2164     
2165     bool canSpeculateInt52(RareCaseProfilingSource source)
2166     {
2167         return nodeCanSpeculateInt52(arithNodeFlags(), source);
2168     }
2169     
2170     RareCaseProfilingSource sourceFor(PredictionPass pass)
2171     {
2172         if (pass == PrimaryPass || child1()->sawBooleans() || (child2() && child2()->sawBooleans()))
2173             return DFGRareCase;
2174         return AllRareCases;
2175     }
2176     
2177     bool canSpeculateInt32(PredictionPass pass)
2178     {
2179         return canSpeculateInt32(sourceFor(pass));
2180     }
2181     
2182     bool canSpeculateInt52(PredictionPass pass)
2183     {
2184         return canSpeculateInt52(sourceFor(pass));
2185     }
2186
2187     bool hasTypeLocation()
2188     {
2189         return op() == ProfileType;
2190     }
2191
2192     TypeLocation* typeLocation()
2193     {
2194         ASSERT(hasTypeLocation());
2195         return reinterpret_cast<TypeLocation*>(m_opInfo);
2196     }
2197
2198     bool hasBasicBlockLocation()
2199     {
2200         return op() == ProfileControlFlow;
2201     }
2202
2203     BasicBlockLocation* basicBlockLocation()
2204     {
2205         ASSERT(hasBasicBlockLocation());
2206         return reinterpret_cast<BasicBlockLocation*>(m_opInfo);
2207     }
2208     
2209     Node* replacement() const
2210     {
2211         return m_misc.replacement;
2212     }
2213     
2214     void setReplacement(Node* replacement)
2215     {
2216         m_misc.replacement = replacement;
2217     }
2218     
2219     Epoch epoch() const
2220     {
2221         return Epoch::fromUnsigned(m_misc.epoch);
2222     }
2223     
2224     void setEpoch(Epoch epoch)
2225     {
2226         m_misc.epoch = epoch.toUnsigned();
2227     }
2228
2229     unsigned numberOfArgumentsToSkip()
2230     {
2231         ASSERT(op() == CopyRest || op() == GetRestLength);
2232         return static_cast<unsigned>(m_opInfo);
2233     }
2234
2235     void dumpChildren(PrintStream& out)
2236     {
2237         if (!child1())
2238             return;
2239         out.printf("@%u", child1()->index());
2240         if (!child2())
2241             return;
2242         out.printf(", @%u", child2()->index());
2243         if (!child3())
2244             return;
2245         out.printf(", @%u", child3()->index());
2246     }
2247     
2248     // NB. This class must have a trivial destructor.
2249
2250     NodeOrigin origin;
2251
2252     // References to up to 3 children, or links to a variable length set of children.
2253     AdjacencyList children;
2254
2255 private:
2256     unsigned m_op : 10; // real type is NodeType
2257     unsigned m_flags : 22;
2258     // The virtual register number (spill location) associated with this .
2259     VirtualRegister m_virtualRegister;
2260     // The number of uses of the result of this operation (+1 for 'must generate' nodes, which have side-effects).
2261     unsigned m_refCount;
2262     // The prediction ascribed to this node after propagation.
2263     SpeculatedType m_prediction;
2264     // Immediate values, accesses type-checked via accessors above. The first one is
2265     // big enough to store a pointer.
2266     uintptr_t m_opInfo;
2267     uintptr_t m_opInfo2;
2268
2269 public:
2270     // Fields used by various analyses.
2271     AbstractValue value;
2272     
2273     // Miscellaneous data that is usually meaningless, but can hold some analysis results
2274     // if you ask right. For example, if you do Graph::initializeNodeOwners(), Node::owner
2275     // will tell you which basic block a node belongs to. You cannot rely on this persisting
2276     // across transformations unless you do the maintenance work yourself. Other phases use
2277     // Node::replacement, but they do so manually: first you do Graph::clearReplacements()
2278     // and then you set, and use, replacement's yourself. Same thing for epoch.
2279     //
2280     // Bottom line: don't use these fields unless you initialize them yourself, or by
2281     // calling some appropriate methods that initialize them the way you want. Otherwise,
2282     // these fields are meaningless.
2283 private:
2284     union {
2285         Node* replacement;
2286         unsigned epoch;
2287     } m_misc;
2288 public:
2289     BasicBlock* owner;
2290 };
2291
2292 inline bool nodeComparator(Node* a, Node* b)
2293 {
2294     return a->index() < b->index();
2295 }
2296
2297 template<typename T>
2298 CString nodeListDump(const T& nodeList)
2299 {
2300     return sortedListDump(nodeList, nodeComparator);
2301 }
2302
2303 template<typename T>
2304 CString nodeMapDump(const T& nodeMap, DumpContext* context = 0)
2305 {
2306     Vector<typename T::KeyType> keys;
2307     for (
2308         typename T::const_iterator iter = nodeMap.begin();
2309         iter != nodeMap.end(); ++iter)
2310         keys.append(iter->key);
2311     std::sort(keys.begin(), keys.end(), nodeComparator);
2312     StringPrintStream out;
2313     CommaPrinter comma;
2314     for(unsigned i = 0; i < keys.size(); ++i)
2315         out.print(comma, keys[i], "=>", inContext(nodeMap.get(keys[i]), context));
2316     return out.toCString();
2317 }
2318
2319 } } // namespace JSC::DFG
2320
2321 namespace WTF {
2322
2323 void printInternal(PrintStream&, JSC::DFG::SwitchKind);
2324 void printInternal(PrintStream&, JSC::DFG::Node*);
2325
2326 inline JSC::DFG::Node* inContext(JSC::DFG::Node* node, JSC::DumpContext*) { return node; }
2327
2328 } // namespace WTF
2329
2330 using WTF::inContext;
2331
2332 #endif
2333 #endif