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