bab1c353fce649213dddc5668958135941527908
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGNode.h
1 /*
2  * Copyright (C) 2011-2016 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 #ifndef DFGNode_h
27 #define DFGNode_h
28
29 #if ENABLE(DFG_JIT)
30
31 #include "BasicBlockLocation.h"
32 #include "CodeBlock.h"
33 #include "DFGAbstractValue.h"
34 #include "DFGAdjacencyList.h"
35 #include "DFGArithMode.h"
36 #include "DFGArrayMode.h"
37 #include "DFGCommon.h"
38 #include "DFGEpoch.h"
39 #include "DFGLazyJSValue.h"
40 #include "DFGMultiGetByOffsetData.h"
41 #include "DFGNodeFlags.h"
42 #include "DFGNodeOrigin.h"
43 #include "DFGNodeType.h"
44 #include "DFGObjectMaterializationData.h"
45 #include "DFGOpInfo.h"
46 #include "DFGTransition.h"
47 #include "DFGUseKind.h"
48 #include "DFGVariableAccessData.h"
49 #include "GetByIdVariant.h"
50 #include "JSCJSValue.h"
51 #include "Operands.h"
52 #include "PutByIdVariant.h"
53 #include "SpeculatedType.h"
54 #include "StructureSet.h"
55 #include "TypeLocation.h"
56 #include "ValueProfile.h"
57 #include <wtf/ListDump.h>
58
59 namespace JSC { namespace DFG {
60
61 class Graph;
62 class PromotedLocationDescriptor;
63 struct BasicBlock;
64
65 struct StorageAccessData {
66     PropertyOffset offset;
67     unsigned identifierNumber;
68
69     // This needs to know the inferred type. For puts, this is necessary because we need to remember
70     // what check is needed. For gets, this is necessary because otherwise AI might forget what type is
71     // guaranteed.
72     InferredType::Descriptor inferredType;
73 };
74
75 struct MultiPutByOffsetData {
76     unsigned identifierNumber;
77     Vector<PutByIdVariant, 2> variants;
78     
79     bool writesStructures() const;
80     bool reallocatesStorage() const;
81 };
82
83 struct NewArrayBufferData {
84     unsigned startConstant;
85     unsigned numConstants;
86     IndexingType indexingType;
87 };
88
89 struct BranchTarget {
90     BranchTarget()
91         : block(0)
92         , count(PNaN)
93     {
94     }
95     
96     explicit BranchTarget(BasicBlock* block)
97         : block(block)
98         , count(PNaN)
99     {
100     }
101     
102     void setBytecodeIndex(unsigned bytecodeIndex)
103     {
104         block = bitwise_cast<BasicBlock*>(static_cast<uintptr_t>(bytecodeIndex));
105     }
106     unsigned bytecodeIndex() const { return bitwise_cast<uintptr_t>(block); }
107     
108     void dump(PrintStream&) const;
109     
110     BasicBlock* block;
111     float count;
112 };
113
114 struct BranchData {
115     static BranchData withBytecodeIndices(
116         unsigned takenBytecodeIndex, unsigned notTakenBytecodeIndex)
117     {
118         BranchData result;
119         result.taken.block = bitwise_cast<BasicBlock*>(static_cast<uintptr_t>(takenBytecodeIndex));
120         result.notTaken.block = bitwise_cast<BasicBlock*>(static_cast<uintptr_t>(notTakenBytecodeIndex));
121         return result;
122     }
123     
124     unsigned takenBytecodeIndex() const { return taken.bytecodeIndex(); }
125     unsigned notTakenBytecodeIndex() const { return notTaken.bytecodeIndex(); }
126     
127     BasicBlock*& forCondition(bool condition)
128     {
129         if (condition)
130             return taken.block;
131         return notTaken.block;
132     }
133     
134     BranchTarget taken;
135     BranchTarget notTaken;
136 };
137
138 // The SwitchData and associated data structures duplicate the information in
139 // JumpTable. The DFG may ultimately end up using the JumpTable, though it may
140 // instead decide to do something different - this is entirely up to the DFG.
141 // These data structures give the DFG a higher-level semantic description of
142 // what is going on, which will allow it to make the right decision.
143 //
144 // Note that there will never be multiple SwitchCases in SwitchData::cases that
145 // have the same SwitchCase::value, since the bytecode's JumpTables never have
146 // duplicates - since the JumpTable maps a value to a target. It's a
147 // one-to-many mapping. So we may have duplicate targets, but never duplicate
148 // values.
149 struct SwitchCase {
150     SwitchCase()
151     {
152     }
153     
154     SwitchCase(LazyJSValue value, BasicBlock* target)
155         : value(value)
156         , target(target)
157     {
158     }
159     
160     static SwitchCase withBytecodeIndex(LazyJSValue value, unsigned bytecodeIndex)
161     {
162         SwitchCase result;
163         result.value = value;
164         result.target.setBytecodeIndex(bytecodeIndex);
165         return result;
166     }
167     
168     LazyJSValue value;
169     BranchTarget target;
170 };
171
172 struct SwitchData {
173     // Initializes most fields to obviously invalid values. Anyone
174     // constructing this should make sure to initialize everything they
175     // care about manually.
176     SwitchData()
177         : kind(static_cast<SwitchKind>(-1))
178         , switchTableIndex(UINT_MAX)
179         , didUseJumpTable(false)
180     {
181     }
182     
183     Vector<SwitchCase> cases;
184     BranchTarget fallThrough;
185     SwitchKind kind;
186     unsigned switchTableIndex;
187     bool didUseJumpTable;
188 };
189
190 struct CallVarargsData {
191     int firstVarArgOffset;
192 };
193
194 struct LoadVarargsData {
195     VirtualRegister start; // Local for the first element. This is the first actual argument, not this.
196     VirtualRegister count; // Local for the count.
197     VirtualRegister machineStart;
198     VirtualRegister machineCount;
199     unsigned offset; // Which array element to start with. Usually this is 0.
200     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".
201     unsigned limit; // Maximum number of elements to load. Includes "this".
202 };
203
204 struct StackAccessData {
205     StackAccessData()
206         : format(DeadFlush)
207     {
208     }
209     
210     StackAccessData(VirtualRegister local, FlushFormat format)
211         : local(local)
212         , format(format)
213     {
214     }
215     
216     VirtualRegister local;
217     VirtualRegister machineLocal;
218     FlushFormat format;
219     
220     FlushedAt flushedAt() { return FlushedAt(format, machineLocal); }
221 };
222
223 // === Node ===
224 //
225 // Node represents a single operation in the data flow graph.
226 struct Node {
227     enum VarArgTag { VarArg };
228     
229     Node() { }
230     
231     Node(NodeType op, NodeOrigin nodeOrigin, const AdjacencyList& children)
232         : origin(nodeOrigin)
233         , children(children)
234         , m_virtualRegister(VirtualRegister())
235         , m_refCount(1)
236         , m_prediction(SpecNone)
237         , owner(nullptr)
238     {
239         m_misc.replacement = nullptr;
240         setOpAndDefaultFlags(op);
241     }
242     
243     // Construct a node with up to 3 children, no immediate value.
244     Node(NodeType op, NodeOrigin nodeOrigin, Edge child1 = Edge(), Edge child2 = Edge(), Edge child3 = Edge())
245         : origin(nodeOrigin)
246         , children(AdjacencyList::Fixed, child1, child2, child3)
247         , m_virtualRegister(VirtualRegister())
248         , m_refCount(1)
249         , m_prediction(SpecNone)
250         , m_opInfo(0)
251         , m_opInfo2(0)
252         , owner(nullptr)
253     {
254         m_misc.replacement = nullptr;
255         setOpAndDefaultFlags(op);
256         ASSERT(!(m_flags & NodeHasVarArgs));
257     }
258
259     // Construct a node with up to 3 children, no immediate value.
260     Node(NodeFlags result, NodeType op, NodeOrigin nodeOrigin, Edge child1 = Edge(), Edge child2 = Edge(), Edge child3 = Edge())
261         : origin(nodeOrigin)
262         , children(AdjacencyList::Fixed, child1, child2, child3)
263         , m_virtualRegister(VirtualRegister())
264         , m_refCount(1)
265         , m_prediction(SpecNone)
266         , m_opInfo(0)
267         , m_opInfo2(0)
268         , owner(nullptr)
269     {
270         m_misc.replacement = nullptr;
271         setOpAndDefaultFlags(op);
272         setResult(result);
273         ASSERT(!(m_flags & NodeHasVarArgs));
274     }
275
276     // Construct a node with up to 3 children and an immediate value.
277     Node(NodeType op, NodeOrigin nodeOrigin, OpInfo imm, Edge child1 = Edge(), Edge child2 = Edge(), Edge child3 = Edge())
278         : origin(nodeOrigin)
279         , children(AdjacencyList::Fixed, child1, child2, child3)
280         , m_virtualRegister(VirtualRegister())
281         , m_refCount(1)
282         , m_prediction(SpecNone)
283         , m_opInfo(imm.m_value)
284         , m_opInfo2(0)
285         , owner(nullptr)
286     {
287         m_misc.replacement = nullptr;
288         setOpAndDefaultFlags(op);
289         ASSERT(!(m_flags & NodeHasVarArgs));
290     }
291
292     // Construct a node with up to 3 children and an immediate value.
293     Node(NodeFlags result, NodeType op, NodeOrigin nodeOrigin, OpInfo imm, Edge child1 = Edge(), Edge child2 = Edge(), Edge child3 = Edge())
294         : origin(nodeOrigin)
295         , children(AdjacencyList::Fixed, child1, child2, child3)
296         , m_virtualRegister(VirtualRegister())
297         , m_refCount(1)
298         , m_prediction(SpecNone)
299         , m_opInfo(imm.m_value)
300         , m_opInfo2(0)
301         , owner(nullptr)
302     {
303         m_misc.replacement = nullptr;
304         setOpAndDefaultFlags(op);
305         setResult(result);
306         ASSERT(!(m_flags & NodeHasVarArgs));
307     }
308
309     // Construct a node with up to 3 children and two immediate values.
310     Node(NodeType op, NodeOrigin nodeOrigin, OpInfo imm1, OpInfo imm2, Edge child1 = Edge(), Edge child2 = Edge(), Edge child3 = Edge())
311         : origin(nodeOrigin)
312         , children(AdjacencyList::Fixed, child1, child2, child3)
313         , m_virtualRegister(VirtualRegister())
314         , m_refCount(1)
315         , m_prediction(SpecNone)
316         , m_opInfo(imm1.m_value)
317         , m_opInfo2(imm2.m_value)
318         , owner(nullptr)
319     {
320         m_misc.replacement = nullptr;
321         setOpAndDefaultFlags(op);
322         ASSERT(!(m_flags & NodeHasVarArgs));
323     }
324     
325     // Construct a node with a variable number of children and two immediate values.
326     Node(VarArgTag, NodeType op, NodeOrigin nodeOrigin, OpInfo imm1, OpInfo imm2, unsigned firstChild, unsigned numChildren)
327         : origin(nodeOrigin)
328         , children(AdjacencyList::Variable, firstChild, numChildren)
329         , m_virtualRegister(VirtualRegister())
330         , m_refCount(1)
331         , m_prediction(SpecNone)
332         , m_opInfo(imm1.m_value)
333         , m_opInfo2(imm2.m_value)
334         , owner(nullptr)
335     {
336         m_misc.replacement = nullptr;
337         setOpAndDefaultFlags(op);
338         ASSERT(m_flags & NodeHasVarArgs);
339     }
340     
341     NodeType op() const { return static_cast<NodeType>(m_op); }
342     NodeFlags flags() const { return m_flags; }
343     
344     // This is not a fast method.
345     unsigned index() const;
346     
347     void setOp(NodeType op)
348     {
349         m_op = op;
350     }
351     
352     void setFlags(NodeFlags flags)
353     {
354         m_flags = flags;
355     }
356     
357     bool mergeFlags(NodeFlags flags)
358     {
359         NodeFlags newFlags = m_flags | flags;
360         if (newFlags == m_flags)
361             return false;
362         m_flags = newFlags;
363         return true;
364     }
365     
366     bool filterFlags(NodeFlags flags)
367     {
368         NodeFlags newFlags = m_flags & flags;
369         if (newFlags == m_flags)
370             return false;
371         m_flags = newFlags;
372         return true;
373     }
374     
375     bool clearFlags(NodeFlags flags)
376     {
377         return filterFlags(~flags);
378     }
379     
380     void setResult(NodeFlags result)
381     {
382         ASSERT(!(result & ~NodeResultMask));
383         clearFlags(NodeResultMask);
384         mergeFlags(result);
385     }
386     
387     NodeFlags result() const
388     {
389         return flags() & NodeResultMask;
390     }
391     
392     void setOpAndDefaultFlags(NodeType op)
393     {
394         m_op = op;
395         m_flags = defaultFlags(op);
396     }
397
398     void remove();
399
400     void convertToCheckStructure(StructureSet* set)
401     {
402         setOpAndDefaultFlags(CheckStructure);
403         m_opInfo = bitwise_cast<uintptr_t>(set); 
404     }
405
406     void convertToCheckStructureImmediate(Node* structure)
407     {
408         ASSERT(op() == CheckStructure);
409         m_op = CheckStructureImmediate;
410         children.setChild1(Edge(structure, CellUse));
411     }
412     
413     void replaceWith(Node* other)
414     {
415         remove();
416         setReplacement(other);
417     }
418
419     void convertToIdentity();
420     void convertToIdentityOn(Node*);
421
422     bool mustGenerate()
423     {
424         return m_flags & NodeMustGenerate;
425     }
426     
427     bool isConstant()
428     {
429         switch (op()) {
430         case JSConstant:
431         case DoubleConstant:
432         case Int52Constant:
433             return true;
434         default:
435             return false;
436         }
437     }
438     
439     bool hasConstant()
440     {
441         switch (op()) {
442         case JSConstant:
443         case DoubleConstant:
444         case Int52Constant:
445             return true;
446             
447         case PhantomDirectArguments:
448         case PhantomClonedArguments:
449             // These pretend to be the empty value constant for the benefit of the DFG backend, which
450             // otherwise wouldn't take kindly to a node that doesn't compute a value.
451             return true;
452             
453         default:
454             return false;
455         }
456     }
457
458     FrozenValue* constant()
459     {
460         ASSERT(hasConstant());
461         
462         if (op() == PhantomDirectArguments || op() == PhantomClonedArguments) {
463             // These pretend to be the empty value constant for the benefit of the DFG backend, which
464             // otherwise wouldn't take kindly to a node that doesn't compute a value.
465             return FrozenValue::emptySingleton();
466         }
467         
468         return bitwise_cast<FrozenValue*>(m_opInfo);
469     }
470     
471     // Don't call this directly - use Graph::convertToConstant() instead!
472     void convertToConstant(FrozenValue* value)
473     {
474         if (hasDoubleResult())
475             m_op = DoubleConstant;
476         else if (hasInt52Result())
477             m_op = Int52Constant;
478         else
479             m_op = JSConstant;
480         m_flags &= ~NodeMustGenerate;
481         m_opInfo = bitwise_cast<uintptr_t>(value);
482         children.reset();
483     }
484
485     void convertToLazyJSConstant(Graph&, LazyJSValue);
486     
487     void convertToConstantStoragePointer(void* pointer)
488     {
489         ASSERT(op() == GetIndexedPropertyStorage);
490         m_op = ConstantStoragePointer;
491         m_opInfo = bitwise_cast<uintptr_t>(pointer);
492         children.reset();
493     }
494     
495     void convertToGetLocalUnlinked(VirtualRegister local)
496     {
497         m_op = GetLocalUnlinked;
498         m_flags &= ~NodeMustGenerate;
499         m_opInfo = local.offset();
500         m_opInfo2 = VirtualRegister().offset();
501         children.reset();
502     }
503     
504     void convertToPutStack(StackAccessData* data)
505     {
506         m_op = PutStack;
507         m_flags |= NodeMustGenerate;
508         m_opInfo = bitwise_cast<uintptr_t>(data);
509         m_opInfo2 = 0;
510     }
511     
512     void convertToGetStack(StackAccessData* data)
513     {
514         m_op = GetStack;
515         m_flags &= ~NodeMustGenerate;
516         m_opInfo = bitwise_cast<uintptr_t>(data);
517         m_opInfo2 = 0;
518         children.reset();
519     }
520     
521     void convertToGetByOffset(StorageAccessData& data, Edge storage)
522     {
523         ASSERT(m_op == GetById || m_op == GetByIdFlush || m_op == MultiGetByOffset);
524         m_opInfo = bitwise_cast<uintptr_t>(&data);
525         children.setChild2(children.child1());
526         children.child2().setUseKind(KnownCellUse);
527         children.setChild1(storage);
528         m_op = GetByOffset;
529         m_flags &= ~NodeMustGenerate;
530     }
531     
532     void convertToMultiGetByOffset(MultiGetByOffsetData* data)
533     {
534         ASSERT(m_op == GetById || m_op == GetByIdFlush);
535         m_opInfo = bitwise_cast<intptr_t>(data);
536         child1().setUseKind(CellUse);
537         m_op = MultiGetByOffset;
538         ASSERT(m_flags & NodeMustGenerate);
539     }
540     
541     void convertToPutByOffset(StorageAccessData& data, Edge storage)
542     {
543         ASSERT(m_op == PutById || m_op == PutByIdDirect || m_op == PutByIdFlush || m_op == MultiPutByOffset);
544         m_opInfo = bitwise_cast<uintptr_t>(&data);
545         children.setChild3(children.child2());
546         children.setChild2(children.child1());
547         children.setChild1(storage);
548         m_op = PutByOffset;
549     }
550     
551     void convertToMultiPutByOffset(MultiPutByOffsetData* data)
552     {
553         ASSERT(m_op == PutById || m_op == PutByIdDirect || m_op == PutByIdFlush);
554         m_opInfo = bitwise_cast<intptr_t>(data);
555         m_op = MultiPutByOffset;
556     }
557     
558     void convertToPutHint(const PromotedLocationDescriptor&, Node* base, Node* value);
559     
560     void convertToPutByOffsetHint();
561     void convertToPutStructureHint(Node* structure);
562     void convertToPutClosureVarHint();
563     
564     void convertToPhantomNewObject()
565     {
566         ASSERT(m_op == NewObject || m_op == MaterializeNewObject);
567         m_op = PhantomNewObject;
568         m_flags &= ~NodeHasVarArgs;
569         m_flags |= NodeMustGenerate;
570         m_opInfo = 0;
571         m_opInfo2 = 0;
572         children = AdjacencyList();
573     }
574
575     void convertToPhantomNewFunction()
576     {
577         ASSERT(m_op == NewFunction || m_op == NewGeneratorFunction);
578         m_op = PhantomNewFunction;
579         m_flags |= NodeMustGenerate;
580         m_opInfo = 0;
581         m_opInfo2 = 0;
582         children = AdjacencyList();
583     }
584
585     void convertToPhantomNewGeneratorFunction()
586     {
587         ASSERT(m_op == NewGeneratorFunction);
588         m_op = PhantomNewGeneratorFunction;
589         m_flags |= NodeMustGenerate;
590         m_opInfo = 0;
591         m_opInfo2 = 0;
592         children = AdjacencyList();
593     }
594
595     void convertToPhantomCreateActivation()
596     {
597         ASSERT(m_op == CreateActivation || m_op == MaterializeCreateActivation);
598         m_op = PhantomCreateActivation;
599         m_flags &= ~NodeHasVarArgs;
600         m_flags |= NodeMustGenerate;
601         m_opInfo = 0;
602         m_opInfo2 = 0;
603         children = AdjacencyList();
604     }
605
606     void convertPhantomToPhantomLocal()
607     {
608         ASSERT(m_op == Phantom && (child1()->op() == Phi || child1()->op() == SetLocal || child1()->op() == SetArgument));
609         m_op = PhantomLocal;
610         m_opInfo = child1()->m_opInfo; // Copy the variableAccessData.
611         children.setChild1(Edge());
612     }
613     
614     void convertFlushToPhantomLocal()
615     {
616         ASSERT(m_op == Flush);
617         m_op = PhantomLocal;
618         children = AdjacencyList();
619     }
620     
621     void convertToGetLocal(VariableAccessData* variable, Node* phi)
622     {
623         ASSERT(m_op == GetLocalUnlinked);
624         m_op = GetLocal;
625         m_opInfo = bitwise_cast<uintptr_t>(variable);
626         m_opInfo2 = 0;
627         children.setChild1(Edge(phi));
628     }
629     
630     void convertToToString()
631     {
632         ASSERT(m_op == ToPrimitive);
633         m_op = ToString;
634     }
635
636     void convertToArithSqrt()
637     {
638         ASSERT(m_op == ArithPow);
639         child2() = Edge();
640         m_op = ArithSqrt;
641     }
642
643     void convertToArithNegate()
644     {
645         ASSERT(m_op == ArithAbs && child1().useKind() == Int32Use);
646         m_op = ArithNegate;
647     }
648     
649     JSValue asJSValue()
650     {
651         return constant()->value();
652     }
653      
654     bool isInt32Constant()
655     {
656         return isConstant() && constant()->value().isInt32();
657     }
658      
659     int32_t asInt32()
660     {
661         return asJSValue().asInt32();
662     }
663      
664     uint32_t asUInt32()
665     {
666         return asInt32();
667     }
668      
669     bool isDoubleConstant()
670     {
671         return isConstant() && constant()->value().isDouble();
672     }
673      
674     bool isNumberConstant()
675     {
676         return isConstant() && constant()->value().isNumber();
677     }
678     
679     double asNumber()
680     {
681         return asJSValue().asNumber();
682     }
683      
684     bool isMachineIntConstant()
685     {
686         return isConstant() && constant()->value().isMachineInt();
687     }
688      
689     int64_t asMachineInt()
690     {
691         return asJSValue().asMachineInt();
692     }
693      
694     bool isBooleanConstant()
695     {
696         return isConstant() && constant()->value().isBoolean();
697     }
698      
699     bool asBoolean()
700     {
701         return constant()->value().asBoolean();
702     }
703
704     bool isUndefinedOrNullConstant()
705     {
706         return isConstant() && constant()->value().isUndefinedOrNull();
707     }
708
709     bool isCellConstant()
710     {
711         return isConstant() && constant()->value() && constant()->value().isCell();
712     }
713      
714     JSCell* asCell()
715     {
716         return constant()->value().asCell();
717     }
718      
719     template<typename T>
720     T dynamicCastConstant()
721     {
722         if (!isCellConstant())
723             return nullptr;
724         return jsDynamicCast<T>(asCell());
725     }
726     
727     template<typename T>
728     T castConstant()
729     {
730         T result = dynamicCastConstant<T>();
731         RELEASE_ASSERT(result);
732         return result;
733     }
734
735     bool hasLazyJSValue()
736     {
737         return op() == LazyJSConstant;
738     }
739
740     LazyJSValue lazyJSValue()
741     {
742         ASSERT(hasLazyJSValue());
743         return *bitwise_cast<LazyJSValue*>(m_opInfo);
744     }
745
746     String tryGetString(Graph&);
747
748     JSValue initializationValueForActivation() const
749     {
750         ASSERT(op() == CreateActivation);
751         return bitwise_cast<FrozenValue*>(m_opInfo2)->value();
752     }
753      
754     bool containsMovHint()
755     {
756         switch (op()) {
757         case MovHint:
758         case ZombieHint:
759             return true;
760         default:
761             return false;
762         }
763     }
764     
765     bool hasVariableAccessData(Graph&);
766     bool hasLocal(Graph& graph)
767     {
768         return hasVariableAccessData(graph);
769     }
770     
771     // This is useful for debugging code, where a node that should have a variable
772     // access data doesn't have one because it hasn't been initialized yet.
773     VariableAccessData* tryGetVariableAccessData()
774     {
775         VariableAccessData* result = reinterpret_cast<VariableAccessData*>(m_opInfo);
776         if (!result)
777             return 0;
778         return result->find();
779     }
780     
781     VariableAccessData* variableAccessData()
782     {
783         return reinterpret_cast<VariableAccessData*>(m_opInfo)->find();
784     }
785     
786     VirtualRegister local()
787     {
788         return variableAccessData()->local();
789     }
790     
791     VirtualRegister machineLocal()
792     {
793         return variableAccessData()->machineLocal();
794     }
795     
796     bool hasUnlinkedLocal()
797     {
798         switch (op()) {
799         case GetLocalUnlinked:
800         case ExtractOSREntryLocal:
801         case MovHint:
802         case ZombieHint:
803         case KillStack:
804             return true;
805         default:
806             return false;
807         }
808     }
809     
810     VirtualRegister unlinkedLocal()
811     {
812         ASSERT(hasUnlinkedLocal());
813         return static_cast<VirtualRegister>(m_opInfo);
814     }
815     
816     bool hasUnlinkedMachineLocal()
817     {
818         return op() == GetLocalUnlinked;
819     }
820     
821     void setUnlinkedMachineLocal(VirtualRegister reg)
822     {
823         ASSERT(hasUnlinkedMachineLocal());
824         m_opInfo2 = reg.offset();
825     }
826     
827     VirtualRegister unlinkedMachineLocal()
828     {
829         ASSERT(hasUnlinkedMachineLocal());
830         return VirtualRegister(m_opInfo2);
831     }
832     
833     bool hasStackAccessData()
834     {
835         switch (op()) {
836         case PutStack:
837         case GetStack:
838             return true;
839         default:
840             return false;
841         }
842     }
843     
844     StackAccessData* stackAccessData()
845     {
846         ASSERT(hasStackAccessData());
847         return bitwise_cast<StackAccessData*>(m_opInfo);
848     }
849     
850     bool hasPhi()
851     {
852         return op() == Upsilon;
853     }
854     
855     Node* phi()
856     {
857         ASSERT(hasPhi());
858         return bitwise_cast<Node*>(m_opInfo);
859     }
860
861     bool isStoreBarrier()
862     {
863         return op() == StoreBarrier;
864     }
865
866     bool hasIdentifier()
867     {
868         switch (op()) {
869         case TryGetById:
870         case GetById:
871         case GetByIdFlush:
872         case PutById:
873         case PutByIdFlush:
874         case PutByIdDirect:
875         case PutGetterById:
876         case PutSetterById:
877         case PutGetterSetterById:
878         case DeleteById:
879         case GetDynamicVar:
880         case PutDynamicVar:
881         case ResolveScope:
882             return true;
883         default:
884             return false;
885         }
886     }
887
888     unsigned identifierNumber()
889     {
890         ASSERT(hasIdentifier());
891         return m_opInfo;
892     }
893
894     bool hasGetPutInfo()
895     {
896         switch (op()) {
897         case GetDynamicVar:
898         case PutDynamicVar:
899             return true;
900         default:
901             return false;
902         }
903     }
904
905     unsigned getPutInfo()
906     {
907         ASSERT(hasGetPutInfo());
908         return m_opInfo2;
909     }
910
911     bool hasAccessorAttributes()
912     {
913         switch (op()) {
914         case PutGetterById:
915         case PutSetterById:
916         case PutGetterSetterById:
917         case PutGetterByVal:
918         case PutSetterByVal:
919             return true;
920         default:
921             return false;
922         }
923     }
924
925     int32_t accessorAttributes()
926     {
927         ASSERT(hasAccessorAttributes());
928         switch (op()) {
929         case PutGetterById:
930         case PutSetterById:
931         case PutGetterSetterById:
932             return m_opInfo2;
933         case PutGetterByVal:
934         case PutSetterByVal:
935             return m_opInfo;
936         default:
937             RELEASE_ASSERT_NOT_REACHED();
938             return 0;
939         }
940     }
941     
942     bool hasPromotedLocationDescriptor()
943     {
944         return op() == PutHint;
945     }
946     
947     PromotedLocationDescriptor promotedLocationDescriptor();
948     
949     // This corrects the arithmetic node flags, so that irrelevant bits are
950     // ignored. In particular, anything other than ArithMul does not need
951     // to know if it can speculate on negative zero.
952     NodeFlags arithNodeFlags()
953     {
954         NodeFlags result = m_flags & NodeArithFlagsMask;
955         if (op() == ArithMul || op() == ArithDiv || op() == ArithMod || op() == ArithNegate || op() == ArithPow || op() == ArithRound || op() == ArithFloor || op() == ArithCeil || op() == ArithTrunc || op() == DoubleAsInt32)
956             return result;
957         return result & ~NodeBytecodeNeedsNegZero;
958     }
959
960     bool mayHaveNonIntResult()
961     {
962         return m_flags & NodeMayHaveNonIntResult;
963     }
964
965     bool hasConstantBuffer()
966     {
967         return op() == NewArrayBuffer;
968     }
969     
970     NewArrayBufferData* newArrayBufferData()
971     {
972         ASSERT(hasConstantBuffer());
973         return reinterpret_cast<NewArrayBufferData*>(m_opInfo);
974     }
975     
976     unsigned startConstant()
977     {
978         return newArrayBufferData()->startConstant;
979     }
980     
981     unsigned numConstants()
982     {
983         return newArrayBufferData()->numConstants;
984     }
985     
986     bool hasIndexingType()
987     {
988         switch (op()) {
989         case NewArray:
990         case NewArrayWithSize:
991         case NewArrayBuffer:
992             return true;
993         default:
994             return false;
995         }
996     }
997
998     // Return the indexing type that an array allocation *wants* to use. It may end up using a different
999     // type if we're having a bad time. You can determine the actual indexing type by asking the global
1000     // object:
1001     //
1002     //     m_graph.globalObjectFor(node->origin.semantic)->arrayStructureForIndexingTypeDuringAllocation(node->indexingType())
1003     //
1004     // This will give you a Structure*, and that will have some indexing type that may be different from
1005     // the this one.
1006     IndexingType indexingType()
1007     {
1008         ASSERT(hasIndexingType());
1009         if (op() == NewArrayBuffer)
1010             return newArrayBufferData()->indexingType;
1011         return m_opInfo;
1012     }
1013     
1014     bool hasTypedArrayType()
1015     {
1016         switch (op()) {
1017         case NewTypedArray:
1018             return true;
1019         default:
1020             return false;
1021         }
1022     }
1023     
1024     TypedArrayType typedArrayType()
1025     {
1026         ASSERT(hasTypedArrayType());
1027         TypedArrayType result = static_cast<TypedArrayType>(m_opInfo);
1028         ASSERT(isTypedView(result));
1029         return result;
1030     }
1031     
1032     bool hasInlineCapacity()
1033     {
1034         return op() == CreateThis;
1035     }
1036
1037     unsigned inlineCapacity()
1038     {
1039         ASSERT(hasInlineCapacity());
1040         return m_opInfo;
1041     }
1042
1043     void setIndexingType(IndexingType indexingType)
1044     {
1045         ASSERT(hasIndexingType());
1046         m_opInfo = indexingType;
1047     }
1048     
1049     // FIXME: We really should be able to inline code that uses NewRegexp. That means
1050     // using something other than the index into the CodeBlock here.
1051     // https://bugs.webkit.org/show_bug.cgi?id=154808
1052     bool hasRegexpIndex()
1053     {
1054         return op() == NewRegexp;
1055     }
1056     
1057     unsigned regexpIndex()
1058     {
1059         ASSERT(hasRegexpIndex());
1060         return m_opInfo;
1061     }
1062     
1063     bool hasScopeOffset()
1064     {
1065         return op() == GetClosureVar || op() == PutClosureVar;
1066     }
1067
1068     ScopeOffset scopeOffset()
1069     {
1070         ASSERT(hasScopeOffset());
1071         return ScopeOffset(m_opInfo);
1072     }
1073     
1074     bool hasDirectArgumentsOffset()
1075     {
1076         return op() == GetFromArguments || op() == PutToArguments;
1077     }
1078     
1079     DirectArgumentsOffset capturedArgumentsOffset()
1080     {
1081         ASSERT(hasDirectArgumentsOffset());
1082         return DirectArgumentsOffset(m_opInfo);
1083     }
1084     
1085     bool hasRegisterPointer()
1086     {
1087         return op() == GetGlobalVar || op() == GetGlobalLexicalVariable || op() == PutGlobalVariable;
1088     }
1089     
1090     WriteBarrier<Unknown>* variablePointer()
1091     {
1092         return bitwise_cast<WriteBarrier<Unknown>*>(m_opInfo);
1093     }
1094     
1095     bool hasCallVarargsData()
1096     {
1097         switch (op()) {
1098         case CallVarargs:
1099         case CallForwardVarargs:
1100         case TailCallVarargs:
1101         case TailCallForwardVarargs:
1102         case TailCallVarargsInlinedCaller:
1103         case TailCallForwardVarargsInlinedCaller:
1104         case ConstructVarargs:
1105         case ConstructForwardVarargs:
1106             return true;
1107         default:
1108             return false;
1109         }
1110     }
1111     
1112     CallVarargsData* callVarargsData()
1113     {
1114         ASSERT(hasCallVarargsData());
1115         return bitwise_cast<CallVarargsData*>(m_opInfo);
1116     }
1117     
1118     bool hasLoadVarargsData()
1119     {
1120         return op() == LoadVarargs || op() == ForwardVarargs;
1121     }
1122     
1123     LoadVarargsData* loadVarargsData()
1124     {
1125         ASSERT(hasLoadVarargsData());
1126         return bitwise_cast<LoadVarargsData*>(m_opInfo);
1127     }
1128     
1129     bool hasResult()
1130     {
1131         return !!result();
1132     }
1133
1134     bool hasInt32Result()
1135     {
1136         return result() == NodeResultInt32;
1137     }
1138     
1139     bool hasInt52Result()
1140     {
1141         return result() == NodeResultInt52;
1142     }
1143     
1144     bool hasNumberResult()
1145     {
1146         return result() == NodeResultNumber;
1147     }
1148     
1149     bool hasDoubleResult()
1150     {
1151         return result() == NodeResultDouble;
1152     }
1153     
1154     bool hasJSResult()
1155     {
1156         return result() == NodeResultJS;
1157     }
1158     
1159     bool hasBooleanResult()
1160     {
1161         return result() == NodeResultBoolean;
1162     }
1163
1164     bool hasStorageResult()
1165     {
1166         return result() == NodeResultStorage;
1167     }
1168     
1169     UseKind defaultUseKind()
1170     {
1171         return useKindForResult(result());
1172     }
1173     
1174     Edge defaultEdge()
1175     {
1176         return Edge(this, defaultUseKind());
1177     }
1178
1179     bool isJump()
1180     {
1181         return op() == Jump;
1182     }
1183
1184     bool isBranch()
1185     {
1186         return op() == Branch;
1187     }
1188     
1189     bool isSwitch()
1190     {
1191         return op() == Switch;
1192     }
1193
1194     bool isTerminal()
1195     {
1196         switch (op()) {
1197         case Jump:
1198         case Branch:
1199         case Switch:
1200         case Return:
1201         case TailCall:
1202         case TailCallVarargs:
1203         case TailCallForwardVarargs:
1204         case Unreachable:
1205             return true;
1206         default:
1207             return false;
1208         }
1209     }
1210
1211     bool isFunctionTerminal()
1212     {
1213         if (isTerminal() && !numSuccessors())
1214             return true;
1215
1216         return false;
1217     }
1218
1219     unsigned targetBytecodeOffsetDuringParsing()
1220     {
1221         ASSERT(isJump());
1222         return m_opInfo;
1223     }
1224
1225     BasicBlock*& targetBlock()
1226     {
1227         ASSERT(isJump());
1228         return *bitwise_cast<BasicBlock**>(&m_opInfo);
1229     }
1230     
1231     BranchData* branchData()
1232     {
1233         ASSERT(isBranch());
1234         return bitwise_cast<BranchData*>(m_opInfo);
1235     }
1236     
1237     SwitchData* switchData()
1238     {
1239         ASSERT(isSwitch());
1240         return bitwise_cast<SwitchData*>(m_opInfo);
1241     }
1242     
1243     unsigned numSuccessors()
1244     {
1245         switch (op()) {
1246         case Jump:
1247             return 1;
1248         case Branch:
1249             return 2;
1250         case Switch:
1251             return switchData()->cases.size() + 1;
1252         default:
1253             return 0;
1254         }
1255     }
1256     
1257     BasicBlock*& successor(unsigned index)
1258     {
1259         if (isSwitch()) {
1260             if (index < switchData()->cases.size())
1261                 return switchData()->cases[index].target.block;
1262             RELEASE_ASSERT(index == switchData()->cases.size());
1263             return switchData()->fallThrough.block;
1264         }
1265         switch (index) {
1266         case 0:
1267             if (isJump())
1268                 return targetBlock();
1269             return branchData()->taken.block;
1270         case 1:
1271             return branchData()->notTaken.block;
1272         default:
1273             RELEASE_ASSERT_NOT_REACHED();
1274             return targetBlock();
1275         }
1276     }
1277     
1278     class SuccessorsIterable {
1279     public:
1280         SuccessorsIterable()
1281             : m_terminal(nullptr)
1282         {
1283         }
1284         
1285         SuccessorsIterable(Node* terminal)
1286             : m_terminal(terminal)
1287         {
1288         }
1289         
1290         class iterator {
1291         public:
1292             iterator()
1293                 : m_terminal(nullptr)
1294                 , m_index(UINT_MAX)
1295             {
1296             }
1297             
1298             iterator(Node* terminal, unsigned index)
1299                 : m_terminal(terminal)
1300                 , m_index(index)
1301             {
1302             }
1303             
1304             BasicBlock* operator*()
1305             {
1306                 return m_terminal->successor(m_index);
1307             }
1308             
1309             iterator& operator++()
1310             {
1311                 m_index++;
1312                 return *this;
1313             }
1314             
1315             bool operator==(const iterator& other) const
1316             {
1317                 return m_index == other.m_index;
1318             }
1319             
1320             bool operator!=(const iterator& other) const
1321             {
1322                 return !(*this == other);
1323             }
1324         private:
1325             Node* m_terminal;
1326             unsigned m_index;
1327         };
1328         
1329         iterator begin()
1330         {
1331             return iterator(m_terminal, 0);
1332         }
1333         
1334         iterator end()
1335         {
1336             return iterator(m_terminal, m_terminal->numSuccessors());
1337         }
1338
1339         size_t size() const { return m_terminal->numSuccessors(); }
1340         BasicBlock* at(size_t index) const { return m_terminal->successor(index); }
1341         BasicBlock* operator[](size_t index) const { return at(index); }
1342         
1343     private:
1344         Node* m_terminal;
1345     };
1346     
1347     SuccessorsIterable successors()
1348     {
1349         return SuccessorsIterable(this);
1350     }
1351     
1352     BasicBlock*& successorForCondition(bool condition)
1353     {
1354         return branchData()->forCondition(condition);
1355     }
1356     
1357     bool hasHeapPrediction()
1358     {
1359         switch (op()) {
1360         case ArithRound:
1361         case ArithFloor:
1362         case ArithCeil:
1363         case ArithTrunc:
1364         case GetDirectPname:
1365         case GetById:
1366         case GetByIdFlush:
1367         case GetByVal:
1368         case Call:
1369         case TailCallInlinedCaller:
1370         case Construct:
1371         case CallVarargs:
1372         case TailCallVarargsInlinedCaller:
1373         case ConstructVarargs:
1374         case CallForwardVarargs:
1375         case TailCallForwardVarargsInlinedCaller:
1376         case GetByOffset:
1377         case MultiGetByOffset:
1378         case GetClosureVar:
1379         case GetFromArguments:
1380         case ArrayPop:
1381         case ArrayPush:
1382         case RegExpExec:
1383         case RegExpTest:
1384         case GetGlobalVar:
1385         case GetGlobalLexicalVariable:
1386         case StringReplace:
1387             return true;
1388         default:
1389             return false;
1390         }
1391     }
1392     
1393     SpeculatedType getHeapPrediction()
1394     {
1395         ASSERT(hasHeapPrediction());
1396         return static_cast<SpeculatedType>(m_opInfo2);
1397     }
1398
1399     void setHeapPrediction(SpeculatedType prediction)
1400     {
1401         ASSERT(hasHeapPrediction());
1402         m_opInfo2 = prediction;
1403     }
1404     
1405     bool hasCellOperand()
1406     {
1407         switch (op()) {
1408         case CheckCell:
1409         case OverridesHasInstance:
1410         case NewFunction:
1411         case NewGeneratorFunction:
1412         case CreateActivation:
1413         case MaterializeCreateActivation:
1414             return true;
1415         default:
1416             return false;
1417         }
1418     }
1419
1420     FrozenValue* cellOperand()
1421     {
1422         ASSERT(hasCellOperand());
1423         return reinterpret_cast<FrozenValue*>(m_opInfo);
1424     }
1425     
1426     template<typename T>
1427     T castOperand()
1428     {
1429         return cellOperand()->cast<T>();
1430     }
1431     
1432     void setCellOperand(FrozenValue* value)
1433     {
1434         ASSERT(hasCellOperand());
1435         m_opInfo = bitwise_cast<uintptr_t>(value);
1436     }
1437     
1438     bool hasWatchpointSet()
1439     {
1440         return op() == NotifyWrite;
1441     }
1442     
1443     WatchpointSet* watchpointSet()
1444     {
1445         ASSERT(hasWatchpointSet());
1446         return reinterpret_cast<WatchpointSet*>(m_opInfo);
1447     }
1448     
1449     bool hasStoragePointer()
1450     {
1451         return op() == ConstantStoragePointer;
1452     }
1453     
1454     void* storagePointer()
1455     {
1456         ASSERT(hasStoragePointer());
1457         return reinterpret_cast<void*>(m_opInfo);
1458     }
1459
1460     bool hasUidOperand()
1461     {
1462         return op() == CheckIdent;
1463     }
1464
1465     UniquedStringImpl* uidOperand()
1466     {
1467         ASSERT(hasUidOperand());
1468         return reinterpret_cast<UniquedStringImpl*>(m_opInfo);
1469     }
1470
1471     bool hasTypeInfoOperand()
1472     {
1473         return op() == CheckTypeInfoFlags;
1474     }
1475
1476     unsigned typeInfoOperand()
1477     {
1478         ASSERT(hasTypeInfoOperand() && m_opInfo <= UCHAR_MAX);
1479         return static_cast<unsigned>(m_opInfo);
1480     }
1481
1482     bool hasTransition()
1483     {
1484         switch (op()) {
1485         case PutStructure:
1486         case AllocatePropertyStorage:
1487         case ReallocatePropertyStorage:
1488             return true;
1489         default:
1490             return false;
1491         }
1492     }
1493     
1494     Transition* transition()
1495     {
1496         ASSERT(hasTransition());
1497         return reinterpret_cast<Transition*>(m_opInfo);
1498     }
1499     
1500     bool hasStructureSet()
1501     {
1502         switch (op()) {
1503         case CheckStructure:
1504         case CheckStructureImmediate:
1505         case MaterializeNewObject:
1506             return true;
1507         default:
1508             return false;
1509         }
1510     }
1511     
1512     StructureSet& structureSet()
1513     {
1514         ASSERT(hasStructureSet());
1515         return *reinterpret_cast<StructureSet*>(m_opInfo);
1516     }
1517     
1518     bool hasStructure()
1519     {
1520         switch (op()) {
1521         case ArrayifyToStructure:
1522         case NewObject:
1523         case NewStringObject:
1524             return true;
1525         default:
1526             return false;
1527         }
1528     }
1529     
1530     Structure* structure()
1531     {
1532         ASSERT(hasStructure());
1533         return reinterpret_cast<Structure*>(m_opInfo);
1534     }
1535     
1536     bool hasStorageAccessData()
1537     {
1538         switch (op()) {
1539         case GetByOffset:
1540         case PutByOffset:
1541         case GetGetterSetterByOffset:
1542             return true;
1543         default:
1544             return false;
1545         }
1546     }
1547     
1548     StorageAccessData& storageAccessData()
1549     {
1550         ASSERT(hasStorageAccessData());
1551         return *bitwise_cast<StorageAccessData*>(m_opInfo);
1552     }
1553     
1554     bool hasMultiGetByOffsetData()
1555     {
1556         return op() == MultiGetByOffset;
1557     }
1558     
1559     MultiGetByOffsetData& multiGetByOffsetData()
1560     {
1561         ASSERT(hasMultiGetByOffsetData());
1562         return *reinterpret_cast<MultiGetByOffsetData*>(m_opInfo);
1563     }
1564     
1565     bool hasMultiPutByOffsetData()
1566     {
1567         return op() == MultiPutByOffset;
1568     }
1569     
1570     MultiPutByOffsetData& multiPutByOffsetData()
1571     {
1572         ASSERT(hasMultiPutByOffsetData());
1573         return *reinterpret_cast<MultiPutByOffsetData*>(m_opInfo);
1574     }
1575     
1576     bool hasObjectMaterializationData()
1577     {
1578         switch (op()) {
1579         case MaterializeNewObject:
1580         case MaterializeCreateActivation:
1581             return true;
1582
1583         default:
1584             return false;
1585         }
1586     }
1587     
1588     ObjectMaterializationData& objectMaterializationData()
1589     {
1590         ASSERT(hasObjectMaterializationData());
1591         return *reinterpret_cast<ObjectMaterializationData*>(m_opInfo2);
1592     }
1593
1594     bool isObjectAllocation()
1595     {
1596         switch (op()) {
1597         case NewObject:
1598         case MaterializeNewObject:
1599             return true;
1600         default:
1601             return false;
1602         }
1603     }
1604     
1605     bool isPhantomObjectAllocation()
1606     {
1607         switch (op()) {
1608         case PhantomNewObject:
1609             return true;
1610         default:
1611             return false;
1612         }
1613     }
1614     
1615     bool isActivationAllocation()
1616     {
1617         switch (op()) {
1618         case CreateActivation:
1619         case MaterializeCreateActivation:
1620             return true;
1621         default:
1622             return false;
1623         }
1624     }
1625
1626     bool isPhantomActivationAllocation()
1627     {
1628         switch (op()) {
1629         case PhantomCreateActivation:
1630             return true;
1631         default:
1632             return false;
1633         }
1634     }
1635
1636     bool isFunctionAllocation()
1637     {
1638         switch (op()) {
1639         case NewFunction:
1640         case NewGeneratorFunction:
1641             return true;
1642         default:
1643             return false;
1644         }
1645     }
1646
1647     bool isPhantomFunctionAllocation()
1648     {
1649         switch (op()) {
1650         case PhantomNewFunction:
1651         case PhantomNewGeneratorFunction:
1652             return true;
1653         default:
1654             return false;
1655         }
1656     }
1657
1658     bool isPhantomAllocation()
1659     {
1660         switch (op()) {
1661         case PhantomNewObject:
1662         case PhantomDirectArguments:
1663         case PhantomClonedArguments:
1664         case PhantomNewFunction:
1665         case PhantomNewGeneratorFunction:
1666         case PhantomCreateActivation:
1667             return true;
1668         default:
1669             return false;
1670         }
1671     }
1672     
1673     bool hasArrayMode()
1674     {
1675         switch (op()) {
1676         case GetIndexedPropertyStorage:
1677         case GetArrayLength:
1678         case PutByValDirect:
1679         case PutByVal:
1680         case PutByValAlias:
1681         case GetByVal:
1682         case StringCharAt:
1683         case StringCharCodeAt:
1684         case CheckArray:
1685         case Arrayify:
1686         case ArrayifyToStructure:
1687         case ArrayPush:
1688         case ArrayPop:
1689         case HasIndexedProperty:
1690             return true;
1691         default:
1692             return false;
1693         }
1694     }
1695     
1696     ArrayMode arrayMode()
1697     {
1698         ASSERT(hasArrayMode());
1699         if (op() == ArrayifyToStructure)
1700             return ArrayMode::fromWord(m_opInfo2);
1701         return ArrayMode::fromWord(m_opInfo);
1702     }
1703     
1704     bool setArrayMode(ArrayMode arrayMode)
1705     {
1706         ASSERT(hasArrayMode());
1707         if (this->arrayMode() == arrayMode)
1708             return false;
1709         m_opInfo = arrayMode.asWord();
1710         return true;
1711     }
1712     
1713     bool hasArithMode()
1714     {
1715         switch (op()) {
1716         case ArithAbs:
1717         case ArithAdd:
1718         case ArithSub:
1719         case ArithNegate:
1720         case ArithMul:
1721         case ArithDiv:
1722         case ArithMod:
1723         case UInt32ToNumber:
1724         case DoubleAsInt32:
1725             return true;
1726         default:
1727             return false;
1728         }
1729     }
1730
1731     Arith::Mode arithMode()
1732     {
1733         ASSERT(hasArithMode());
1734         return static_cast<Arith::Mode>(m_opInfo);
1735     }
1736     
1737     void setArithMode(Arith::Mode mode)
1738     {
1739         m_opInfo = mode;
1740     }
1741
1742     bool hasArithRoundingMode()
1743     {
1744         return op() == ArithRound || op() == ArithFloor || op() == ArithCeil || op() == ArithTrunc;
1745     }
1746
1747     Arith::RoundingMode arithRoundingMode()
1748     {
1749         ASSERT(hasArithRoundingMode());
1750         return static_cast<Arith::RoundingMode>(m_opInfo);
1751     }
1752
1753     void setArithRoundingMode(Arith::RoundingMode mode)
1754     {
1755         ASSERT(hasArithRoundingMode());
1756         m_opInfo = static_cast<uintptr_t>(mode);
1757     }
1758     
1759     bool hasVirtualRegister()
1760     {
1761         return m_virtualRegister.isValid();
1762     }
1763     
1764     VirtualRegister virtualRegister()
1765     {
1766         ASSERT(hasResult());
1767         ASSERT(m_virtualRegister.isValid());
1768         return m_virtualRegister;
1769     }
1770     
1771     void setVirtualRegister(VirtualRegister virtualRegister)
1772     {
1773         ASSERT(hasResult());
1774         ASSERT(!m_virtualRegister.isValid());
1775         m_virtualRegister = virtualRegister;
1776     }
1777     
1778     bool hasExecutionCounter()
1779     {
1780         return op() == CountExecution;
1781     }
1782     
1783     Profiler::ExecutionCounter* executionCounter()
1784     {
1785         return bitwise_cast<Profiler::ExecutionCounter*>(m_opInfo);
1786     }
1787
1788     bool shouldGenerate()
1789     {
1790         return m_refCount;
1791     }
1792     
1793     bool isSemanticallySkippable()
1794     {
1795         return op() == CountExecution;
1796     }
1797
1798     unsigned refCount()
1799     {
1800         return m_refCount;
1801     }
1802
1803     unsigned postfixRef()
1804     {
1805         return m_refCount++;
1806     }
1807
1808     unsigned adjustedRefCount()
1809     {
1810         return mustGenerate() ? m_refCount - 1 : m_refCount;
1811     }
1812     
1813     void setRefCount(unsigned refCount)
1814     {
1815         m_refCount = refCount;
1816     }
1817     
1818     Edge& child1()
1819     {
1820         ASSERT(!(m_flags & NodeHasVarArgs));
1821         return children.child1();
1822     }
1823     
1824     // This is useful if you want to do a fast check on the first child
1825     // before also doing a check on the opcode. Use this with care and
1826     // avoid it if possible.
1827     Edge child1Unchecked()
1828     {
1829         return children.child1Unchecked();
1830     }
1831
1832     Edge& child2()
1833     {
1834         ASSERT(!(m_flags & NodeHasVarArgs));
1835         return children.child2();
1836     }
1837
1838     Edge& child3()
1839     {
1840         ASSERT(!(m_flags & NodeHasVarArgs));
1841         return children.child3();
1842     }
1843     
1844     unsigned firstChild()
1845     {
1846         ASSERT(m_flags & NodeHasVarArgs);
1847         return children.firstChild();
1848     }
1849     
1850     unsigned numChildren()
1851     {
1852         ASSERT(m_flags & NodeHasVarArgs);
1853         return children.numChildren();
1854     }
1855     
1856     UseKind binaryUseKind()
1857     {
1858         ASSERT(child1().useKind() == child2().useKind());
1859         return child1().useKind();
1860     }
1861     
1862     bool isBinaryUseKind(UseKind left, UseKind right)
1863     {
1864         return child1().useKind() == left && child2().useKind() == right;
1865     }
1866     
1867     bool isBinaryUseKind(UseKind useKind)
1868     {
1869         return isBinaryUseKind(useKind, useKind);
1870     }
1871     
1872     Edge childFor(UseKind useKind)
1873     {
1874         if (child1().useKind() == useKind)
1875             return child1();
1876         if (child2().useKind() == useKind)
1877             return child2();
1878         if (child3().useKind() == useKind)
1879             return child3();
1880         return Edge();
1881     }
1882     
1883     SpeculatedType prediction()
1884     {
1885         return m_prediction;
1886     }
1887     
1888     bool predict(SpeculatedType prediction)
1889     {
1890         return mergeSpeculation(m_prediction, prediction);
1891     }
1892     
1893     bool shouldSpeculateInt32()
1894     {
1895         return isInt32Speculation(prediction());
1896     }
1897     
1898     bool sawBooleans()
1899     {
1900         return !!(prediction() & SpecBoolean);
1901     }
1902     
1903     bool shouldSpeculateInt32OrBoolean()
1904     {
1905         return isInt32OrBooleanSpeculation(prediction());
1906     }
1907     
1908     bool shouldSpeculateInt32ForArithmetic()
1909     {
1910         return isInt32SpeculationForArithmetic(prediction());
1911     }
1912     
1913     bool shouldSpeculateInt32OrBooleanForArithmetic()
1914     {
1915         return isInt32OrBooleanSpeculationForArithmetic(prediction());
1916     }
1917     
1918     bool shouldSpeculateInt32OrBooleanExpectingDefined()
1919     {
1920         return isInt32OrBooleanSpeculationExpectingDefined(prediction());
1921     }
1922     
1923     bool shouldSpeculateMachineInt()
1924     {
1925         return isMachineIntSpeculation(prediction());
1926     }
1927     
1928     bool shouldSpeculateDouble()
1929     {
1930         return isDoubleSpeculation(prediction());
1931     }
1932     
1933     bool shouldSpeculateDoubleReal()
1934     {
1935         return isDoubleRealSpeculation(prediction());
1936     }
1937     
1938     bool shouldSpeculateNumber()
1939     {
1940         return isFullNumberSpeculation(prediction());
1941     }
1942     
1943     bool shouldSpeculateNumberOrBoolean()
1944     {
1945         return isFullNumberOrBooleanSpeculation(prediction());
1946     }
1947     
1948     bool shouldSpeculateNumberOrBooleanExpectingDefined()
1949     {
1950         return isFullNumberOrBooleanSpeculationExpectingDefined(prediction());
1951     }
1952     
1953     bool shouldSpeculateBoolean()
1954     {
1955         return isBooleanSpeculation(prediction());
1956     }
1957     
1958     bool shouldSpeculateOther()
1959     {
1960         return isOtherSpeculation(prediction());
1961     }
1962     
1963     bool shouldSpeculateMisc()
1964     {
1965         return isMiscSpeculation(prediction());
1966     }
1967    
1968     bool shouldSpeculateStringIdent()
1969     {
1970         return isStringIdentSpeculation(prediction());
1971     }
1972     
1973     bool shouldSpeculateNotStringVar()
1974     {
1975         return isNotStringVarSpeculation(prediction());
1976     }
1977  
1978     bool shouldSpeculateString()
1979     {
1980         return isStringSpeculation(prediction());
1981     }
1982  
1983     bool shouldSpeculateStringOrOther()
1984     {
1985         return isStringOrOtherSpeculation(prediction());
1986     }
1987  
1988     bool shouldSpeculateStringObject()
1989     {
1990         return isStringObjectSpeculation(prediction());
1991     }
1992     
1993     bool shouldSpeculateStringOrStringObject()
1994     {
1995         return isStringOrStringObjectSpeculation(prediction());
1996     }
1997
1998     bool shouldSpeculateRegExpObject()
1999     {
2000         return isRegExpObjectSpeculation(prediction());
2001     }
2002     
2003     bool shouldSpeculateSymbol()
2004     {
2005         return isSymbolSpeculation(prediction());
2006     }
2007     
2008     bool shouldSpeculateFinalObject()
2009     {
2010         return isFinalObjectSpeculation(prediction());
2011     }
2012     
2013     bool shouldSpeculateFinalObjectOrOther()
2014     {
2015         return isFinalObjectOrOtherSpeculation(prediction());
2016     }
2017     
2018     bool shouldSpeculateArray()
2019     {
2020         return isArraySpeculation(prediction());
2021     }
2022     
2023     bool shouldSpeculateDirectArguments()
2024     {
2025         return isDirectArgumentsSpeculation(prediction());
2026     }
2027     
2028     bool shouldSpeculateScopedArguments()
2029     {
2030         return isScopedArgumentsSpeculation(prediction());
2031     }
2032     
2033     bool shouldSpeculateInt8Array()
2034     {
2035         return isInt8ArraySpeculation(prediction());
2036     }
2037     
2038     bool shouldSpeculateInt16Array()
2039     {
2040         return isInt16ArraySpeculation(prediction());
2041     }
2042     
2043     bool shouldSpeculateInt32Array()
2044     {
2045         return isInt32ArraySpeculation(prediction());
2046     }
2047     
2048     bool shouldSpeculateUint8Array()
2049     {
2050         return isUint8ArraySpeculation(prediction());
2051     }
2052
2053     bool shouldSpeculateUint8ClampedArray()
2054     {
2055         return isUint8ClampedArraySpeculation(prediction());
2056     }
2057     
2058     bool shouldSpeculateUint16Array()
2059     {
2060         return isUint16ArraySpeculation(prediction());
2061     }
2062     
2063     bool shouldSpeculateUint32Array()
2064     {
2065         return isUint32ArraySpeculation(prediction());
2066     }
2067     
2068     bool shouldSpeculateFloat32Array()
2069     {
2070         return isFloat32ArraySpeculation(prediction());
2071     }
2072     
2073     bool shouldSpeculateFloat64Array()
2074     {
2075         return isFloat64ArraySpeculation(prediction());
2076     }
2077     
2078     bool shouldSpeculateArrayOrOther()
2079     {
2080         return isArrayOrOtherSpeculation(prediction());
2081     }
2082     
2083     bool shouldSpeculateObject()
2084     {
2085         return isObjectSpeculation(prediction());
2086     }
2087     
2088     bool shouldSpeculateObjectOrOther()
2089     {
2090         return isObjectOrOtherSpeculation(prediction());
2091     }
2092
2093     bool shouldSpeculateCell()
2094     {
2095         return isCellSpeculation(prediction());
2096     }
2097     
2098     bool shouldSpeculateCellOrOther()
2099     {
2100         return isCellOrOtherSpeculation(prediction());
2101     }
2102     
2103     bool shouldSpeculateNotCell()
2104     {
2105         return isNotCellSpeculation(prediction());
2106     }
2107     
2108     bool shouldSpeculateUntypedForArithmetic()
2109     {
2110         return isUntypedSpeculationForArithmetic(prediction());
2111     }
2112
2113     static bool shouldSpeculateUntypedForArithmetic(Node* op1, Node* op2)
2114     {
2115         return op1->shouldSpeculateUntypedForArithmetic() || op2->shouldSpeculateUntypedForArithmetic();
2116     }
2117     
2118     bool shouldSpeculateUntypedForBitOps()
2119     {
2120         return isUntypedSpeculationForBitOps(prediction());
2121     }
2122     
2123     static bool shouldSpeculateUntypedForBitOps(Node* op1, Node* op2)
2124     {
2125         return op1->shouldSpeculateUntypedForBitOps() || op2->shouldSpeculateUntypedForBitOps();
2126     }
2127     
2128     static bool shouldSpeculateBoolean(Node* op1, Node* op2)
2129     {
2130         return op1->shouldSpeculateBoolean() && op2->shouldSpeculateBoolean();
2131     }
2132     
2133     static bool shouldSpeculateInt32(Node* op1, Node* op2)
2134     {
2135         return op1->shouldSpeculateInt32() && op2->shouldSpeculateInt32();
2136     }
2137     
2138     static bool shouldSpeculateInt32OrBoolean(Node* op1, Node* op2)
2139     {
2140         return op1->shouldSpeculateInt32OrBoolean()
2141             && op2->shouldSpeculateInt32OrBoolean();
2142     }
2143     
2144     static bool shouldSpeculateInt32OrBooleanForArithmetic(Node* op1, Node* op2)
2145     {
2146         return op1->shouldSpeculateInt32OrBooleanForArithmetic()
2147             && op2->shouldSpeculateInt32OrBooleanForArithmetic();
2148     }
2149     
2150     static bool shouldSpeculateInt32OrBooleanExpectingDefined(Node* op1, Node* op2)
2151     {
2152         return op1->shouldSpeculateInt32OrBooleanExpectingDefined()
2153             && op2->shouldSpeculateInt32OrBooleanExpectingDefined();
2154     }
2155     
2156     static bool shouldSpeculateMachineInt(Node* op1, Node* op2)
2157     {
2158         return op1->shouldSpeculateMachineInt() && op2->shouldSpeculateMachineInt();
2159     }
2160     
2161     static bool shouldSpeculateNumber(Node* op1, Node* op2)
2162     {
2163         return op1->shouldSpeculateNumber() && op2->shouldSpeculateNumber();
2164     }
2165     
2166     static bool shouldSpeculateNumberOrBoolean(Node* op1, Node* op2)
2167     {
2168         return op1->shouldSpeculateNumberOrBoolean()
2169             && op2->shouldSpeculateNumberOrBoolean();
2170     }
2171     
2172     static bool shouldSpeculateNumberOrBooleanExpectingDefined(Node* op1, Node* op2)
2173     {
2174         return op1->shouldSpeculateNumberOrBooleanExpectingDefined()
2175             && op2->shouldSpeculateNumberOrBooleanExpectingDefined();
2176     }
2177
2178     static bool shouldSpeculateSymbol(Node* op1, Node* op2)
2179     {
2180         return op1->shouldSpeculateSymbol() && op2->shouldSpeculateSymbol();
2181     }
2182     
2183     static bool shouldSpeculateFinalObject(Node* op1, Node* op2)
2184     {
2185         return op1->shouldSpeculateFinalObject() && op2->shouldSpeculateFinalObject();
2186     }
2187
2188     static bool shouldSpeculateArray(Node* op1, Node* op2)
2189     {
2190         return op1->shouldSpeculateArray() && op2->shouldSpeculateArray();
2191     }
2192     
2193     bool canSpeculateInt32(RareCaseProfilingSource source)
2194     {
2195         return nodeCanSpeculateInt32(arithNodeFlags(), source);
2196     }
2197     
2198     bool canSpeculateInt52(RareCaseProfilingSource source)
2199     {
2200         return nodeCanSpeculateInt52(arithNodeFlags(), source);
2201     }
2202     
2203     RareCaseProfilingSource sourceFor(PredictionPass pass)
2204     {
2205         if (pass == PrimaryPass || child1()->sawBooleans() || (child2() && child2()->sawBooleans()))
2206             return DFGRareCase;
2207         return AllRareCases;
2208     }
2209     
2210     bool canSpeculateInt32(PredictionPass pass)
2211     {
2212         return canSpeculateInt32(sourceFor(pass));
2213     }
2214     
2215     bool canSpeculateInt52(PredictionPass pass)
2216     {
2217         return canSpeculateInt52(sourceFor(pass));
2218     }
2219
2220     bool hasTypeLocation()
2221     {
2222         return op() == ProfileType;
2223     }
2224
2225     TypeLocation* typeLocation()
2226     {
2227         ASSERT(hasTypeLocation());
2228         return reinterpret_cast<TypeLocation*>(m_opInfo);
2229     }
2230
2231     bool hasBasicBlockLocation()
2232     {
2233         return op() == ProfileControlFlow;
2234     }
2235
2236     BasicBlockLocation* basicBlockLocation()
2237     {
2238         ASSERT(hasBasicBlockLocation());
2239         return reinterpret_cast<BasicBlockLocation*>(m_opInfo);
2240     }
2241     
2242     Node* replacement() const
2243     {
2244         return m_misc.replacement;
2245     }
2246     
2247     void setReplacement(Node* replacement)
2248     {
2249         m_misc.replacement = replacement;
2250     }
2251     
2252     Epoch epoch() const
2253     {
2254         return Epoch::fromUnsigned(m_misc.epoch);
2255     }
2256     
2257     void setEpoch(Epoch epoch)
2258     {
2259         m_misc.epoch = epoch.toUnsigned();
2260     }
2261
2262     unsigned numberOfArgumentsToSkip()
2263     {
2264         ASSERT(op() == CopyRest || op() == GetRestLength);
2265         return static_cast<unsigned>(m_opInfo);
2266     }
2267
2268     void dumpChildren(PrintStream& out)
2269     {
2270         if (!child1())
2271             return;
2272         out.printf("@%u", child1()->index());
2273         if (!child2())
2274             return;
2275         out.printf(", @%u", child2()->index());
2276         if (!child3())
2277             return;
2278         out.printf(", @%u", child3()->index());
2279     }
2280     
2281     // NB. This class must have a trivial destructor.
2282
2283     NodeOrigin origin;
2284
2285     // References to up to 3 children, or links to a variable length set of children.
2286     AdjacencyList children;
2287
2288 private:
2289     unsigned m_op : 10; // real type is NodeType
2290     unsigned m_flags : 22;
2291     // The virtual register number (spill location) associated with this .
2292     VirtualRegister m_virtualRegister;
2293     // The number of uses of the result of this operation (+1 for 'must generate' nodes, which have side-effects).
2294     unsigned m_refCount;
2295     // The prediction ascribed to this node after propagation.
2296     SpeculatedType m_prediction;
2297     // Immediate values, accesses type-checked via accessors above. The first one is
2298     // big enough to store a pointer.
2299     uintptr_t m_opInfo;
2300     uintptr_t m_opInfo2;
2301
2302 public:
2303     // Fields used by various analyses.
2304     AbstractValue value;
2305     
2306     // Miscellaneous data that is usually meaningless, but can hold some analysis results
2307     // if you ask right. For example, if you do Graph::initializeNodeOwners(), Node::owner
2308     // will tell you which basic block a node belongs to. You cannot rely on this persisting
2309     // across transformations unless you do the maintenance work yourself. Other phases use
2310     // Node::replacement, but they do so manually: first you do Graph::clearReplacements()
2311     // and then you set, and use, replacement's yourself. Same thing for epoch.
2312     //
2313     // Bottom line: don't use these fields unless you initialize them yourself, or by
2314     // calling some appropriate methods that initialize them the way you want. Otherwise,
2315     // these fields are meaningless.
2316 private:
2317     union {
2318         Node* replacement;
2319         unsigned epoch;
2320     } m_misc;
2321 public:
2322     BasicBlock* owner;
2323 };
2324
2325 inline bool nodeComparator(Node* a, Node* b)
2326 {
2327     return a->index() < b->index();
2328 }
2329
2330 template<typename T>
2331 CString nodeListDump(const T& nodeList)
2332 {
2333     return sortedListDump(nodeList, nodeComparator);
2334 }
2335
2336 template<typename T>
2337 CString nodeMapDump(const T& nodeMap, DumpContext* context = 0)
2338 {
2339     Vector<typename T::KeyType> keys;
2340     for (
2341         typename T::const_iterator iter = nodeMap.begin();
2342         iter != nodeMap.end(); ++iter)
2343         keys.append(iter->key);
2344     std::sort(keys.begin(), keys.end(), nodeComparator);
2345     StringPrintStream out;
2346     CommaPrinter comma;
2347     for(unsigned i = 0; i < keys.size(); ++i)
2348         out.print(comma, keys[i], "=>", inContext(nodeMap.get(keys[i]), context));
2349     return out.toCString();
2350 }
2351
2352 template<typename T>
2353 CString nodeValuePairListDump(const T& nodeValuePairList, DumpContext* context = 0)
2354 {
2355     using V = typename T::ValueType;
2356     T sortedList = nodeValuePairList;
2357     std::sort(sortedList.begin(), sortedList.end(), [](const V& a, const V& b) {
2358         return nodeComparator(a.node, b.node);
2359     });
2360
2361     StringPrintStream out;
2362     CommaPrinter comma;
2363     for (const auto& pair : sortedList)
2364         out.print(comma, pair.node, "=>", inContext(pair.value, context));
2365     return out.toCString();
2366 }
2367
2368 } } // namespace JSC::DFG
2369
2370 namespace WTF {
2371
2372 void printInternal(PrintStream&, JSC::DFG::SwitchKind);
2373 void printInternal(PrintStream&, JSC::DFG::Node*);
2374
2375 inline JSC::DFG::Node* inContext(JSC::DFG::Node* node, JSC::DumpContext*) { return node; }
2376
2377 } // namespace WTF
2378
2379 using WTF::inContext;
2380
2381 #endif
2382 #endif