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