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