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