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