Update the argument count in DFGByteCodeParser::handleRecursiveCall
[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();
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(Node* other)
455     {
456         remove();
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     bool hasQueriedType()
1269     {
1270         return op() == IsCellWithType;
1271     }
1272
1273     JSType queriedType()
1274     {
1275         static_assert(std::is_same<uint8_t, std::underlying_type<JSType>::type>::value, "Ensure that uint8_t is the underlying type for JSType.");
1276         return static_cast<JSType>(m_opInfo.as<uint32_t>());
1277     }
1278
1279     bool hasSpeculatedTypeForQuery()
1280     {
1281         return op() == IsCellWithType;
1282     }
1283
1284     SpeculatedType speculatedTypeForQuery()
1285     {
1286         return speculationFromJSType(queriedType());
1287     }
1288     
1289     bool hasResult()
1290     {
1291         return !!result();
1292     }
1293     
1294     bool hasInt52Result()
1295     {
1296         return result() == NodeResultInt52;
1297     }
1298     
1299     bool hasNumberResult()
1300     {
1301         return result() == NodeResultNumber;
1302     }
1303     
1304     bool hasDoubleResult()
1305     {
1306         return result() == NodeResultDouble;
1307     }
1308     
1309     bool hasJSResult()
1310     {
1311         return result() == NodeResultJS;
1312     }
1313     
1314     bool hasBooleanResult()
1315     {
1316         return result() == NodeResultBoolean;
1317     }
1318
1319     bool hasStorageResult()
1320     {
1321         return result() == NodeResultStorage;
1322     }
1323     
1324     UseKind defaultUseKind()
1325     {
1326         return useKindForResult(result());
1327     }
1328     
1329     Edge defaultEdge()
1330     {
1331         return Edge(this, defaultUseKind());
1332     }
1333
1334     bool isJump()
1335     {
1336         return op() == Jump;
1337     }
1338
1339     bool isBranch()
1340     {
1341         return op() == Branch;
1342     }
1343     
1344     bool isSwitch() const
1345     {
1346         return op() == Switch;
1347     }
1348
1349     bool isEntrySwitch() const
1350     {
1351         return op() == EntrySwitch;
1352     }
1353
1354     bool isTerminal()
1355     {
1356         switch (op()) {
1357         case Jump:
1358         case Branch:
1359         case Switch:
1360         case EntrySwitch:
1361         case Return:
1362         case TailCall:
1363         case DirectTailCall:
1364         case TailCallVarargs:
1365         case TailCallForwardVarargs:
1366         case Unreachable:
1367         case Throw:
1368         case ThrowStaticError:
1369             return true;
1370         default:
1371             return false;
1372         }
1373     }
1374
1375     bool isFunctionTerminal()
1376     {
1377         if (isTerminal() && !numSuccessors())
1378             return true;
1379
1380         return false;
1381     }
1382
1383     // As is described in DFGNodeType.h's ForceOSRExit, this is a pseudo-terminal.
1384     // It means that execution should fall out of DFG at this point, but execution
1385     // does continue in the basic block - just in a different compiler.
1386     // FIXME: This is used for lightweight reachability decision. But this should
1387     // be replaced with AI-based reachability ideally.
1388     bool isPseudoTerminal()
1389     {
1390         switch (op()) {
1391         case ForceOSRExit:
1392         case CheckBadCell:
1393             return true;
1394         default:
1395             return false;
1396         }
1397     }
1398
1399     unsigned targetBytecodeOffsetDuringParsing()
1400     {
1401         ASSERT(isJump());
1402         return m_opInfo.as<unsigned>();
1403     }
1404
1405     BasicBlock*& targetBlock()
1406     {
1407         ASSERT(isJump());
1408         return *bitwise_cast<BasicBlock**>(&m_opInfo.u.pointer);
1409     }
1410     
1411     BranchData* branchData()
1412     {
1413         ASSERT(isBranch());
1414         return m_opInfo.as<BranchData*>();
1415     }
1416     
1417     SwitchData* switchData()
1418     {
1419         ASSERT(isSwitch());
1420         return m_opInfo.as<SwitchData*>();
1421     }
1422
1423     EntrySwitchData* entrySwitchData()
1424     {
1425         ASSERT(isEntrySwitch());
1426         return m_opInfo.as<EntrySwitchData*>();
1427     }
1428
1429     Intrinsic intrinsic()
1430     {
1431         RELEASE_ASSERT(op() == CPUIntrinsic);
1432         return m_opInfo.as<Intrinsic>();
1433     }
1434     
1435     unsigned numSuccessors()
1436     {
1437         switch (op()) {
1438         case Jump:
1439             return 1;
1440         case Branch:
1441             return 2;
1442         case Switch:
1443             return switchData()->cases.size() + 1;
1444         case EntrySwitch:
1445             return entrySwitchData()->cases.size();
1446         default:
1447             return 0;
1448         }
1449     }
1450     
1451     BasicBlock*& successor(unsigned index)
1452     {
1453         if (isSwitch()) {
1454             if (index < switchData()->cases.size())
1455                 return switchData()->cases[index].target.block;
1456             RELEASE_ASSERT(index == switchData()->cases.size());
1457             return switchData()->fallThrough.block;
1458         } else if (isEntrySwitch())
1459             return entrySwitchData()->cases[index];
1460
1461         switch (index) {
1462         case 0:
1463             if (isJump())
1464                 return targetBlock();
1465             return branchData()->taken.block;
1466         case 1:
1467             return branchData()->notTaken.block;
1468         default:
1469             RELEASE_ASSERT_NOT_REACHED();
1470             return targetBlock();
1471         }
1472     }
1473     
1474     class SuccessorsIterable {
1475     public:
1476         SuccessorsIterable()
1477             : m_terminal(nullptr)
1478         {
1479         }
1480         
1481         SuccessorsIterable(Node* terminal)
1482             : m_terminal(terminal)
1483         {
1484         }
1485         
1486         class iterator {
1487         public:
1488             iterator()
1489                 : m_terminal(nullptr)
1490                 , m_index(UINT_MAX)
1491             {
1492             }
1493             
1494             iterator(Node* terminal, unsigned index)
1495                 : m_terminal(terminal)
1496                 , m_index(index)
1497             {
1498             }
1499             
1500             BasicBlock* operator*()
1501             {
1502                 return m_terminal->successor(m_index);
1503             }
1504             
1505             iterator& operator++()
1506             {
1507                 m_index++;
1508                 return *this;
1509             }
1510             
1511             bool operator==(const iterator& other) const
1512             {
1513                 return m_index == other.m_index;
1514             }
1515             
1516             bool operator!=(const iterator& other) const
1517             {
1518                 return !(*this == other);
1519             }
1520         private:
1521             Node* m_terminal;
1522             unsigned m_index;
1523         };
1524         
1525         iterator begin()
1526         {
1527             return iterator(m_terminal, 0);
1528         }
1529         
1530         iterator end()
1531         {
1532             return iterator(m_terminal, m_terminal->numSuccessors());
1533         }
1534
1535         size_t size() const { return m_terminal->numSuccessors(); }
1536         BasicBlock* at(size_t index) const { return m_terminal->successor(index); }
1537         BasicBlock* operator[](size_t index) const { return at(index); }
1538         
1539     private:
1540         Node* m_terminal;
1541     };
1542     
1543     SuccessorsIterable successors()
1544     {
1545         return SuccessorsIterable(this);
1546     }
1547     
1548     BasicBlock*& successorForCondition(bool condition)
1549     {
1550         return branchData()->forCondition(condition);
1551     }
1552     
1553     bool hasHeapPrediction()
1554     {
1555         switch (op()) {
1556         case ArithAbs:
1557         case ArithRound:
1558         case ArithFloor:
1559         case ArithCeil:
1560         case ArithTrunc:
1561         case GetDirectPname:
1562         case GetById:
1563         case GetByIdFlush:
1564         case GetByIdWithThis:
1565         case GetPrototypeOf:
1566         case TryGetById:
1567         case GetByVal:
1568         case GetByValWithThis:
1569         case Call:
1570         case DirectCall:
1571         case TailCallInlinedCaller:
1572         case DirectTailCallInlinedCaller:
1573         case Construct:
1574         case DirectConstruct:
1575         case CallVarargs:
1576         case CallEval:
1577         case TailCallVarargsInlinedCaller:
1578         case ConstructVarargs:
1579         case CallForwardVarargs:
1580         case TailCallForwardVarargsInlinedCaller:
1581         case GetByOffset:
1582         case MultiGetByOffset:
1583         case GetClosureVar:
1584         case GetFromArguments:
1585         case GetArgument:
1586         case ArrayPop:
1587         case ArrayPush:
1588         case RegExpExec:
1589         case RegExpExecNonGlobalOrSticky:
1590         case RegExpTest:
1591         case RegExpMatchFast:
1592         case GetGlobalVar:
1593         case GetGlobalLexicalVariable:
1594         case StringReplace:
1595         case StringReplaceRegExp:
1596         case ToNumber:
1597         case ToObject:
1598         case CallObjectConstructor:
1599         case LoadKeyFromMapBucket:
1600         case LoadValueFromMapBucket:
1601         case CallDOMGetter:
1602         case CallDOM:
1603         case ParseInt:
1604         case AtomicsAdd:
1605         case AtomicsAnd:
1606         case AtomicsCompareExchange:
1607         case AtomicsExchange:
1608         case AtomicsLoad:
1609         case AtomicsOr:
1610         case AtomicsStore:
1611         case AtomicsSub:
1612         case AtomicsXor:
1613         case GetDynamicVar:
1614         case ExtractValueFromWeakMapGet:
1615         case ToThis:
1616             return true;
1617         default:
1618             return false;
1619         }
1620     }
1621     
1622     SpeculatedType getHeapPrediction()
1623     {
1624         ASSERT(hasHeapPrediction());
1625         return m_opInfo2.as<SpeculatedType>();
1626     }
1627
1628     void setHeapPrediction(SpeculatedType prediction)
1629     {
1630         ASSERT(hasHeapPrediction());
1631         m_opInfo2 = prediction;
1632     }
1633
1634     SpeculatedType getForcedPrediction()
1635     {
1636         ASSERT(op() == IdentityWithProfile);
1637         return m_opInfo.as<SpeculatedType>();
1638     }
1639
1640     uint32_t catchOSREntryIndex() const
1641     {
1642         ASSERT(op() == ExtractCatchLocal);
1643         return m_opInfo.as<uint32_t>();
1644     }
1645
1646     SpeculatedType catchLocalPrediction()
1647     {
1648         ASSERT(op() == ExtractCatchLocal);
1649         return m_opInfo2.as<SpeculatedType>();
1650     }
1651     
1652     bool hasCellOperand()
1653     {
1654         switch (op()) {
1655         case CheckCell:
1656         case OverridesHasInstance:
1657         case NewFunction:
1658         case NewGeneratorFunction:
1659         case NewAsyncFunction:
1660         case NewAsyncGeneratorFunction:
1661         case CreateActivation:
1662         case MaterializeCreateActivation:
1663         case NewRegexp:
1664         case NewArrayBuffer:
1665         case PhantomNewArrayBuffer:
1666         case CompareEqPtr:
1667         case CallObjectConstructor:
1668         case DirectCall:
1669         case DirectTailCall:
1670         case DirectConstruct:
1671         case DirectTailCallInlinedCaller:
1672         case RegExpExecNonGlobalOrSticky:
1673             return true;
1674         default:
1675             return false;
1676         }
1677     }
1678
1679     FrozenValue* cellOperand()
1680     {
1681         ASSERT(hasCellOperand());
1682         return m_opInfo.as<FrozenValue*>();
1683     }
1684     
1685     template<typename T>
1686     T castOperand()
1687     {
1688         return cellOperand()->cast<T>();
1689     }
1690     
1691     void setCellOperand(FrozenValue* value)
1692     {
1693         ASSERT(hasCellOperand());
1694         m_opInfo = value;
1695     }
1696     
1697     bool hasWatchpointSet()
1698     {
1699         return op() == NotifyWrite;
1700     }
1701     
1702     WatchpointSet* watchpointSet()
1703     {
1704         ASSERT(hasWatchpointSet());
1705         return m_opInfo.as<WatchpointSet*>();
1706     }
1707     
1708     bool hasStoragePointer()
1709     {
1710         return op() == ConstantStoragePointer;
1711     }
1712     
1713     void* storagePointer()
1714     {
1715         ASSERT(hasStoragePointer());
1716         return m_opInfo.as<void*>();
1717     }
1718
1719     bool hasUidOperand()
1720     {
1721         return op() == CheckStringIdent;
1722     }
1723
1724     UniquedStringImpl* uidOperand()
1725     {
1726         ASSERT(hasUidOperand());
1727         return m_opInfo.as<UniquedStringImpl*>();
1728     }
1729
1730     bool hasTypeInfoOperand()
1731     {
1732         return op() == CheckTypeInfoFlags;
1733     }
1734
1735     unsigned typeInfoOperand()
1736     {
1737         ASSERT(hasTypeInfoOperand() && m_opInfo.as<uint32_t>() <= static_cast<uint32_t>(UCHAR_MAX));
1738         return m_opInfo.as<uint32_t>();
1739     }
1740
1741     bool hasTransition()
1742     {
1743         switch (op()) {
1744         case PutStructure:
1745         case AllocatePropertyStorage:
1746         case ReallocatePropertyStorage:
1747             return true;
1748         default:
1749             return false;
1750         }
1751     }
1752     
1753     Transition* transition()
1754     {
1755         ASSERT(hasTransition());
1756         return m_opInfo.as<Transition*>();
1757     }
1758     
1759     bool hasStructureSet()
1760     {
1761         switch (op()) {
1762         case CheckStructure:
1763         case CheckStructureOrEmpty:
1764         case CheckStructureImmediate:
1765         case MaterializeNewObject:
1766             return true;
1767         default:
1768             return false;
1769         }
1770     }
1771     
1772     const RegisteredStructureSet& structureSet()
1773     {
1774         ASSERT(hasStructureSet());
1775         return *m_opInfo.as<RegisteredStructureSet*>();
1776     }
1777     
1778     bool hasStructure()
1779     {
1780         switch (op()) {
1781         case ArrayifyToStructure:
1782         case NewObject:
1783         case NewStringObject:
1784             return true;
1785         default:
1786             return false;
1787         }
1788     }
1789     
1790     RegisteredStructure structure()
1791     {
1792         ASSERT(hasStructure());
1793         return m_opInfo.asRegisteredStructure();
1794     }
1795     
1796     bool hasStorageAccessData()
1797     {
1798         switch (op()) {
1799         case GetByOffset:
1800         case PutByOffset:
1801         case GetGetterSetterByOffset:
1802             return true;
1803         default:
1804             return false;
1805         }
1806     }
1807     
1808     StorageAccessData& storageAccessData()
1809     {
1810         ASSERT(hasStorageAccessData());
1811         return *m_opInfo.as<StorageAccessData*>();
1812     }
1813     
1814     bool hasMultiGetByOffsetData()
1815     {
1816         return op() == MultiGetByOffset;
1817     }
1818     
1819     MultiGetByOffsetData& multiGetByOffsetData()
1820     {
1821         ASSERT(hasMultiGetByOffsetData());
1822         return *m_opInfo.as<MultiGetByOffsetData*>();
1823     }
1824     
1825     bool hasMultiPutByOffsetData()
1826     {
1827         return op() == MultiPutByOffset;
1828     }
1829     
1830     MultiPutByOffsetData& multiPutByOffsetData()
1831     {
1832         ASSERT(hasMultiPutByOffsetData());
1833         return *m_opInfo.as<MultiPutByOffsetData*>();
1834     }
1835     
1836     bool hasObjectMaterializationData()
1837     {
1838         switch (op()) {
1839         case MaterializeNewObject:
1840         case MaterializeCreateActivation:
1841             return true;
1842
1843         default:
1844             return false;
1845         }
1846     }
1847     
1848     ObjectMaterializationData& objectMaterializationData()
1849     {
1850         ASSERT(hasObjectMaterializationData());
1851         return *m_opInfo2.as<ObjectMaterializationData*>();
1852     }
1853
1854     bool isObjectAllocation()
1855     {
1856         switch (op()) {
1857         case NewObject:
1858         case MaterializeNewObject:
1859             return true;
1860         default:
1861             return false;
1862         }
1863     }
1864     
1865     bool isPhantomObjectAllocation()
1866     {
1867         switch (op()) {
1868         case PhantomNewObject:
1869             return true;
1870         default:
1871             return false;
1872         }
1873     }
1874     
1875     bool isActivationAllocation()
1876     {
1877         switch (op()) {
1878         case CreateActivation:
1879         case MaterializeCreateActivation:
1880             return true;
1881         default:
1882             return false;
1883         }
1884     }
1885
1886     bool isPhantomActivationAllocation()
1887     {
1888         switch (op()) {
1889         case PhantomCreateActivation:
1890             return true;
1891         default:
1892             return false;
1893         }
1894     }
1895
1896     bool isFunctionAllocation()
1897     {
1898         switch (op()) {
1899         case NewFunction:
1900         case NewGeneratorFunction:
1901         case NewAsyncGeneratorFunction:
1902         case NewAsyncFunction:
1903             return true;
1904         default:
1905             return false;
1906         }
1907     }
1908
1909     bool isPhantomFunctionAllocation()
1910     {
1911         switch (op()) {
1912         case PhantomNewFunction:
1913         case PhantomNewGeneratorFunction:
1914         case PhantomNewAsyncFunction:
1915         case PhantomNewAsyncGeneratorFunction:
1916             return true;
1917         default:
1918             return false;
1919         }
1920     }
1921
1922     bool isPhantomAllocation()
1923     {
1924         switch (op()) {
1925         case PhantomNewObject:
1926         case PhantomDirectArguments:
1927         case PhantomCreateRest:
1928         case PhantomSpread:
1929         case PhantomNewArrayWithSpread:
1930         case PhantomNewArrayBuffer:
1931         case PhantomClonedArguments:
1932         case PhantomNewFunction:
1933         case PhantomNewGeneratorFunction:
1934         case PhantomNewAsyncFunction:
1935         case PhantomNewAsyncGeneratorFunction:
1936         case PhantomCreateActivation:
1937         case PhantomNewRegexp:
1938             return true;
1939         default:
1940             return false;
1941         }
1942     }
1943     
1944     bool hasArrayMode()
1945     {
1946         switch (op()) {
1947         case GetIndexedPropertyStorage:
1948         case GetArrayLength:
1949         case GetVectorLength:
1950         case In:
1951         case PutByValDirect:
1952         case PutByVal:
1953         case PutByValAlias:
1954         case GetByVal:
1955         case StringCharAt:
1956         case StringCharCodeAt:
1957         case CheckArray:
1958         case Arrayify:
1959         case ArrayifyToStructure:
1960         case ArrayPush:
1961         case ArrayPop:
1962         case ArrayIndexOf:
1963         case HasIndexedProperty:
1964         case AtomicsAdd:
1965         case AtomicsAnd:
1966         case AtomicsCompareExchange:
1967         case AtomicsExchange:
1968         case AtomicsLoad:
1969         case AtomicsOr:
1970         case AtomicsStore:
1971         case AtomicsSub:
1972         case AtomicsXor:
1973             return true;
1974         default:
1975             return false;
1976         }
1977     }
1978     
1979     ArrayMode arrayMode()
1980     {
1981         ASSERT(hasArrayMode());
1982         if (op() == ArrayifyToStructure)
1983             return ArrayMode::fromWord(m_opInfo2.as<uint32_t>());
1984         return ArrayMode::fromWord(m_opInfo.as<uint32_t>());
1985     }
1986     
1987     bool setArrayMode(ArrayMode arrayMode)
1988     {
1989         ASSERT(hasArrayMode());
1990         if (this->arrayMode() == arrayMode)
1991             return false;
1992         m_opInfo = arrayMode.asWord();
1993         return true;
1994     }
1995     
1996     bool hasArithMode()
1997     {
1998         switch (op()) {
1999         case ArithAbs:
2000         case ArithAdd:
2001         case ArithSub:
2002         case ArithNegate:
2003         case ArithMul:
2004         case ArithDiv:
2005         case ArithMod:
2006         case UInt32ToNumber:
2007         case DoubleAsInt32:
2008             return true;
2009         default:
2010             return false;
2011         }
2012     }
2013
2014     Arith::Mode arithMode()
2015     {
2016         ASSERT(hasArithMode());
2017         return static_cast<Arith::Mode>(m_opInfo.as<uint32_t>());
2018     }
2019     
2020     void setArithMode(Arith::Mode mode)
2021     {
2022         m_opInfo = mode;
2023     }
2024
2025     bool hasArithRoundingMode()
2026     {
2027         return op() == ArithRound || op() == ArithFloor || op() == ArithCeil || op() == ArithTrunc;
2028     }
2029
2030     Arith::RoundingMode arithRoundingMode()
2031     {
2032         ASSERT(hasArithRoundingMode());
2033         return static_cast<Arith::RoundingMode>(m_opInfo.as<uint32_t>());
2034     }
2035
2036     void setArithRoundingMode(Arith::RoundingMode mode)
2037     {
2038         ASSERT(hasArithRoundingMode());
2039         m_opInfo = static_cast<uint32_t>(mode);
2040     }
2041
2042     bool hasArithUnaryType()
2043     {
2044         return op() == ArithUnary;
2045     }
2046
2047     Arith::UnaryType arithUnaryType()
2048     {
2049         ASSERT(hasArithUnaryType());
2050         return static_cast<Arith::UnaryType>(m_opInfo.as<uint32_t>());
2051     }
2052     
2053     bool hasVirtualRegister()
2054     {
2055         return m_virtualRegister.isValid();
2056     }
2057
2058     VirtualRegister virtualRegister()
2059     {
2060         ASSERT(hasResult());
2061         ASSERT(m_virtualRegister.isValid());
2062         return m_virtualRegister;
2063     }
2064     
2065     void setVirtualRegister(VirtualRegister virtualRegister)
2066     {
2067         ASSERT(hasResult());
2068         ASSERT(!m_virtualRegister.isValid());
2069         m_virtualRegister = virtualRegister;
2070     }
2071     
2072     bool hasExecutionCounter()
2073     {
2074         return op() == CountExecution;
2075     }
2076     
2077     Profiler::ExecutionCounter* executionCounter()
2078     {
2079         return m_opInfo.as<Profiler::ExecutionCounter*>();
2080     }
2081
2082     unsigned entrypointIndex()
2083     {
2084         ASSERT(op() == InitializeEntrypointArguments);
2085         return m_opInfo.as<unsigned>();
2086     }
2087
2088     bool shouldGenerate()
2089     {
2090         return m_refCount;
2091     }
2092     
2093     // Return true if the execution of this Node does not affect our ability to OSR to the FTL.
2094     // FIXME: Isn't this just like checking if the node has effects?
2095     bool isSemanticallySkippable()
2096     {
2097         return op() == CountExecution || op() == InvalidationPoint;
2098     }
2099
2100     unsigned refCount()
2101     {
2102         return m_refCount;
2103     }
2104
2105     unsigned postfixRef()
2106     {
2107         return m_refCount++;
2108     }
2109
2110     unsigned adjustedRefCount()
2111     {
2112         return mustGenerate() ? m_refCount - 1 : m_refCount;
2113     }
2114     
2115     void setRefCount(unsigned refCount)
2116     {
2117         m_refCount = refCount;
2118     }
2119     
2120     Edge& child1()
2121     {
2122         ASSERT(!(m_flags & NodeHasVarArgs));
2123         return children.child1();
2124     }
2125     
2126     // This is useful if you want to do a fast check on the first child
2127     // before also doing a check on the opcode. Use this with care and
2128     // avoid it if possible.
2129     Edge child1Unchecked()
2130     {
2131         return children.child1Unchecked();
2132     }
2133
2134     Edge& child2()
2135     {
2136         ASSERT(!(m_flags & NodeHasVarArgs));
2137         return children.child2();
2138     }
2139
2140     Edge& child3()
2141     {
2142         ASSERT(!(m_flags & NodeHasVarArgs));
2143         return children.child3();
2144     }
2145     
2146     unsigned firstChild()
2147     {
2148         ASSERT(m_flags & NodeHasVarArgs);
2149         return children.firstChild();
2150     }
2151     
2152     unsigned numChildren()
2153     {
2154         ASSERT(m_flags & NodeHasVarArgs);
2155         return children.numChildren();
2156     }
2157     
2158     UseKind binaryUseKind()
2159     {
2160         ASSERT(child1().useKind() == child2().useKind());
2161         return child1().useKind();
2162     }
2163     
2164     bool isBinaryUseKind(UseKind left, UseKind right)
2165     {
2166         return child1().useKind() == left && child2().useKind() == right;
2167     }
2168     
2169     bool isBinaryUseKind(UseKind useKind)
2170     {
2171         return isBinaryUseKind(useKind, useKind);
2172     }
2173     
2174     Edge childFor(UseKind useKind)
2175     {
2176         if (child1().useKind() == useKind)
2177             return child1();
2178         if (child2().useKind() == useKind)
2179             return child2();
2180         if (child3().useKind() == useKind)
2181             return child3();
2182         return Edge();
2183     }
2184     
2185     SpeculatedType prediction()
2186     {
2187         return m_prediction;
2188     }
2189     
2190     bool predict(SpeculatedType prediction)
2191     {
2192         return mergeSpeculation(m_prediction, prediction);
2193     }
2194     
2195     bool shouldSpeculateInt32()
2196     {
2197         return isInt32Speculation(prediction());
2198     }
2199
2200     bool shouldSpeculateNotInt32()
2201     {
2202         return isNotInt32Speculation(prediction());
2203     }
2204     
2205     bool sawBooleans()
2206     {
2207         return !!(prediction() & SpecBoolean);
2208     }
2209     
2210     bool shouldSpeculateInt32OrBoolean()
2211     {
2212         return isInt32OrBooleanSpeculation(prediction());
2213     }
2214     
2215     bool shouldSpeculateInt32ForArithmetic()
2216     {
2217         return isInt32SpeculationForArithmetic(prediction());
2218     }
2219     
2220     bool shouldSpeculateInt32OrBooleanForArithmetic()
2221     {
2222         return isInt32OrBooleanSpeculationForArithmetic(prediction());
2223     }
2224     
2225     bool shouldSpeculateInt32OrBooleanExpectingDefined()
2226     {
2227         return isInt32OrBooleanSpeculationExpectingDefined(prediction());
2228     }
2229     
2230     bool shouldSpeculateAnyInt()
2231     {
2232         return isAnyIntSpeculation(prediction());
2233     }
2234     
2235     bool shouldSpeculateDouble()
2236     {
2237         return isDoubleSpeculation(prediction());
2238     }
2239     
2240     bool shouldSpeculateDoubleReal()
2241     {
2242         return isDoubleRealSpeculation(prediction());
2243     }
2244     
2245     bool shouldSpeculateNumber()
2246     {
2247         return isFullNumberSpeculation(prediction());
2248     }
2249     
2250     bool shouldSpeculateNumberOrBoolean()
2251     {
2252         return isFullNumberOrBooleanSpeculation(prediction());
2253     }
2254     
2255     bool shouldSpeculateNumberOrBooleanExpectingDefined()
2256     {
2257         return isFullNumberOrBooleanSpeculationExpectingDefined(prediction());
2258     }
2259     
2260     bool shouldSpeculateBoolean()
2261     {
2262         return isBooleanSpeculation(prediction());
2263     }
2264
2265     bool shouldSpeculateNotBoolean()
2266     {
2267         return isNotBooleanSpeculation(prediction());
2268     }
2269     
2270     bool shouldSpeculateOther()
2271     {
2272         return isOtherSpeculation(prediction());
2273     }
2274     
2275     bool shouldSpeculateMisc()
2276     {
2277         return isMiscSpeculation(prediction());
2278     }
2279    
2280     bool shouldSpeculateStringIdent()
2281     {
2282         return isStringIdentSpeculation(prediction());
2283     }
2284     
2285     bool shouldSpeculateNotStringVar()
2286     {
2287         return isNotStringVarSpeculation(prediction());
2288     }
2289  
2290     bool shouldSpeculateString()
2291     {
2292         return isStringSpeculation(prediction());
2293     }
2294
2295     bool shouldSpeculateNotString()
2296     {
2297         return isNotStringSpeculation(prediction());
2298     }
2299  
2300     bool shouldSpeculateStringOrOther()
2301     {
2302         return isStringOrOtherSpeculation(prediction());
2303     }
2304  
2305     bool shouldSpeculateStringObject()
2306     {
2307         return isStringObjectSpeculation(prediction());
2308     }
2309     
2310     bool shouldSpeculateStringOrStringObject()
2311     {
2312         return isStringOrStringObjectSpeculation(prediction());
2313     }
2314
2315     bool shouldSpeculateRegExpObject()
2316     {
2317         return isRegExpObjectSpeculation(prediction());
2318     }
2319     
2320     bool shouldSpeculateSymbol()
2321     {
2322         return isSymbolSpeculation(prediction());
2323     }
2324     
2325     bool shouldSpeculateFinalObject()
2326     {
2327         return isFinalObjectSpeculation(prediction());
2328     }
2329     
2330     bool shouldSpeculateFinalObjectOrOther()
2331     {
2332         return isFinalObjectOrOtherSpeculation(prediction());
2333     }
2334     
2335     bool shouldSpeculateArray()
2336     {
2337         return isArraySpeculation(prediction());
2338     }
2339
2340     bool shouldSpeculateFunction()
2341     {
2342         return isFunctionSpeculation(prediction());
2343     }
2344
2345     bool shouldSpeculateProxyObject()
2346     {
2347         return isProxyObjectSpeculation(prediction());
2348     }
2349
2350     bool shouldSpeculateDerivedArray()
2351     {
2352         return isDerivedArraySpeculation(prediction());
2353     }
2354     
2355     bool shouldSpeculateDirectArguments()
2356     {
2357         return isDirectArgumentsSpeculation(prediction());
2358     }
2359     
2360     bool shouldSpeculateScopedArguments()
2361     {
2362         return isScopedArgumentsSpeculation(prediction());
2363     }
2364     
2365     bool shouldSpeculateInt8Array()
2366     {
2367         return isInt8ArraySpeculation(prediction());
2368     }
2369     
2370     bool shouldSpeculateInt16Array()
2371     {
2372         return isInt16ArraySpeculation(prediction());
2373     }
2374     
2375     bool shouldSpeculateInt32Array()
2376     {
2377         return isInt32ArraySpeculation(prediction());
2378     }
2379     
2380     bool shouldSpeculateUint8Array()
2381     {
2382         return isUint8ArraySpeculation(prediction());
2383     }
2384
2385     bool shouldSpeculateUint8ClampedArray()
2386     {
2387         return isUint8ClampedArraySpeculation(prediction());
2388     }
2389     
2390     bool shouldSpeculateUint16Array()
2391     {
2392         return isUint16ArraySpeculation(prediction());
2393     }
2394     
2395     bool shouldSpeculateUint32Array()
2396     {
2397         return isUint32ArraySpeculation(prediction());
2398     }
2399     
2400     bool shouldSpeculateFloat32Array()
2401     {
2402         return isFloat32ArraySpeculation(prediction());
2403     }
2404     
2405     bool shouldSpeculateFloat64Array()
2406     {
2407         return isFloat64ArraySpeculation(prediction());
2408     }
2409     
2410     bool shouldSpeculateArrayOrOther()
2411     {
2412         return isArrayOrOtherSpeculation(prediction());
2413     }
2414     
2415     bool shouldSpeculateObject()
2416     {
2417         return isObjectSpeculation(prediction());
2418     }
2419     
2420     bool shouldSpeculateObjectOrOther()
2421     {
2422         return isObjectOrOtherSpeculation(prediction());
2423     }
2424
2425     bool shouldSpeculateCell()
2426     {
2427         return isCellSpeculation(prediction());
2428     }
2429     
2430     bool shouldSpeculateCellOrOther()
2431     {
2432         return isCellOrOtherSpeculation(prediction());
2433     }
2434     
2435     bool shouldSpeculateNotCell()
2436     {
2437         return isNotCellSpeculation(prediction());
2438     }
2439     
2440     bool shouldSpeculateUntypedForArithmetic()
2441     {
2442         return isUntypedSpeculationForArithmetic(prediction());
2443     }
2444
2445     static bool shouldSpeculateUntypedForArithmetic(Node* op1, Node* op2)
2446     {
2447         return op1->shouldSpeculateUntypedForArithmetic() || op2->shouldSpeculateUntypedForArithmetic();
2448     }
2449     
2450     bool shouldSpeculateUntypedForBitOps()
2451     {
2452         return isUntypedSpeculationForBitOps(prediction());
2453     }
2454     
2455     static bool shouldSpeculateUntypedForBitOps(Node* op1, Node* op2)
2456     {
2457         return op1->shouldSpeculateUntypedForBitOps() || op2->shouldSpeculateUntypedForBitOps();
2458     }
2459     
2460     static bool shouldSpeculateBoolean(Node* op1, Node* op2)
2461     {
2462         return op1->shouldSpeculateBoolean() && op2->shouldSpeculateBoolean();
2463     }
2464     
2465     static bool shouldSpeculateInt32(Node* op1, Node* op2)
2466     {
2467         return op1->shouldSpeculateInt32() && op2->shouldSpeculateInt32();
2468     }
2469     
2470     static bool shouldSpeculateInt32OrBoolean(Node* op1, Node* op2)
2471     {
2472         return op1->shouldSpeculateInt32OrBoolean()
2473             && op2->shouldSpeculateInt32OrBoolean();
2474     }
2475     
2476     static bool shouldSpeculateInt32OrBooleanForArithmetic(Node* op1, Node* op2)
2477     {
2478         return op1->shouldSpeculateInt32OrBooleanForArithmetic()
2479             && op2->shouldSpeculateInt32OrBooleanForArithmetic();
2480     }
2481     
2482     static bool shouldSpeculateInt32OrBooleanExpectingDefined(Node* op1, Node* op2)
2483     {
2484         return op1->shouldSpeculateInt32OrBooleanExpectingDefined()
2485             && op2->shouldSpeculateInt32OrBooleanExpectingDefined();
2486     }
2487     
2488     static bool shouldSpeculateAnyInt(Node* op1, Node* op2)
2489     {
2490         return op1->shouldSpeculateAnyInt() && op2->shouldSpeculateAnyInt();
2491     }
2492     
2493     static bool shouldSpeculateNumber(Node* op1, Node* op2)
2494     {
2495         return op1->shouldSpeculateNumber() && op2->shouldSpeculateNumber();
2496     }
2497     
2498     static bool shouldSpeculateNumberOrBoolean(Node* op1, Node* op2)
2499     {
2500         return op1->shouldSpeculateNumberOrBoolean()
2501             && op2->shouldSpeculateNumberOrBoolean();
2502     }
2503     
2504     static bool shouldSpeculateNumberOrBooleanExpectingDefined(Node* op1, Node* op2)
2505     {
2506         return op1->shouldSpeculateNumberOrBooleanExpectingDefined()
2507             && op2->shouldSpeculateNumberOrBooleanExpectingDefined();
2508     }
2509
2510     static bool shouldSpeculateSymbol(Node* op1, Node* op2)
2511     {
2512         return op1->shouldSpeculateSymbol() && op2->shouldSpeculateSymbol();
2513     }
2514     
2515     static bool shouldSpeculateFinalObject(Node* op1, Node* op2)
2516     {
2517         return op1->shouldSpeculateFinalObject() && op2->shouldSpeculateFinalObject();
2518     }
2519
2520     static bool shouldSpeculateArray(Node* op1, Node* op2)
2521     {
2522         return op1->shouldSpeculateArray() && op2->shouldSpeculateArray();
2523     }
2524     
2525     bool canSpeculateInt32(RareCaseProfilingSource source)
2526     {
2527         return nodeCanSpeculateInt32(arithNodeFlags(), source);
2528     }
2529     
2530     bool canSpeculateInt52(RareCaseProfilingSource source)
2531     {
2532         return nodeCanSpeculateInt52(arithNodeFlags(), source);
2533     }
2534     
2535     RareCaseProfilingSource sourceFor(PredictionPass pass)
2536     {
2537         if (pass == PrimaryPass || child1()->sawBooleans() || (child2() && child2()->sawBooleans()))
2538             return DFGRareCase;
2539         return AllRareCases;
2540     }
2541     
2542     bool canSpeculateInt32(PredictionPass pass)
2543     {
2544         return canSpeculateInt32(sourceFor(pass));
2545     }
2546     
2547     bool canSpeculateInt52(PredictionPass pass)
2548     {
2549         return canSpeculateInt52(sourceFor(pass));
2550     }
2551
2552     bool hasTypeLocation()
2553     {
2554         return op() == ProfileType;
2555     }
2556
2557     TypeLocation* typeLocation()
2558     {
2559         ASSERT(hasTypeLocation());
2560         return m_opInfo.as<TypeLocation*>();
2561     }
2562
2563     bool hasBasicBlockLocation()
2564     {
2565         return op() == ProfileControlFlow;
2566     }
2567
2568     BasicBlockLocation* basicBlockLocation()
2569     {
2570         ASSERT(hasBasicBlockLocation());
2571         return m_opInfo.as<BasicBlockLocation*>();
2572     }
2573
2574     bool hasCallDOMGetterData() const
2575     {
2576         return op() == CallDOMGetter;
2577     }
2578
2579     CallDOMGetterData* callDOMGetterData()
2580     {
2581         ASSERT(hasCallDOMGetterData());
2582         return m_opInfo.as<CallDOMGetterData*>();
2583     }
2584
2585     bool hasClassInfo() const
2586     {
2587         return op() == CheckSubClass;
2588     }
2589
2590     const ClassInfo* classInfo()
2591     {
2592         return m_opInfo.as<const ClassInfo*>();
2593     }
2594
2595     bool hasSignature() const
2596     {
2597         // Note that this does not include TailCall node types intentionally.
2598         // CallDOM node types are always converted from Call.
2599         return op() == Call || op() == CallDOM;
2600     }
2601
2602     const DOMJIT::Signature* signature()
2603     {
2604         return m_opInfo.as<const DOMJIT::Signature*>();
2605     }
2606
2607     bool hasInternalMethodType() const
2608     {
2609         return op() == HasIndexedProperty;
2610     }
2611
2612     PropertySlot::InternalMethodType internalMethodType() const
2613     {
2614         ASSERT(hasInternalMethodType());
2615         return static_cast<PropertySlot::InternalMethodType>(m_opInfo2.as<uint32_t>());
2616     }
2617
2618     void setInternalMethodType(PropertySlot::InternalMethodType type)
2619     {
2620         ASSERT(hasInternalMethodType());
2621         m_opInfo2 = static_cast<uint32_t>(type);
2622     }
2623
2624     Node* replacement() const
2625     {
2626         return m_misc.replacement;
2627     }
2628     
2629     void setReplacement(Node* replacement)
2630     {
2631         m_misc.replacement = replacement;
2632     }
2633     
2634     Epoch epoch() const
2635     {
2636         return Epoch::fromUnsigned(m_misc.epoch);
2637     }
2638     
2639     void setEpoch(Epoch epoch)
2640     {
2641         m_misc.epoch = epoch.toUnsigned();
2642     }
2643
2644     unsigned numberOfArgumentsToSkip()
2645     {
2646         ASSERT(op() == CreateRest || op() == PhantomCreateRest || op() == GetRestLength || op() == GetMyArgumentByVal || op() == GetMyArgumentByValOutOfBounds);
2647         return m_opInfo.as<unsigned>();
2648     }
2649
2650     bool hasArgumentIndex()
2651     {
2652         return op() == GetArgument;
2653     }
2654
2655     unsigned argumentIndex()
2656     {
2657         ASSERT(hasArgumentIndex());
2658         return m_opInfo.as<unsigned>();
2659     }
2660
2661     bool hasBucketOwnerType()
2662     {
2663         return op() == GetMapBucketNext || op() == LoadKeyFromMapBucket || op() == LoadValueFromMapBucket;
2664     }
2665
2666     BucketOwnerType bucketOwnerType()
2667     {
2668         ASSERT(hasBucketOwnerType());
2669         return m_opInfo.as<BucketOwnerType>();
2670     }
2671
2672     bool hasValidRadixConstant()
2673     {
2674         return op() == NumberToStringWithValidRadixConstant;
2675     }
2676
2677     int32_t validRadixConstant()
2678     {
2679         ASSERT(hasValidRadixConstant());
2680         return m_opInfo.as<int32_t>();
2681     }
2682
2683     bool hasIgnoreLastIndexIsWritable()
2684     {
2685         return op() == SetRegExpObjectLastIndex;
2686     }
2687
2688     bool ignoreLastIndexIsWritable()
2689     {
2690         ASSERT(hasIgnoreLastIndexIsWritable());
2691         return m_opInfo.as<uint32_t>();
2692     }
2693
2694     uint32_t errorType()
2695     {
2696         ASSERT(op() == ThrowStaticError);
2697         return m_opInfo.as<uint32_t>();
2698     }
2699
2700     void dumpChildren(PrintStream& out)
2701     {
2702         if (!child1())
2703             return;
2704         out.printf("@%u", child1()->index());
2705         if (!child2())
2706             return;
2707         out.printf(", @%u", child2()->index());
2708         if (!child3())
2709             return;
2710         out.printf(", @%u", child3()->index());
2711     }
2712     
2713     // NB. This class must have a trivial destructor.
2714
2715     NodeOrigin origin;
2716
2717     // References to up to 3 children, or links to a variable length set of children.
2718     AdjacencyList children;
2719
2720 private:
2721     friend class B3::SparseCollection<Node>;
2722
2723     unsigned m_index { std::numeric_limits<unsigned>::max() };
2724     unsigned m_op : 10; // real type is NodeType
2725     unsigned m_flags : 20;
2726     // The virtual register number (spill location) associated with this .
2727     VirtualRegister m_virtualRegister;
2728     // The number of uses of the result of this operation (+1 for 'must generate' nodes, which have side-effects).
2729     unsigned m_refCount;
2730     // The prediction ascribed to this node after propagation.
2731     SpeculatedType m_prediction { SpecNone };
2732     // Immediate values, accesses type-checked via accessors above.
2733     struct OpInfoWrapper {
2734         OpInfoWrapper()
2735         {
2736             u.int64 = 0;
2737         }
2738         OpInfoWrapper(uint32_t intValue)
2739         {
2740             u.int64 = 0;
2741             u.int32 = intValue;
2742         }
2743         OpInfoWrapper(uint64_t intValue)
2744         {
2745             u.int64 = intValue;
2746         }
2747         OpInfoWrapper(void* pointer)
2748         {
2749             u.int64 = 0;
2750             u.pointer = pointer;
2751         }
2752         OpInfoWrapper(const void* constPointer)
2753         {
2754             u.int64 = 0;
2755             u.constPointer = constPointer;
2756         }
2757         OpInfoWrapper(RegisteredStructure structure)
2758         {
2759             u.int64 = 0;
2760             u.pointer = bitwise_cast<void*>(structure);
2761         }
2762         OpInfoWrapper& operator=(uint32_t int32)
2763         {
2764             u.int64 = 0;
2765             u.int32 = int32;
2766             return *this;
2767         }
2768         OpInfoWrapper& operator=(int32_t int32)
2769         {
2770             u.int64 = 0;
2771             u.int32 = int32;
2772             return *this;
2773         }
2774         OpInfoWrapper& operator=(uint64_t int64)
2775         {
2776             u.int64 = int64;
2777             return *this;
2778         }
2779         OpInfoWrapper& operator=(void* pointer)
2780         {
2781             u.int64 = 0;
2782             u.pointer = pointer;
2783             return *this;
2784         }
2785         OpInfoWrapper& operator=(const void* constPointer)
2786         {
2787             u.int64 = 0;
2788             u.constPointer = constPointer;
2789             return *this;
2790         }
2791         OpInfoWrapper& operator=(RegisteredStructure structure)
2792         {
2793             u.int64 = 0;
2794             u.pointer = bitwise_cast<void*>(structure);
2795             return *this;
2796         }
2797         OpInfoWrapper& operator=(NewArrayBufferData newArrayBufferData)
2798         {
2799             u.int64 = bitwise_cast<uint64_t>(newArrayBufferData);
2800             return *this;
2801         }
2802         template <typename T>
2803         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
2804         {
2805             return static_cast<T>(u.pointer);
2806         }
2807         template <typename T>
2808         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
2809         {
2810             return static_cast<T>(u.constPointer);
2811         }
2812         template <typename T>
2813         ALWAYS_INLINE auto as() const -> typename std::enable_if<(std::is_integral<T>::value || std::is_enum<T>::value) && sizeof(T) == 4, T>::type
2814         {
2815             return static_cast<T>(u.int32);
2816         }
2817         template <typename T>
2818         ALWAYS_INLINE auto as() const -> typename std::enable_if<(std::is_integral<T>::value || std::is_enum<T>::value) && sizeof(T) == 8, T>::type
2819         {
2820             return static_cast<T>(u.int64);
2821         }
2822         ALWAYS_INLINE RegisteredStructure asRegisteredStructure() const
2823         {
2824             return bitwise_cast<RegisteredStructure>(u.pointer);
2825         }
2826         ALWAYS_INLINE NewArrayBufferData asNewArrayBufferData() const
2827         {
2828             return bitwise_cast<NewArrayBufferData>(u.int64);
2829         }
2830
2831         union {
2832             uint32_t int32;
2833             uint64_t int64;
2834             void* pointer;
2835             const void* constPointer;
2836         } u;
2837     };
2838     OpInfoWrapper m_opInfo;
2839     OpInfoWrapper m_opInfo2;
2840
2841     // Miscellaneous data that is usually meaningless, but can hold some analysis results
2842     // if you ask right. For example, if you do Graph::initializeNodeOwners(), Node::owner
2843     // will tell you which basic block a node belongs to. You cannot rely on this persisting
2844     // across transformations unless you do the maintenance work yourself. Other phases use
2845     // Node::replacement, but they do so manually: first you do Graph::clearReplacements()
2846     // and then you set, and use, replacement's yourself. Same thing for epoch.
2847     //
2848     // Bottom line: don't use these fields unless you initialize them yourself, or by
2849     // calling some appropriate methods that initialize them the way you want. Otherwise,
2850     // these fields are meaningless.
2851 private:
2852     union {
2853         Node* replacement;
2854         unsigned epoch;
2855     } m_misc;
2856 public:
2857     BasicBlock* owner;
2858 };
2859
2860 // Uncomment this to log NodeSet operations.
2861 // typedef LoggingHashSet<Node::HashSetTemplateInstantiationString, Node*> NodeSet;
2862 typedef HashSet<Node*> NodeSet;
2863
2864 struct NodeComparator {
2865     template<typename NodePtrType>
2866     bool operator()(NodePtrType a, NodePtrType b) const
2867     {
2868         return a->index() < b->index();
2869     }
2870 };
2871
2872 template<typename T>
2873 CString nodeListDump(const T& nodeList)
2874 {
2875     return sortedListDump(nodeList, NodeComparator());
2876 }
2877
2878 template<typename T>
2879 CString nodeMapDump(const T& nodeMap, DumpContext* context = 0)
2880 {
2881     Vector<typename T::KeyType> keys;
2882     for (
2883         typename T::const_iterator iter = nodeMap.begin();
2884         iter != nodeMap.end(); ++iter)
2885         keys.append(iter->key);
2886     std::sort(keys.begin(), keys.end(), NodeComparator());
2887     StringPrintStream out;
2888     CommaPrinter comma;
2889     for(unsigned i = 0; i < keys.size(); ++i)
2890         out.print(comma, keys[i], "=>", inContext(nodeMap.get(keys[i]), context));
2891     return out.toCString();
2892 }
2893
2894 template<typename T>
2895 CString nodeValuePairListDump(const T& nodeValuePairList, DumpContext* context = 0)
2896 {
2897     using V = typename T::ValueType;
2898     T sortedList = nodeValuePairList;
2899     std::sort(sortedList.begin(), sortedList.end(), [](const V& a, const V& b) {
2900         return NodeComparator()(a.node, b.node);
2901     });
2902
2903     StringPrintStream out;
2904     CommaPrinter comma;
2905     for (const auto& pair : sortedList)
2906         out.print(comma, pair.node, "=>", inContext(pair.value, context));
2907     return out.toCString();
2908 }
2909
2910 } } // namespace JSC::DFG
2911
2912 namespace WTF {
2913
2914 void printInternal(PrintStream&, JSC::DFG::SwitchKind);
2915 void printInternal(PrintStream&, JSC::DFG::Node*);
2916
2917 inline JSC::DFG::Node* inContext(JSC::DFG::Node* node, JSC::DumpContext*) { return node; }
2918
2919 template<>
2920 struct LoggingHashKeyTraits<JSC::DFG::Node*> {
2921     static void print(PrintStream& out, JSC::DFG::Node* key)
2922     {
2923         out.print("bitwise_cast<::JSC::DFG::Node*>(", RawPointer(key), "lu)");
2924     }
2925 };
2926
2927 } // namespace WTF
2928
2929 using WTF::inContext;
2930
2931 #endif