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