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