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