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