2  * Copyright (C) 2011-2015 Apple Inc. All rights reserved. 
   4  * Redistribution and use in source and binary forms, with or without 
   5  * modification, are permitted provided that the following conditions 
   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. 
  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.  
  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" 
  39 #include "DFGLazyJSValue.h" 
  40 #include "DFGNodeFlags.h" 
  41 #include "DFGNodeOrigin.h" 
  42 #include "DFGNodeType.h" 
  43 #include "DFGObjectMaterializationData.h" 
  44 #include "DFGTransition.h" 
  45 #include "DFGUseKind.h" 
  46 #include "DFGVariableAccessData.h" 
  47 #include "GetByIdVariant.h" 
  48 #include "JSCJSValue.h" 
  50 #include "PutByIdVariant.h" 
  51 #include "SpeculatedType.h" 
  52 #include "StructureSet.h" 
  53 #include "TypeLocation.h" 
  54 #include "ValueProfile.h" 
  55 #include <wtf/ListDump.h> 
  57 namespace JSC 
{ namespace DFG 
{ 
  60 class PromotedLocationDescriptor
; 
  63 struct StorageAccessData 
{ 
  64     PropertyOffset offset
; 
  65     unsigned identifierNumber
; 
  68 struct MultiGetByOffsetData 
{ 
  69     unsigned identifierNumber
; 
  70     Vector
<GetByIdVariant
, 2> variants
; 
  73 struct MultiPutByOffsetData 
{ 
  74     unsigned identifierNumber
; 
  75     Vector
<PutByIdVariant
, 2> variants
; 
  77     bool writesStructures() const; 
  78     bool reallocatesStorage() const; 
  81 struct NewArrayBufferData 
{ 
  82     unsigned startConstant
; 
  83     unsigned numConstants
; 
  84     IndexingType indexingType
; 
  94     explicit BranchTarget(BasicBlock
* block
) 
 100     void setBytecodeIndex(unsigned bytecodeIndex
) 
 102         block 
= bitwise_cast
<BasicBlock
*>(static_cast<uintptr_t>(bytecodeIndex
)); 
 104     unsigned bytecodeIndex() const { return bitwise_cast
<uintptr_t>(block
); } 
 106     void dump(PrintStream
&) const; 
 113     static BranchData 
withBytecodeIndices( 
 114         unsigned takenBytecodeIndex
, unsigned notTakenBytecodeIndex
) 
 117         result
.taken
.block 
= bitwise_cast
<BasicBlock
*>(static_cast<uintptr_t>(takenBytecodeIndex
)); 
 118         result
.notTaken
.block 
= bitwise_cast
<BasicBlock
*>(static_cast<uintptr_t>(notTakenBytecodeIndex
)); 
 122     unsigned takenBytecodeIndex() const { return taken
.bytecodeIndex(); } 
 123     unsigned notTakenBytecodeIndex() const { return notTaken
.bytecodeIndex(); } 
 125     BasicBlock
*& forCondition(bool condition
) 
 129         return notTaken
.block
; 
 133     BranchTarget notTaken
; 
 136 // The SwitchData and associated data structures duplicate the information in 
 137 // JumpTable. The DFG may ultimately end up using the JumpTable, though it may 
 138 // instead decide to do something different - this is entirely up to the DFG. 
 139 // These data structures give the DFG a higher-level semantic description of 
 140 // what is going on, which will allow it to make the right decision. 
 142 // Note that there will never be multiple SwitchCases in SwitchData::cases that 
 143 // have the same SwitchCase::value, since the bytecode's JumpTables never have 
 144 // duplicates - since the JumpTable maps a value to a target. It's a 
 145 // one-to-many mapping. So we may have duplicate targets, but never duplicate 
 152     SwitchCase(LazyJSValue value
, BasicBlock
* target
) 
 158     static SwitchCase 
withBytecodeIndex(LazyJSValue value
, unsigned bytecodeIndex
) 
 161         result
.value 
= value
; 
 162         result
.target
.setBytecodeIndex(bytecodeIndex
); 
 171     // Initializes most fields to obviously invalid values. Anyone 
 172     // constructing this should make sure to initialize everything they 
 173     // care about manually. 
 175         : kind(static_cast<SwitchKind
>(-1)) 
 176         , switchTableIndex(UINT_MAX
) 
 177         , didUseJumpTable(false) 
 181     Vector
<SwitchCase
> cases
; 
 182     BranchTarget fallThrough
; 
 184     unsigned switchTableIndex
; 
 185     bool didUseJumpTable
; 
 188 struct CallVarargsData 
{ 
 189     int firstVarArgOffset
; 
 192 struct LoadVarargsData 
{ 
 193     VirtualRegister start
; // Local for the first element. This is the first actual argument, not this. 
 194     VirtualRegister count
; // Local for the count. 
 195     VirtualRegister machineStart
; 
 196     VirtualRegister machineCount
; 
 197     unsigned offset
; // Which array element to start with. Usually this is 0. 
 198     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". 
 199     unsigned limit
; // Maximum number of elements to load. Includes "this". 
 202 struct StackAccessData 
{ 
 208     StackAccessData(VirtualRegister local
, FlushFormat format
) 
 214     VirtualRegister local
; 
 215     VirtualRegister machineLocal
; 
 218     FlushedAt 
flushedAt() { return FlushedAt(format
, machineLocal
); } 
 221 // This type used in passing an immediate argument to Node constructor; 
 222 // distinguishes an immediate value (typically an index into a CodeBlock data structure -  
 223 // a constant index, argument, or identifier) from a Node*. 
 225     OpInfo() : m_value(0) { } 
 226     explicit OpInfo(int32_t value
) : m_value(static_cast<uintptr_t>(value
)) { } 
 227     explicit OpInfo(uint32_t value
) : m_value(static_cast<uintptr_t>(value
)) { } 
 228 #if OS(DARWIN) || USE(JSVALUE64) 
 229     explicit OpInfo(size_t value
) : m_value(static_cast<uintptr_t>(value
)) { } 
 231     explicit OpInfo(void* value
) : m_value(reinterpret_cast<uintptr_t>(value
)) { } 
 237 // Node represents a single operation in the data flow graph. 
 239     enum VarArgTag 
{ VarArg 
}; 
 243     Node(NodeType op
, NodeOrigin nodeOrigin
, const AdjacencyList
& children
) 
 246         , m_virtualRegister(VirtualRegister()) 
 248         , m_prediction(SpecNone
) 
 251         m_misc
.replacement 
= nullptr; 
 252         setOpAndDefaultFlags(op
); 
 255     // Construct a node with up to 3 children, no immediate value. 
 256     Node(NodeType op
, NodeOrigin nodeOrigin
, Edge child1 
= Edge(), Edge child2 
= Edge(), Edge child3 
= Edge()) 
 258         , children(AdjacencyList::Fixed
, child1
, child2
, child3
) 
 259         , m_virtualRegister(VirtualRegister()) 
 261         , m_prediction(SpecNone
) 
 266         m_misc
.replacement 
= nullptr; 
 267         setOpAndDefaultFlags(op
); 
 268         ASSERT(!(m_flags 
& NodeHasVarArgs
)); 
 271     // Construct a node with up to 3 children, no immediate value. 
 272     Node(NodeFlags result
, NodeType op
, NodeOrigin nodeOrigin
, Edge child1 
= Edge(), Edge child2 
= Edge(), Edge child3 
= Edge()) 
 274         , children(AdjacencyList::Fixed
, child1
, child2
, child3
) 
 275         , m_virtualRegister(VirtualRegister()) 
 277         , m_prediction(SpecNone
) 
 282         m_misc
.replacement 
= nullptr; 
 283         setOpAndDefaultFlags(op
); 
 285         ASSERT(!(m_flags 
& NodeHasVarArgs
)); 
 288     // Construct a node with up to 3 children and an immediate value. 
 289     Node(NodeType op
, NodeOrigin nodeOrigin
, OpInfo imm
, Edge child1 
= Edge(), Edge child2 
= Edge(), Edge child3 
= Edge()) 
 291         , children(AdjacencyList::Fixed
, child1
, child2
, child3
) 
 292         , m_virtualRegister(VirtualRegister()) 
 294         , m_prediction(SpecNone
) 
 295         , m_opInfo(imm
.m_value
) 
 299         m_misc
.replacement 
= nullptr; 
 300         setOpAndDefaultFlags(op
); 
 301         ASSERT(!(m_flags 
& NodeHasVarArgs
)); 
 304     // Construct a node with up to 3 children and an immediate value. 
 305     Node(NodeFlags result
, NodeType op
, NodeOrigin nodeOrigin
, OpInfo imm
, Edge child1 
= Edge(), Edge child2 
= Edge(), Edge child3 
= Edge()) 
 307         , children(AdjacencyList::Fixed
, child1
, child2
, child3
) 
 308         , m_virtualRegister(VirtualRegister()) 
 310         , m_prediction(SpecNone
) 
 311         , m_opInfo(imm
.m_value
) 
 315         m_misc
.replacement 
= nullptr; 
 316         setOpAndDefaultFlags(op
); 
 318         ASSERT(!(m_flags 
& NodeHasVarArgs
)); 
 321     // Construct a node with up to 3 children and two immediate values. 
 322     Node(NodeType op
, NodeOrigin nodeOrigin
, OpInfo imm1
, OpInfo imm2
, Edge child1 
= Edge(), Edge child2 
= Edge(), Edge child3 
= Edge()) 
 324         , children(AdjacencyList::Fixed
, child1
, child2
, child3
) 
 325         , m_virtualRegister(VirtualRegister()) 
 327         , m_prediction(SpecNone
) 
 328         , m_opInfo(imm1
.m_value
) 
 329         , m_opInfo2(imm2
.m_value
) 
 332         m_misc
.replacement 
= nullptr; 
 333         setOpAndDefaultFlags(op
); 
 334         ASSERT(!(m_flags 
& NodeHasVarArgs
)); 
 337     // Construct a node with a variable number of children and two immediate values. 
 338     Node(VarArgTag
, NodeType op
, NodeOrigin nodeOrigin
, OpInfo imm1
, OpInfo imm2
, unsigned firstChild
, unsigned numChildren
) 
 340         , children(AdjacencyList::Variable
, firstChild
, numChildren
) 
 341         , m_virtualRegister(VirtualRegister()) 
 343         , m_prediction(SpecNone
) 
 344         , m_opInfo(imm1
.m_value
) 
 345         , m_opInfo2(imm2
.m_value
) 
 348         m_misc
.replacement 
= nullptr; 
 349         setOpAndDefaultFlags(op
); 
 350         ASSERT(m_flags 
& NodeHasVarArgs
); 
 353     NodeType 
op() const { return static_cast<NodeType
>(m_op
); } 
 354     NodeFlags 
flags() const { return m_flags
; } 
 356     // This is not a fast method. 
 357     unsigned index() const; 
 359     void setOp(NodeType op
) 
 364     void setFlags(NodeFlags flags
) 
 369     bool mergeFlags(NodeFlags flags
) 
 371         NodeFlags newFlags 
= m_flags 
| flags
; 
 372         if (newFlags 
== m_flags
) 
 378     bool filterFlags(NodeFlags flags
) 
 380         NodeFlags newFlags 
= m_flags 
& flags
; 
 381         if (newFlags 
== m_flags
) 
 387     bool clearFlags(NodeFlags flags
) 
 389         return filterFlags(~flags
); 
 392     void setResult(NodeFlags result
) 
 394         ASSERT(!(result 
& ~NodeResultMask
)); 
 395         clearFlags(NodeResultMask
); 
 399     NodeFlags 
result() const 
 401         return flags() & NodeResultMask
; 
 404     void setOpAndDefaultFlags(NodeType op
) 
 407         m_flags 
= defaultFlags(op
); 
 412     void convertToCheckStructure(StructureSet
* set
) 
 414         setOpAndDefaultFlags(CheckStructure
); 
 415         m_opInfo 
= bitwise_cast
<uintptr_t>(set
);  
 418     void convertToCheckStructureImmediate(Node
* structure
) 
 420         ASSERT(op() == CheckStructure
); 
 421         m_op 
= CheckStructureImmediate
; 
 422         children
.setChild1(Edge(structure
, CellUse
)); 
 425     void replaceWith(Node
* other
) 
 428         setReplacement(other
); 
 431     void convertToIdentity(); 
 432     void convertToIdentityOn(Node
*); 
 436         return m_flags 
& NodeMustGenerate
; 
 459         case PhantomDirectArguments
: 
 460         case PhantomClonedArguments
: 
 461             // These pretend to be the empty value constant for the benefit of the DFG backend, which 
 462             // otherwise wouldn't take kindly to a node that doesn't compute a value. 
 470     FrozenValue
* constant() 
 472         ASSERT(hasConstant()); 
 474         if (op() == PhantomDirectArguments 
|| op() == PhantomClonedArguments
) { 
 475             // These pretend to be the empty value constant for the benefit of the DFG backend, which 
 476             // otherwise wouldn't take kindly to a node that doesn't compute a value. 
 477             return FrozenValue::emptySingleton(); 
 480         return bitwise_cast
<FrozenValue
*>(m_opInfo
); 
 483     // Don't call this directly - use Graph::convertToConstant() instead! 
 484     void convertToConstant(FrozenValue
* value
) 
 486         if (hasDoubleResult()) 
 487             m_op 
= DoubleConstant
; 
 488         else if (hasInt52Result()) 
 489             m_op 
= Int52Constant
; 
 492         m_flags 
&= ~NodeMustGenerate
; 
 493         m_opInfo 
= bitwise_cast
<uintptr_t>(value
); 
 497     void convertToConstantStoragePointer(void* pointer
) 
 499         ASSERT(op() == GetIndexedPropertyStorage
); 
 500         m_op 
= ConstantStoragePointer
; 
 501         m_opInfo 
= bitwise_cast
<uintptr_t>(pointer
); 
 505     void convertToGetLocalUnlinked(VirtualRegister local
) 
 507         m_op 
= GetLocalUnlinked
; 
 508         m_flags 
&= ~NodeMustGenerate
; 
 509         m_opInfo 
= local
.offset(); 
 510         m_opInfo2 
= VirtualRegister().offset(); 
 514     void convertToPutStack(StackAccessData
* data
) 
 517         m_flags 
|= NodeMustGenerate
; 
 518         m_opInfo 
= bitwise_cast
<uintptr_t>(data
); 
 522     void convertToGetStack(StackAccessData
* data
) 
 525         m_flags 
&= ~NodeMustGenerate
; 
 526         m_opInfo 
= bitwise_cast
<uintptr_t>(data
); 
 531     void convertToGetByOffset(StorageAccessData
& data
, Edge storage
) 
 533         ASSERT(m_op 
== GetById 
|| m_op 
== GetByIdFlush 
|| m_op 
== MultiGetByOffset
); 
 534         m_opInfo 
= bitwise_cast
<uintptr_t>(&data
); 
 535         children
.setChild2(children
.child1()); 
 536         children
.child2().setUseKind(KnownCellUse
); 
 537         children
.setChild1(storage
); 
 539         m_flags 
&= ~NodeMustGenerate
; 
 542     void convertToMultiGetByOffset(MultiGetByOffsetData
* data
) 
 544         ASSERT(m_op 
== GetById 
|| m_op 
== GetByIdFlush
); 
 545         m_opInfo 
= bitwise_cast
<intptr_t>(data
); 
 546         child1().setUseKind(CellUse
); 
 547         m_op 
= MultiGetByOffset
; 
 548         ASSERT(m_flags 
& NodeMustGenerate
); 
 551     void convertToPutByOffset(StorageAccessData
& data
, Edge storage
) 
 553         ASSERT(m_op 
== PutById 
|| m_op 
== PutByIdDirect 
|| m_op 
== PutByIdFlush 
|| m_op 
== MultiPutByOffset
); 
 554         m_opInfo 
= bitwise_cast
<uintptr_t>(&data
); 
 555         children
.setChild3(children
.child2()); 
 556         children
.setChild2(children
.child1()); 
 557         children
.setChild1(storage
); 
 561     void convertToMultiPutByOffset(MultiPutByOffsetData
* data
) 
 563         ASSERT(m_op 
== PutById 
|| m_op 
== PutByIdDirect 
|| m_op 
== PutByIdFlush
); 
 564         m_opInfo 
= bitwise_cast
<intptr_t>(data
); 
 565         m_op 
= MultiPutByOffset
; 
 568     void convertToPutHint(const PromotedLocationDescriptor
&, Node
* base
, Node
* value
); 
 570     void convertToPutByOffsetHint(); 
 571     void convertToPutStructureHint(Node
* structure
); 
 572     void convertToPutClosureVarHint(); 
 574     void convertToPhantomNewObject() 
 576         ASSERT(m_op 
== NewObject 
|| m_op 
== MaterializeNewObject
); 
 577         m_op 
= PhantomNewObject
; 
 578         m_flags 
&= ~NodeHasVarArgs
; 
 579         m_flags 
|= NodeMustGenerate
; 
 582         children 
= AdjacencyList(); 
 585     void convertToPhantomNewFunction() 
 587         ASSERT(m_op 
== NewFunction
); 
 588         m_op 
= PhantomNewFunction
; 
 589         m_flags 
|= NodeMustGenerate
; 
 592         children 
= AdjacencyList(); 
 595     void convertToPhantomCreateActivation() 
 597         ASSERT(m_op 
== CreateActivation 
|| m_op 
== MaterializeCreateActivation
); 
 598         m_op 
= PhantomCreateActivation
; 
 599         m_flags 
&= ~NodeHasVarArgs
; 
 600         m_flags 
|= NodeMustGenerate
; 
 603         children 
= AdjacencyList(); 
 606     void convertPhantomToPhantomLocal() 
 608         ASSERT(m_op 
== Phantom 
&& (child1()->op() == Phi 
|| child1()->op() == SetLocal 
|| child1()->op() == SetArgument
)); 
 610         m_opInfo 
= child1()->m_opInfo
; // Copy the variableAccessData. 
 611         children
.setChild1(Edge()); 
 614     void convertFlushToPhantomLocal() 
 616         ASSERT(m_op 
== Flush
); 
 618         children 
= AdjacencyList(); 
 621     void convertToGetLocal(VariableAccessData
* variable
, Node
* phi
) 
 623         ASSERT(m_op 
== GetLocalUnlinked
); 
 625         m_opInfo 
= bitwise_cast
<uintptr_t>(variable
); 
 627         children
.setChild1(Edge(phi
)); 
 630     void convertToToString() 
 632         ASSERT(m_op 
== ToPrimitive
); 
 636     void convertToArithSqrt() 
 638         ASSERT(m_op 
== ArithPow
); 
 645         return constant()->value(); 
 648     bool isInt32Constant() 
 650         return isConstant() && constant()->value().isInt32(); 
 655         return asJSValue().asInt32(); 
 663     bool isDoubleConstant() 
 665         return isConstant() && constant()->value().isDouble(); 
 668     bool isNumberConstant() 
 670         return isConstant() && constant()->value().isNumber(); 
 675         return asJSValue().asNumber(); 
 678     bool isMachineIntConstant() 
 680         return isConstant() && constant()->value().isMachineInt(); 
 683     int64_t asMachineInt() 
 685         return asJSValue().asMachineInt(); 
 688     bool isBooleanConstant() 
 690         return isConstant() && constant()->value().isBoolean(); 
 695         return constant()->value().asBoolean(); 
 698     bool isCellConstant() 
 700         return isConstant() && constant()->value() && constant()->value().isCell(); 
 705         return constant()->value().asCell(); 
 709     T 
dynamicCastConstant() 
 711         if (!isCellConstant()) 
 713         return jsDynamicCast
<T
>(asCell()); 
 719         T result 
= dynamicCastConstant
<T
>(); 
 720         RELEASE_ASSERT(result
); 
 724     bool containsMovHint() 
 735     bool hasVariableAccessData(Graph
&); 
 736     bool hasLocal(Graph
& graph
) 
 738         return hasVariableAccessData(graph
); 
 741     // This is useful for debugging code, where a node that should have a variable 
 742     // access data doesn't have one because it hasn't been initialized yet. 
 743     VariableAccessData
* tryGetVariableAccessData() 
 745         VariableAccessData
* result 
= reinterpret_cast<VariableAccessData
*>(m_opInfo
); 
 748         return result
->find(); 
 751     VariableAccessData
* variableAccessData() 
 753         return reinterpret_cast<VariableAccessData
*>(m_opInfo
)->find(); 
 756     VirtualRegister 
local() 
 758         return variableAccessData()->local(); 
 761     VirtualRegister 
machineLocal() 
 763         return variableAccessData()->machineLocal(); 
 766     bool hasUnlinkedLocal() 
 769         case GetLocalUnlinked
: 
 770         case ExtractOSREntryLocal
: 
 780     VirtualRegister 
unlinkedLocal() 
 782         ASSERT(hasUnlinkedLocal()); 
 783         return static_cast<VirtualRegister
>(m_opInfo
); 
 786     bool hasUnlinkedMachineLocal() 
 788         return op() == GetLocalUnlinked
; 
 791     void setUnlinkedMachineLocal(VirtualRegister reg
) 
 793         ASSERT(hasUnlinkedMachineLocal()); 
 794         m_opInfo2 
= reg
.offset(); 
 797     VirtualRegister 
unlinkedMachineLocal() 
 799         ASSERT(hasUnlinkedMachineLocal()); 
 800         return VirtualRegister(m_opInfo2
); 
 803     bool hasStackAccessData() 
 814     StackAccessData
* stackAccessData() 
 816         ASSERT(hasStackAccessData()); 
 817         return bitwise_cast
<StackAccessData
*>(m_opInfo
); 
 822         return op() == Upsilon
; 
 828         return bitwise_cast
<Node
*>(m_opInfo
); 
 831     bool isStoreBarrier() 
 833         return op() == StoreBarrier
; 
 850     unsigned identifierNumber() 
 852         ASSERT(hasIdentifier()); 
 856     bool hasPromotedLocationDescriptor() 
 858         return op() == PutHint
; 
 861     PromotedLocationDescriptor 
promotedLocationDescriptor(); 
 863     // This corrects the arithmetic node flags, so that irrelevant bits are 
 864     // ignored. In particular, anything other than ArithMul does not need 
 865     // to know if it can speculate on negative zero. 
 866     NodeFlags 
arithNodeFlags() 
 868         NodeFlags result 
= m_flags 
& NodeArithFlagsMask
; 
 869         if (op() == ArithMul 
|| op() == ArithDiv 
|| op() == ArithMod 
|| op() == ArithNegate 
|| op() == ArithPow 
|| op() == ArithRound 
|| op() == DoubleAsInt32
) 
 871         return result 
& ~NodeBytecodeNeedsNegZero
; 
 874     bool hasConstantBuffer() 
 876         return op() == NewArrayBuffer
; 
 879     NewArrayBufferData
* newArrayBufferData() 
 881         ASSERT(hasConstantBuffer()); 
 882         return reinterpret_cast<NewArrayBufferData
*>(m_opInfo
); 
 885     unsigned startConstant() 
 887         return newArrayBufferData()->startConstant
; 
 890     unsigned numConstants() 
 892         return newArrayBufferData()->numConstants
; 
 895     bool hasIndexingType() 
 899         case NewArrayWithSize
: 
 907     IndexingType 
indexingType() 
 909         ASSERT(hasIndexingType()); 
 910         if (op() == NewArrayBuffer
) 
 911             return newArrayBufferData()->indexingType
; 
 915     bool hasTypedArrayType() 
 925     TypedArrayType 
typedArrayType() 
 927         ASSERT(hasTypedArrayType()); 
 928         TypedArrayType result 
= static_cast<TypedArrayType
>(m_opInfo
); 
 929         ASSERT(isTypedView(result
)); 
 933     bool hasInlineCapacity() 
 935         return op() == CreateThis
; 
 938     unsigned inlineCapacity() 
 940         ASSERT(hasInlineCapacity()); 
 944     void setIndexingType(IndexingType indexingType
) 
 946         ASSERT(hasIndexingType()); 
 947         m_opInfo 
= indexingType
; 
 950     bool hasRegexpIndex() 
 952         return op() == NewRegexp
; 
 955     unsigned regexpIndex() 
 957         ASSERT(hasRegexpIndex()); 
 961     bool hasScopeOffset() 
 963         return op() == GetClosureVar 
|| op() == PutClosureVar
; 
 966     ScopeOffset 
scopeOffset() 
 968         ASSERT(hasScopeOffset()); 
 969         return ScopeOffset(m_opInfo
); 
 972     bool hasDirectArgumentsOffset() 
 974         return op() == GetFromArguments 
|| op() == PutToArguments
; 
 977     DirectArgumentsOffset 
capturedArgumentsOffset() 
 979         ASSERT(hasDirectArgumentsOffset()); 
 980         return DirectArgumentsOffset(m_opInfo
); 
 983     bool hasRegisterPointer() 
 985         return op() == GetGlobalVar 
|| op() == PutGlobalVar
; 
 988     WriteBarrier
<Unknown
>* variablePointer() 
 990         return bitwise_cast
<WriteBarrier
<Unknown
>*>(m_opInfo
); 
 993     bool hasCallVarargsData() 
 997         case CallForwardVarargs
: 
 998         case ConstructVarargs
: 
 999         case ConstructForwardVarargs
: 
1006     CallVarargsData
* callVarargsData() 
1008         ASSERT(hasCallVarargsData()); 
1009         return bitwise_cast
<CallVarargsData
*>(m_opInfo
); 
1012     bool hasLoadVarargsData() 
1014         return op() == LoadVarargs 
|| op() == ForwardVarargs
; 
1017     LoadVarargsData
* loadVarargsData() 
1019         ASSERT(hasLoadVarargsData()); 
1020         return bitwise_cast
<LoadVarargsData
*>(m_opInfo
); 
1028     bool hasInt32Result() 
1030         return result() == NodeResultInt32
; 
1033     bool hasInt52Result() 
1035         return result() == NodeResultInt52
; 
1038     bool hasNumberResult() 
1040         return result() == NodeResultNumber
; 
1043     bool hasDoubleResult() 
1045         return result() == NodeResultDouble
; 
1050         return result() == NodeResultJS
; 
1053     bool hasBooleanResult() 
1055         return result() == NodeResultBoolean
; 
1058     bool hasStorageResult() 
1060         return result() == NodeResultStorage
; 
1063     UseKind 
defaultUseKind() 
1065         return useKindForResult(result()); 
1070         return Edge(this, defaultUseKind()); 
1075         return op() == Jump
; 
1080         return op() == Branch
; 
1085         return op() == Switch
; 
1102     unsigned targetBytecodeOffsetDuringParsing() 
1108     BasicBlock
*& targetBlock() 
1111         return *bitwise_cast
<BasicBlock
**>(&m_opInfo
); 
1114     BranchData
* branchData() 
1117         return bitwise_cast
<BranchData
*>(m_opInfo
); 
1120     SwitchData
* switchData() 
1123         return bitwise_cast
<SwitchData
*>(m_opInfo
); 
1126     unsigned numSuccessors() 
1134             return switchData()->cases
.size() + 1; 
1140     BasicBlock
*& successor(unsigned index
) 
1143             if (index 
< switchData()->cases
.size()) 
1144                 return switchData()->cases
[index
].target
.block
; 
1145             RELEASE_ASSERT(index 
== switchData()->cases
.size()); 
1146             return switchData()->fallThrough
.block
; 
1151                 return targetBlock(); 
1152             return branchData()->taken
.block
; 
1154             return branchData()->notTaken
.block
; 
1156             RELEASE_ASSERT_NOT_REACHED(); 
1157             return targetBlock(); 
1161     class SuccessorsIterable 
{ 
1163         SuccessorsIterable() 
1164             : m_terminal(nullptr) 
1168         SuccessorsIterable(Node
* terminal
) 
1169             : m_terminal(terminal
) 
1176                 : m_terminal(nullptr) 
1181             iterator(Node
* terminal
, unsigned index
) 
1182                 : m_terminal(terminal
) 
1187             BasicBlock
* operator*() 
1189                 return m_terminal
->successor(m_index
); 
1192             iterator
& operator++() 
1198             bool operator==(const iterator
& other
) const 
1200                 return m_index 
== other
.m_index
; 
1203             bool operator!=(const iterator
& other
) const 
1205                 return !(*this == other
); 
1214             return iterator(m_terminal
, 0); 
1219             return iterator(m_terminal
, m_terminal
->numSuccessors()); 
1226     SuccessorsIterable 
successors() 
1228         return SuccessorsIterable(this); 
1231     BasicBlock
*& successorForCondition(bool condition
) 
1233         return branchData()->forCondition(condition
); 
1236     bool hasHeapPrediction() 
1240         case GetDirectPname
: 
1247         case ConstructVarargs
: 
1248         case CallForwardVarargs
: 
1250         case NativeConstruct
: 
1252         case MultiGetByOffset
: 
1254         case GetFromArguments
: 
1266     SpeculatedType 
getHeapPrediction() 
1268         ASSERT(hasHeapPrediction()); 
1269         return static_cast<SpeculatedType
>(m_opInfo2
); 
1272     void setHeapPrediction(SpeculatedType prediction
) 
1274         ASSERT(hasHeapPrediction()); 
1275         m_opInfo2 
= prediction
; 
1278     bool hasCellOperand() 
1282         case NativeConstruct
: 
1285         case CreateActivation
: 
1286         case MaterializeCreateActivation
: 
1293     FrozenValue
* cellOperand() 
1295         ASSERT(hasCellOperand()); 
1297         case MaterializeCreateActivation
: 
1298             return reinterpret_cast<FrozenValue
*>(m_opInfo2
); 
1300             return reinterpret_cast<FrozenValue
*>(m_opInfo
); 
1302         RELEASE_ASSERT_NOT_REACHED(); 
1305     template<typename T
> 
1308         return cellOperand()->cast
<T
>(); 
1311     void setCellOperand(FrozenValue
* value
) 
1313         ASSERT(hasCellOperand()); 
1314         m_opInfo 
= bitwise_cast
<uintptr_t>(value
); 
1317     bool hasWatchpointSet() 
1319         return op() == NotifyWrite
; 
1322     WatchpointSet
* watchpointSet() 
1324         ASSERT(hasWatchpointSet()); 
1325         return reinterpret_cast<WatchpointSet
*>(m_opInfo
); 
1328     bool hasStoragePointer() 
1330         return op() == ConstantStoragePointer
; 
1333     void* storagePointer() 
1335         ASSERT(hasStoragePointer()); 
1336         return reinterpret_cast<void*>(m_opInfo
); 
1339     bool hasTransition() 
1343         case AllocatePropertyStorage
: 
1344         case ReallocatePropertyStorage
: 
1351     Transition
* transition() 
1353         ASSERT(hasTransition()); 
1354         return reinterpret_cast<Transition
*>(m_opInfo
); 
1357     bool hasStructureSet() 
1360         case CheckStructure
: 
1361         case CheckStructureImmediate
: 
1368     StructureSet
& structureSet() 
1370         ASSERT(hasStructureSet()); 
1371         return *reinterpret_cast<StructureSet
*>(m_opInfo
); 
1377         case ArrayifyToStructure
: 
1379         case NewStringObject
: 
1386     Structure
* structure() 
1388         ASSERT(hasStructure()); 
1389         return reinterpret_cast<Structure
*>(m_opInfo
); 
1392     bool hasStorageAccessData() 
1397         case GetGetterSetterByOffset
: 
1404     StorageAccessData
& storageAccessData() 
1406         ASSERT(hasStorageAccessData()); 
1407         return *bitwise_cast
<StorageAccessData
*>(m_opInfo
); 
1410     bool hasMultiGetByOffsetData() 
1412         return op() == MultiGetByOffset
; 
1415     MultiGetByOffsetData
& multiGetByOffsetData() 
1417         ASSERT(hasMultiGetByOffsetData()); 
1418         return *reinterpret_cast<MultiGetByOffsetData
*>(m_opInfo
); 
1421     bool hasMultiPutByOffsetData() 
1423         return op() == MultiPutByOffset
; 
1426     MultiPutByOffsetData
& multiPutByOffsetData() 
1428         ASSERT(hasMultiPutByOffsetData()); 
1429         return *reinterpret_cast<MultiPutByOffsetData
*>(m_opInfo
); 
1432     bool hasObjectMaterializationData() 
1435         case MaterializeNewObject
: 
1436         case MaterializeCreateActivation
: 
1444     ObjectMaterializationData
& objectMaterializationData() 
1446         ASSERT(hasObjectMaterializationData()); 
1447         return *reinterpret_cast<ObjectMaterializationData
*>(m_opInfo
); 
1450     bool isObjectAllocation() 
1454         case MaterializeNewObject
: 
1461     bool isPhantomObjectAllocation() 
1464         case PhantomNewObject
: 
1471     bool isActivationAllocation() 
1474         case CreateActivation
: 
1475         case MaterializeCreateActivation
: 
1482     bool isPhantomActivationAllocation() 
1485         case PhantomCreateActivation
: 
1492     bool isFunctionAllocation() 
1502     bool isPhantomFunctionAllocation() 
1505         case PhantomNewFunction
: 
1512     bool isPhantomAllocation() 
1515         case PhantomNewObject
: 
1516         case PhantomDirectArguments
: 
1517         case PhantomClonedArguments
: 
1518         case PhantomNewFunction
: 
1519         case PhantomCreateActivation
: 
1529         case GetIndexedPropertyStorage
: 
1530         case GetArrayLength
: 
1531         case PutByValDirect
: 
1536         case StringCharCodeAt
: 
1539         case ArrayifyToStructure
: 
1542         case HasIndexedProperty
: 
1549     ArrayMode 
arrayMode() 
1551         ASSERT(hasArrayMode()); 
1552         if (op() == ArrayifyToStructure
) 
1553             return ArrayMode::fromWord(m_opInfo2
); 
1554         return ArrayMode::fromWord(m_opInfo
); 
1557     bool setArrayMode(ArrayMode arrayMode
) 
1559         ASSERT(hasArrayMode()); 
1560         if (this->arrayMode() == arrayMode
) 
1562         m_opInfo 
= arrayMode
.asWord(); 
1575         case UInt32ToNumber
: 
1583     Arith::Mode 
arithMode() 
1585         ASSERT(hasArithMode()); 
1586         return static_cast<Arith::Mode
>(m_opInfo
); 
1589     void setArithMode(Arith::Mode mode
) 
1594     bool hasArithRoundingMode() 
1596         return op() == ArithRound
; 
1599     Arith::RoundingMode 
arithRoundingMode() 
1601         ASSERT(hasArithRoundingMode()); 
1602         return static_cast<Arith::RoundingMode
>(m_opInfo
); 
1605     void setArithRoundingMode(Arith::RoundingMode mode
) 
1607         ASSERT(hasArithRoundingMode()); 
1608         m_opInfo 
= static_cast<uintptr_t>(mode
); 
1611     bool hasVirtualRegister() 
1613         return m_virtualRegister
.isValid(); 
1616     VirtualRegister 
virtualRegister() 
1618         ASSERT(hasResult()); 
1619         ASSERT(m_virtualRegister
.isValid()); 
1620         return m_virtualRegister
; 
1623     void setVirtualRegister(VirtualRegister virtualRegister
) 
1625         ASSERT(hasResult()); 
1626         ASSERT(!m_virtualRegister
.isValid()); 
1627         m_virtualRegister 
= virtualRegister
; 
1630     bool hasExecutionCounter() 
1632         return op() == CountExecution
; 
1635     Profiler::ExecutionCounter
* executionCounter() 
1637         return bitwise_cast
<Profiler::ExecutionCounter
*>(m_opInfo
); 
1640     bool shouldGenerate() 
1645     bool isSemanticallySkippable() 
1647         return op() == CountExecution
; 
1655     unsigned postfixRef() 
1657         return m_refCount
++; 
1660     unsigned adjustedRefCount() 
1662         return mustGenerate() ? m_refCount 
- 1 : m_refCount
; 
1665     void setRefCount(unsigned refCount
) 
1667         m_refCount 
= refCount
; 
1672         ASSERT(!(m_flags 
& NodeHasVarArgs
)); 
1673         return children
.child1(); 
1676     // This is useful if you want to do a fast check on the first child 
1677     // before also doing a check on the opcode. Use this with care and 
1678     // avoid it if possible. 
1679     Edge 
child1Unchecked() 
1681         return children
.child1Unchecked(); 
1686         ASSERT(!(m_flags 
& NodeHasVarArgs
)); 
1687         return children
.child2(); 
1692         ASSERT(!(m_flags 
& NodeHasVarArgs
)); 
1693         return children
.child3(); 
1696     unsigned firstChild() 
1698         ASSERT(m_flags 
& NodeHasVarArgs
); 
1699         return children
.firstChild(); 
1702     unsigned numChildren() 
1704         ASSERT(m_flags 
& NodeHasVarArgs
); 
1705         return children
.numChildren(); 
1708     UseKind 
binaryUseKind() 
1710         ASSERT(child1().useKind() == child2().useKind()); 
1711         return child1().useKind(); 
1714     bool isBinaryUseKind(UseKind left
, UseKind right
) 
1716         return child1().useKind() == left 
&& child2().useKind() == right
; 
1719     bool isBinaryUseKind(UseKind useKind
) 
1721         return isBinaryUseKind(useKind
, useKind
); 
1724     Edge 
childFor(UseKind useKind
) 
1726         if (child1().useKind() == useKind
) 
1728         if (child2().useKind() == useKind
) 
1730         if (child3().useKind() == useKind
) 
1735     SpeculatedType 
prediction() 
1737         return m_prediction
; 
1740     bool predict(SpeculatedType prediction
) 
1742         return mergeSpeculation(m_prediction
, prediction
); 
1745     bool shouldSpeculateInt32() 
1747         return isInt32Speculation(prediction()); 
1752         return !!(prediction() & SpecBoolean
); 
1755     bool shouldSpeculateInt32OrBoolean() 
1757         return isInt32OrBooleanSpeculation(prediction()); 
1760     bool shouldSpeculateInt32ForArithmetic() 
1762         return isInt32SpeculationForArithmetic(prediction()); 
1765     bool shouldSpeculateInt32OrBooleanForArithmetic() 
1767         return isInt32OrBooleanSpeculationForArithmetic(prediction()); 
1770     bool shouldSpeculateInt32OrBooleanExpectingDefined() 
1772         return isInt32OrBooleanSpeculationExpectingDefined(prediction()); 
1775     bool shouldSpeculateMachineInt() 
1777         return isMachineIntSpeculation(prediction()); 
1780     bool shouldSpeculateDouble() 
1782         return isDoubleSpeculation(prediction()); 
1785     bool shouldSpeculateDoubleReal() 
1787         return isDoubleRealSpeculation(prediction()); 
1790     bool shouldSpeculateNumber() 
1792         return isFullNumberSpeculation(prediction()); 
1795     bool shouldSpeculateNumberOrBoolean() 
1797         return isFullNumberOrBooleanSpeculation(prediction()); 
1800     bool shouldSpeculateNumberOrBooleanExpectingDefined() 
1802         return isFullNumberOrBooleanSpeculationExpectingDefined(prediction()); 
1805     bool shouldSpeculateBoolean() 
1807         return isBooleanSpeculation(prediction()); 
1810     bool shouldSpeculateOther() 
1812         return isOtherSpeculation(prediction()); 
1815     bool shouldSpeculateMisc() 
1817         return isMiscSpeculation(prediction()); 
1820     bool shouldSpeculateStringIdent() 
1822         return isStringIdentSpeculation(prediction()); 
1825     bool shouldSpeculateNotStringVar() 
1827         return isNotStringVarSpeculation(prediction()); 
1830     bool shouldSpeculateString() 
1832         return isStringSpeculation(prediction()); 
1835     bool shouldSpeculateStringObject() 
1837         return isStringObjectSpeculation(prediction()); 
1840     bool shouldSpeculateStringOrStringObject() 
1842         return isStringOrStringObjectSpeculation(prediction()); 
1845     bool shouldSpeculateFinalObject() 
1847         return isFinalObjectSpeculation(prediction()); 
1850     bool shouldSpeculateFinalObjectOrOther() 
1852         return isFinalObjectOrOtherSpeculation(prediction()); 
1855     bool shouldSpeculateArray() 
1857         return isArraySpeculation(prediction()); 
1860     bool shouldSpeculateDirectArguments() 
1862         return isDirectArgumentsSpeculation(prediction()); 
1865     bool shouldSpeculateScopedArguments() 
1867         return isScopedArgumentsSpeculation(prediction()); 
1870     bool shouldSpeculateInt8Array() 
1872         return isInt8ArraySpeculation(prediction()); 
1875     bool shouldSpeculateInt16Array() 
1877         return isInt16ArraySpeculation(prediction()); 
1880     bool shouldSpeculateInt32Array() 
1882         return isInt32ArraySpeculation(prediction()); 
1885     bool shouldSpeculateUint8Array() 
1887         return isUint8ArraySpeculation(prediction()); 
1890     bool shouldSpeculateUint8ClampedArray() 
1892         return isUint8ClampedArraySpeculation(prediction()); 
1895     bool shouldSpeculateUint16Array() 
1897         return isUint16ArraySpeculation(prediction()); 
1900     bool shouldSpeculateUint32Array() 
1902         return isUint32ArraySpeculation(prediction()); 
1905     bool shouldSpeculateFloat32Array() 
1907         return isFloat32ArraySpeculation(prediction()); 
1910     bool shouldSpeculateFloat64Array() 
1912         return isFloat64ArraySpeculation(prediction()); 
1915     bool shouldSpeculateArrayOrOther() 
1917         return isArrayOrOtherSpeculation(prediction()); 
1920     bool shouldSpeculateObject() 
1922         return isObjectSpeculation(prediction()); 
1925     bool shouldSpeculateObjectOrOther() 
1927         return isObjectOrOtherSpeculation(prediction()); 
1930     bool shouldSpeculateCell() 
1932         return isCellSpeculation(prediction()); 
1935     bool shouldSpeculateNotCell() 
1937         return isNotCellSpeculation(prediction()); 
1940     static bool shouldSpeculateBoolean(Node
* op1
, Node
* op2
) 
1942         return op1
->shouldSpeculateBoolean() && op2
->shouldSpeculateBoolean(); 
1945     static bool shouldSpeculateInt32(Node
* op1
, Node
* op2
) 
1947         return op1
->shouldSpeculateInt32() && op2
->shouldSpeculateInt32(); 
1950     static bool shouldSpeculateInt32OrBoolean(Node
* op1
, Node
* op2
) 
1952         return op1
->shouldSpeculateInt32OrBoolean() 
1953             && op2
->shouldSpeculateInt32OrBoolean(); 
1956     static bool shouldSpeculateInt32OrBooleanForArithmetic(Node
* op1
, Node
* op2
) 
1958         return op1
->shouldSpeculateInt32OrBooleanForArithmetic() 
1959             && op2
->shouldSpeculateInt32OrBooleanForArithmetic(); 
1962     static bool shouldSpeculateInt32OrBooleanExpectingDefined(Node
* op1
, Node
* op2
) 
1964         return op1
->shouldSpeculateInt32OrBooleanExpectingDefined() 
1965             && op2
->shouldSpeculateInt32OrBooleanExpectingDefined(); 
1968     static bool shouldSpeculateMachineInt(Node
* op1
, Node
* op2
) 
1970         return op1
->shouldSpeculateMachineInt() && op2
->shouldSpeculateMachineInt(); 
1973     static bool shouldSpeculateNumber(Node
* op1
, Node
* op2
) 
1975         return op1
->shouldSpeculateNumber() && op2
->shouldSpeculateNumber(); 
1978     static bool shouldSpeculateNumberOrBoolean(Node
* op1
, Node
* op2
) 
1980         return op1
->shouldSpeculateNumberOrBoolean() 
1981             && op2
->shouldSpeculateNumberOrBoolean(); 
1984     static bool shouldSpeculateNumberOrBooleanExpectingDefined(Node
* op1
, Node
* op2
) 
1986         return op1
->shouldSpeculateNumberOrBooleanExpectingDefined() 
1987             && op2
->shouldSpeculateNumberOrBooleanExpectingDefined(); 
1990     static bool shouldSpeculateFinalObject(Node
* op1
, Node
* op2
) 
1992         return op1
->shouldSpeculateFinalObject() && op2
->shouldSpeculateFinalObject(); 
1995     static bool shouldSpeculateArray(Node
* op1
, Node
* op2
) 
1997         return op1
->shouldSpeculateArray() && op2
->shouldSpeculateArray(); 
2000     bool canSpeculateInt32(RareCaseProfilingSource source
) 
2002         return nodeCanSpeculateInt32(arithNodeFlags(), source
); 
2005     bool canSpeculateInt52(RareCaseProfilingSource source
) 
2007         return nodeCanSpeculateInt52(arithNodeFlags(), source
); 
2010     RareCaseProfilingSource 
sourceFor(PredictionPass pass
) 
2012         if (pass 
== PrimaryPass 
|| child1()->sawBooleans() || (child2() && child2()->sawBooleans())) 
2014         return AllRareCases
; 
2017     bool canSpeculateInt32(PredictionPass pass
) 
2019         return canSpeculateInt32(sourceFor(pass
)); 
2022     bool canSpeculateInt52(PredictionPass pass
) 
2024         return canSpeculateInt52(sourceFor(pass
)); 
2027     bool hasTypeLocation() 
2029         return op() == ProfileType
; 
2032     TypeLocation
* typeLocation() 
2034         ASSERT(hasTypeLocation()); 
2035         return reinterpret_cast<TypeLocation
*>(m_opInfo
); 
2038     bool hasBasicBlockLocation() 
2040         return op() == ProfileControlFlow
; 
2043     BasicBlockLocation
* basicBlockLocation() 
2045         ASSERT(hasBasicBlockLocation()); 
2046         return reinterpret_cast<BasicBlockLocation
*>(m_opInfo
); 
2049     Node
* replacement() const 
2051         return m_misc
.replacement
; 
2054     void setReplacement(Node
* replacement
) 
2056         m_misc
.replacement 
= replacement
; 
2061         return Epoch::fromUnsigned(m_misc
.epoch
); 
2064     void setEpoch(Epoch epoch
) 
2066         m_misc
.epoch 
= epoch
.toUnsigned(); 
2069     void dumpChildren(PrintStream
& out
) 
2073         out
.printf("@%u", child1()->index()); 
2076         out
.printf(", @%u", child2()->index()); 
2079         out
.printf(", @%u", child3()->index()); 
2082     // NB. This class must have a trivial destructor. 
2086     // References to up to 3 children, or links to a variable length set of children. 
2087     AdjacencyList children
; 
2090     unsigned m_op 
: 10; // real type is NodeType 
2091     unsigned m_flags 
: 22; 
2092     // The virtual register number (spill location) associated with this . 
2093     VirtualRegister m_virtualRegister
; 
2094     // The number of uses of the result of this operation (+1 for 'must generate' nodes, which have side-effects). 
2095     unsigned m_refCount
; 
2096     // The prediction ascribed to this node after propagation. 
2097     SpeculatedType m_prediction
; 
2098     // Immediate values, accesses type-checked via accessors above. The first one is 
2099     // big enough to store a pointer. 
2101     uintptr_t m_opInfo2
; 
2104     // Fields used by various analyses. 
2105     AbstractValue value
; 
2107     // Miscellaneous data that is usually meaningless, but can hold some analysis results 
2108     // if you ask right. For example, if you do Graph::initializeNodeOwners(), Node::owner 
2109     // will tell you which basic block a node belongs to. You cannot rely on this persisting 
2110     // across transformations unless you do the maintenance work yourself. Other phases use 
2111     // Node::replacement, but they do so manually: first you do Graph::clearReplacements() 
2112     // and then you set, and use, replacement's yourself. Same thing for epoch. 
2114     // Bottom line: don't use these fields unless you initialize them yourself, or by 
2115     // calling some appropriate methods that initialize them the way you want. Otherwise, 
2116     // these fields are meaningless. 
2126 inline bool nodeComparator(Node
* a
, Node
* b
) 
2128     return a
->index() < b
->index(); 
2131 template<typename T
> 
2132 CString 
nodeListDump(const T
& nodeList
) 
2134     return sortedListDump(nodeList
, nodeComparator
); 
2137 template<typename T
> 
2138 CString 
nodeMapDump(const T
& nodeMap
, DumpContext
* context 
= 0) 
2140     Vector
<typename 
T::KeyType
> keys
; 
2142         typename 
T::const_iterator iter 
= nodeMap
.begin(); 
2143         iter 
!= nodeMap
.end(); ++iter
) 
2144         keys
.append(iter
->key
); 
2145     std::sort(keys
.begin(), keys
.end(), nodeComparator
); 
2146     StringPrintStream out
; 
2148     for(unsigned i 
= 0; i 
< keys
.size(); ++i
) 
2149         out
.print(comma
, keys
[i
], "=>", inContext(nodeMap
.get(keys
[i
]), context
)); 
2150     return out
.toCString(); 
2153 } } // namespace JSC::DFG 
2157 void printInternal(PrintStream
&, JSC::DFG::SwitchKind
); 
2158 void printInternal(PrintStream
&, JSC::DFG::Node
*); 
2160 inline JSC::DFG::Node
* inContext(JSC::DFG::Node
* node
, JSC::DumpContext
*) { return node
; } 
2164 using WTF::inContext
;