2  * Copyright (C) 2011, 2012, 2013 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.  
  29 #include <wtf/Platform.h> 
  33 #include "CodeBlock.h" 
  34 #include "CodeOrigin.h" 
  35 #include "DFGAbstractValue.h" 
  36 #include "DFGAdjacencyList.h" 
  37 #include "DFGArrayMode.h" 
  38 #include "DFGCommon.h" 
  39 #include "DFGNodeFlags.h" 
  40 #include "DFGNodeType.h" 
  41 #include "DFGVariableAccessData.h" 
  42 #include "JSCJSValue.h" 
  44 #include "SpeculatedType.h" 
  45 #include "StructureSet.h" 
  46 #include "ValueProfile.h" 
  48 namespace JSC 
{ namespace DFG 
{ 
  50 struct StructureTransitionData 
{ 
  51     Structure
* previousStructure
; 
  52     Structure
* newStructure
; 
  54     StructureTransitionData() { } 
  56     StructureTransitionData(Structure
* previousStructure
, Structure
* newStructure
) 
  57         : previousStructure(previousStructure
) 
  58         , newStructure(newStructure
) 
  63 struct NewArrayBufferData 
{ 
  64     unsigned startConstant
; 
  65     unsigned numConstants
; 
  66     IndexingType indexingType
; 
  69 // This type used in passing an immediate argument to Node constructor; 
  70 // distinguishes an immediate value (typically an index into a CodeBlock data structure -  
  71 // a constant index, argument, or identifier) from a Node*. 
  73     explicit OpInfo(int32_t value
) : m_value(static_cast<uintptr_t>(value
)) { } 
  74     explicit OpInfo(uint32_t value
) : m_value(static_cast<uintptr_t>(value
)) { } 
  75 #if OS(DARWIN) || USE(JSVALUE64) 
  76     explicit OpInfo(size_t value
) : m_value(static_cast<uintptr_t>(value
)) { } 
  78     explicit OpInfo(void* value
) : m_value(reinterpret_cast<uintptr_t>(value
)) { } 
  84 // Node represents a single operation in the data flow graph. 
  86     enum VarArgTag 
{ VarArg 
}; 
  90     Node(NodeType op
, CodeOrigin codeOrigin
, const AdjacencyList
& children
) 
  91         : codeOrigin(codeOrigin
) 
  93         , m_virtualRegister(InvalidVirtualRegister
) 
  95         , m_prediction(SpecNone
) 
  97         setOpAndDefaultFlags(op
); 
 100     // Construct a node with up to 3 children, no immediate value. 
 101     Node(NodeType op
, CodeOrigin codeOrigin
, Edge child1 
= Edge(), Edge child2 
= Edge(), Edge child3 
= Edge()) 
 102         : codeOrigin(codeOrigin
) 
 103         , children(AdjacencyList::Fixed
, child1
, child2
, child3
) 
 104         , m_virtualRegister(InvalidVirtualRegister
) 
 106         , m_prediction(SpecNone
) 
 108         setOpAndDefaultFlags(op
); 
 109         ASSERT(!(m_flags 
& NodeHasVarArgs
)); 
 112     // Construct a node with up to 3 children and an immediate value. 
 113     Node(NodeType op
, CodeOrigin codeOrigin
, OpInfo imm
, Edge child1 
= Edge(), Edge child2 
= Edge(), Edge child3 
= Edge()) 
 114         : codeOrigin(codeOrigin
) 
 115         , children(AdjacencyList::Fixed
, child1
, child2
, child3
) 
 116         , m_virtualRegister(InvalidVirtualRegister
) 
 118         , m_opInfo(imm
.m_value
) 
 119         , m_prediction(SpecNone
) 
 121         setOpAndDefaultFlags(op
); 
 122         ASSERT(!(m_flags 
& NodeHasVarArgs
)); 
 125     // Construct a node with up to 3 children and two immediate values. 
 126     Node(NodeType op
, CodeOrigin codeOrigin
, OpInfo imm1
, OpInfo imm2
, Edge child1 
= Edge(), Edge child2 
= Edge(), Edge child3 
= Edge()) 
 127         : codeOrigin(codeOrigin
) 
 128         , children(AdjacencyList::Fixed
, child1
, child2
, child3
) 
 129         , m_virtualRegister(InvalidVirtualRegister
) 
 131         , m_opInfo(imm1
.m_value
) 
 132         , m_opInfo2(safeCast
<unsigned>(imm2
.m_value
)) 
 133         , m_prediction(SpecNone
) 
 135         setOpAndDefaultFlags(op
); 
 136         ASSERT(!(m_flags 
& NodeHasVarArgs
)); 
 139     // Construct a node with a variable number of children and two immediate values. 
 140     Node(VarArgTag
, NodeType op
, CodeOrigin codeOrigin
, OpInfo imm1
, OpInfo imm2
, unsigned firstChild
, unsigned numChildren
) 
 141         : codeOrigin(codeOrigin
) 
 142         , children(AdjacencyList::Variable
, firstChild
, numChildren
) 
 143         , m_virtualRegister(InvalidVirtualRegister
) 
 145         , m_opInfo(imm1
.m_value
) 
 146         , m_opInfo2(safeCast
<unsigned>(imm2
.m_value
)) 
 147         , m_prediction(SpecNone
) 
 149         setOpAndDefaultFlags(op
); 
 150         ASSERT(m_flags 
& NodeHasVarArgs
); 
 153     NodeType 
op() const { return static_cast<NodeType
>(m_op
); } 
 154     NodeFlags 
flags() const { return m_flags
; } 
 156     // This is not a fast method. 
 157     unsigned index() const; 
 159     void setOp(NodeType op
) 
 164     void setFlags(NodeFlags flags
) 
 169     bool mergeFlags(NodeFlags flags
) 
 171         ASSERT(!(flags 
& NodeDoesNotExit
)); 
 172         NodeFlags newFlags 
= m_flags 
| flags
; 
 173         if (newFlags 
== m_flags
) 
 179     bool filterFlags(NodeFlags flags
) 
 181         ASSERT(flags 
& NodeDoesNotExit
); 
 182         NodeFlags newFlags 
= m_flags 
& flags
; 
 183         if (newFlags 
== m_flags
) 
 189     bool clearFlags(NodeFlags flags
) 
 191         return filterFlags(~flags
); 
 194     void setOpAndDefaultFlags(NodeType op
) 
 197         m_flags 
= defaultFlags(op
); 
 200     void setOpAndDefaultNonExitFlags(NodeType op
) 
 202         ASSERT(!(m_flags 
& NodeHasVarArgs
)); 
 203         setOpAndDefaultNonExitFlagsUnchecked(op
); 
 206     void setOpAndDefaultNonExitFlagsUnchecked(NodeType op
) 
 209         m_flags 
= (defaultFlags(op
) & ~NodeExitsForward
) | (m_flags 
& NodeExitsForward
); 
 212     void convertToPhantom() 
 214         setOpAndDefaultNonExitFlags(Phantom
); 
 217     void convertToPhantomUnchecked() 
 219         setOpAndDefaultNonExitFlagsUnchecked(Phantom
); 
 222     void convertToIdentity() 
 224         RELEASE_ASSERT(child1()); 
 225         RELEASE_ASSERT(!child2()); 
 226         setOpAndDefaultNonExitFlags(Identity
); 
 231         return m_flags 
& NodeMustGenerate
; 
 234     void setCanExit(bool exits
) 
 237             m_flags 
&= ~NodeDoesNotExit
; 
 239             m_flags 
|= NodeDoesNotExit
; 
 244         return !(m_flags 
& NodeDoesNotExit
); 
 249         return op() == JSConstant
; 
 252     bool isWeakConstant() 
 254         return op() == WeakJSConstant
; 
 257     bool isStronglyProvedConstantIn(InlineCallFrame
* inlineCallFrame
) 
 259         return isConstant() && codeOrigin
.inlineCallFrame 
== inlineCallFrame
; 
 262     bool isStronglyProvedConstantIn(const CodeOrigin
& codeOrigin
) 
 264         return isStronglyProvedConstantIn(codeOrigin
.inlineCallFrame
); 
 267     bool isPhantomArguments() 
 269         return op() == PhantomArguments
; 
 277         case PhantomArguments
: 
 284     unsigned constantNumber() 
 286         ASSERT(isConstant()); 
 290     void convertToConstant(unsigned constantNumber
) 
 293         m_flags 
&= ~(NodeMustGenerate 
| NodeMightClobber 
| NodeClobbersWorld
); 
 294         m_opInfo 
= constantNumber
; 
 298     void convertToWeakConstant(JSCell
* cell
) 
 300         m_op 
= WeakJSConstant
; 
 301         m_flags 
&= ~(NodeMustGenerate 
| NodeMightClobber 
| NodeClobbersWorld
); 
 302         m_opInfo 
= bitwise_cast
<uintptr_t>(cell
); 
 306     void convertToGetLocalUnlinked(VirtualRegister local
) 
 308         m_op 
= GetLocalUnlinked
; 
 309         m_flags 
&= ~(NodeMustGenerate 
| NodeMightClobber 
| NodeClobbersWorld
); 
 314     void convertToStructureTransitionWatchpoint(Structure
* structure
) 
 316         ASSERT(m_op 
== CheckStructure 
|| m_op 
== ForwardCheckStructure 
|| m_op 
== ArrayifyToStructure
); 
 317         m_opInfo 
= bitwise_cast
<uintptr_t>(structure
); 
 318         if (m_op 
== CheckStructure 
|| m_op 
== ArrayifyToStructure
) 
 319             m_op 
= StructureTransitionWatchpoint
; 
 321             m_op 
= ForwardStructureTransitionWatchpoint
; 
 324     void convertToStructureTransitionWatchpoint() 
 326         convertToStructureTransitionWatchpoint(structureSet().singletonStructure()); 
 329     void convertToGetByOffset(unsigned storageAccessDataIndex
, Edge storage
) 
 331         ASSERT(m_op 
== GetById 
|| m_op 
== GetByIdFlush
); 
 332         m_opInfo 
= storageAccessDataIndex
; 
 333         children
.setChild1(storage
); 
 335         m_flags 
&= ~NodeClobbersWorld
; 
 338     void convertToPutByOffset(unsigned storageAccessDataIndex
, Edge storage
) 
 340         ASSERT(m_op 
== PutById 
|| m_op 
== PutByIdDirect
); 
 341         m_opInfo 
= storageAccessDataIndex
; 
 342         children
.setChild3(children
.child2()); 
 343         children
.setChild2(children
.child1()); 
 344         children
.setChild1(storage
); 
 346         m_flags 
&= ~NodeClobbersWorld
; 
 349     void convertToPhantomLocal() 
 351         ASSERT(m_op 
== Phantom 
&& (child1()->op() == Phi 
|| child1()->op() == SetLocal 
|| child1()->op() == SetArgument
)); 
 353         m_opInfo 
= child1()->m_opInfo
; // Copy the variableAccessData. 
 354         children
.setChild1(Edge()); 
 357     void convertToGetLocal(VariableAccessData
* variable
, Node
* phi
) 
 359         ASSERT(m_op 
== GetLocalUnlinked
); 
 361         m_opInfo 
= bitwise_cast
<uintptr_t>(variable
); 
 362         children
.setChild1(Edge(phi
)); 
 365     void convertToToString() 
 367         ASSERT(m_op 
== ToPrimitive
); 
 371     JSCell
* weakConstant() 
 373         ASSERT(op() == WeakJSConstant
); 
 374         return bitwise_cast
<JSCell
*>(m_opInfo
); 
 377     JSValue 
valueOfJSConstant(CodeBlock
* codeBlock
) 
 381             return JSValue(weakConstant()); 
 383             return codeBlock
->constantRegister(FirstConstantRegisterIndex 
+ constantNumber()).get(); 
 384         case PhantomArguments
: 
 387             RELEASE_ASSERT_NOT_REACHED(); 
 388             return JSValue(); // Have to return something in release mode. 
 392     bool isInt32Constant(CodeBlock
* codeBlock
) 
 394         return isConstant() && valueOfJSConstant(codeBlock
).isInt32(); 
 397     bool isDoubleConstant(CodeBlock
* codeBlock
) 
 399         bool result 
= isConstant() && valueOfJSConstant(codeBlock
).isDouble(); 
 401             ASSERT(!isInt32Constant(codeBlock
)); 
 405     bool isNumberConstant(CodeBlock
* codeBlock
) 
 407         bool result 
= isConstant() && valueOfJSConstant(codeBlock
).isNumber(); 
 408         ASSERT(result 
== (isInt32Constant(codeBlock
) || isDoubleConstant(codeBlock
))); 
 412     bool isBooleanConstant(CodeBlock
* codeBlock
) 
 414         return isConstant() && valueOfJSConstant(codeBlock
).isBoolean(); 
 417     bool containsMovHint() 
 422         case MovHintAndCheck
: 
 430     bool hasVariableAccessData() 
 436         case MovHintAndCheck
: 
 450         return hasVariableAccessData(); 
 453     VariableAccessData
* variableAccessData() 
 455         ASSERT(hasVariableAccessData()); 
 456         return reinterpret_cast<VariableAccessData
*>(m_opInfo
)->find(); 
 459     VirtualRegister 
local() 
 461         return variableAccessData()->local(); 
 464     VirtualRegister 
unlinkedLocal() 
 466         ASSERT(op() == GetLocalUnlinked
); 
 467         return static_cast<VirtualRegister
>(m_opInfo
); 
 483     unsigned identifierNumber() 
 485         ASSERT(hasIdentifier()); 
 489     unsigned resolveGlobalDataIndex() 
 491         ASSERT(op() == ResolveGlobal
); 
 495     unsigned resolveOperationsDataIndex() 
 497         ASSERT(op() == Resolve 
|| op() == ResolveBase 
|| op() == ResolveBaseStrictPut
); 
 501     bool hasArithNodeFlags() 
 521     // This corrects the arithmetic node flags, so that irrelevant bits are 
 522     // ignored. In particular, anything other than ArithMul does not need 
 523     // to know if it can speculate on negative zero. 
 524     NodeFlags 
arithNodeFlags() 
 526         NodeFlags result 
= m_flags 
& NodeArithFlagsMask
; 
 527         if (op() == ArithMul 
|| op() == ArithDiv 
|| op() == ArithMod 
|| op() == ArithNegate 
|| op() == DoubleAsInt32
) 
 529         return result 
& ~NodeNeedsNegZero
; 
 532     bool hasConstantBuffer() 
 534         return op() == NewArrayBuffer
; 
 537     NewArrayBufferData
* newArrayBufferData() 
 539         ASSERT(hasConstantBuffer()); 
 540         return reinterpret_cast<NewArrayBufferData
*>(m_opInfo
); 
 543     unsigned startConstant() 
 545         return newArrayBufferData()->startConstant
; 
 548     unsigned numConstants() 
 550         return newArrayBufferData()->numConstants
; 
 553     bool hasIndexingType() 
 557         case NewArrayWithSize
: 
 565     IndexingType 
indexingType() 
 567         ASSERT(hasIndexingType()); 
 568         if (op() == NewArrayBuffer
) 
 569             return newArrayBufferData()->indexingType
; 
 573     bool hasInlineCapacity() 
 575         return op() == CreateThis
; 
 578     unsigned inlineCapacity() 
 580         ASSERT(hasInlineCapacity()); 
 584     void setIndexingType(IndexingType indexingType
) 
 586         ASSERT(hasIndexingType()); 
 587         m_opInfo 
= indexingType
; 
 590     bool hasRegexpIndex() 
 592         return op() == NewRegexp
; 
 595     unsigned regexpIndex() 
 597         ASSERT(hasRegexpIndex()); 
 603         return op() == GetScopedVar 
|| op() == PutScopedVar
; 
 608         ASSERT(hasVarNumber()); 
 612     bool hasIdentifierNumberForCheck() 
 614         return op() == GlobalVarWatchpoint 
|| op() == PutGlobalVarCheck
; 
 617     unsigned identifierNumberForCheck() 
 619         ASSERT(hasIdentifierNumberForCheck()); 
 623     bool hasRegisterPointer() 
 625         return op() == GetGlobalVar 
|| op() == PutGlobalVar 
|| op() == GlobalVarWatchpoint 
|| op() == PutGlobalVarCheck
; 
 628     WriteBarrier
<Unknown
>* registerPointer() 
 630         return bitwise_cast
<WriteBarrier
<Unknown
>*>(m_opInfo
); 
 635         return m_flags 
& NodeResultMask
; 
 638     bool hasInt32Result() 
 640         return (m_flags 
& NodeResultMask
) == NodeResultInt32
; 
 643     bool hasNumberResult() 
 645         return (m_flags 
& NodeResultMask
) == NodeResultNumber
; 
 650         return (m_flags 
& NodeResultMask
) == NodeResultJS
; 
 653     bool hasBooleanResult() 
 655         return (m_flags 
& NodeResultMask
) == NodeResultBoolean
; 
 658     bool hasStorageResult() 
 660         return (m_flags 
& NodeResultMask
) == NodeResultStorage
; 
 670         return op() == Branch
; 
 680         case ThrowReferenceError
: 
 687     unsigned takenBytecodeOffsetDuringParsing() 
 689         ASSERT(isBranch() || isJump()); 
 693     unsigned notTakenBytecodeOffsetDuringParsing() 
 699     void setTakenBlockIndex(BlockIndex blockIndex
) 
 701         ASSERT(isBranch() || isJump()); 
 702         m_opInfo 
= blockIndex
; 
 705     void setNotTakenBlockIndex(BlockIndex blockIndex
) 
 708         m_opInfo2 
= blockIndex
; 
 711     BlockIndex 
takenBlockIndex() 
 713         ASSERT(isBranch() || isJump()); 
 717     BlockIndex 
notTakenBlockIndex() 
 723     unsigned numSuccessors() 
 735     BlockIndex 
successor(unsigned index
) 
 739             return takenBlockIndex(); 
 741             return notTakenBlockIndex(); 
 743             RELEASE_ASSERT_NOT_REACHED(); 
 748     BlockIndex 
successorForCondition(bool condition
) 
 751         return condition 
? takenBlockIndex() : notTakenBlockIndex(); 
 754     bool hasHeapPrediction() 
 760         case GetMyArgumentByVal
: 
 761         case GetMyArgumentByValSafe
: 
 768         case ResolveBaseStrictPut
: 
 781     SpeculatedType 
getHeapPrediction() 
 783         ASSERT(hasHeapPrediction()); 
 784         return static_cast<SpeculatedType
>(m_opInfo2
); 
 787     bool predictHeap(SpeculatedType prediction
) 
 789         ASSERT(hasHeapPrediction()); 
 791         return mergeSpeculation(m_opInfo2
, prediction
); 
 798         case AllocationProfileWatchpoint
: 
 807         ASSERT(hasFunction()); 
 808         JSCell
* result 
= reinterpret_cast<JSFunction
*>(m_opInfo
); 
 809         ASSERT(JSValue(result
).isFunction()); 
 815         return op() == CheckExecutable
; 
 818     ExecutableBase
* executable() 
 820         return jsCast
<ExecutableBase
*>(reinterpret_cast<JSCell
*>(m_opInfo
)); 
 823     bool hasStructureTransitionData() 
 827         case PhantomPutStructure
: 
 828         case AllocatePropertyStorage
: 
 829         case ReallocatePropertyStorage
: 
 836     StructureTransitionData
& structureTransitionData() 
 838         ASSERT(hasStructureTransitionData()); 
 839         return *reinterpret_cast<StructureTransitionData
*>(m_opInfo
); 
 842     bool hasStructureSet() 
 846         case ForwardCheckStructure
: 
 853     StructureSet
& structureSet() 
 855         ASSERT(hasStructureSet()); 
 856         return *reinterpret_cast<StructureSet
*>(m_opInfo
); 
 862         case StructureTransitionWatchpoint
: 
 863         case ForwardStructureTransitionWatchpoint
: 
 864         case ArrayifyToStructure
: 
 866         case NewStringObject
: 
 873     Structure
* structure() 
 875         ASSERT(hasStructure()); 
 876         return reinterpret_cast<Structure
*>(m_opInfo
); 
 879     bool hasStorageAccessData() 
 881         return op() == GetByOffset 
|| op() == PutByOffset
; 
 884     unsigned storageAccessDataIndex() 
 886         ASSERT(hasStorageAccessData()); 
 890     bool hasFunctionDeclIndex() 
 892         return op() == NewFunction
 
 893             || op() == NewFunctionNoCheck
; 
 896     unsigned functionDeclIndex() 
 898         ASSERT(hasFunctionDeclIndex()); 
 902     bool hasFunctionExprIndex() 
 904         return op() == NewFunctionExpression
; 
 907     unsigned functionExprIndex() 
 909         ASSERT(hasFunctionExprIndex()); 
 916         case GetIndexedPropertyStorage
: 
 922         case StringCharCodeAt
: 
 925         case ArrayifyToStructure
: 
 934     ArrayMode 
arrayMode() 
 936         ASSERT(hasArrayMode()); 
 937         if (op() == ArrayifyToStructure
) 
 938             return ArrayMode::fromWord(m_opInfo2
); 
 939         return ArrayMode::fromWord(m_opInfo
); 
 942     bool setArrayMode(ArrayMode arrayMode
) 
 944         ASSERT(hasArrayMode()); 
 945         if (this->arrayMode() == arrayMode
) 
 947         m_opInfo 
= arrayMode
.asWord(); 
 951     bool hasVirtualRegister() 
 953         return m_virtualRegister 
!= InvalidVirtualRegister
; 
 956     VirtualRegister 
virtualRegister() 
 959         ASSERT(m_virtualRegister 
!= InvalidVirtualRegister
); 
 960         return m_virtualRegister
; 
 963     void setVirtualRegister(VirtualRegister virtualRegister
) 
 966         ASSERT(m_virtualRegister 
== InvalidVirtualRegister
); 
 967         m_virtualRegister 
= virtualRegister
; 
 970     bool hasArgumentPositionStart() 
 972         return op() == InlineStart
; 
 975     unsigned argumentPositionStart() 
 977         ASSERT(hasArgumentPositionStart()); 
 981     bool hasExecutionCounter() 
 983         return op() == CountExecution
; 
 986     Profiler::ExecutionCounter
* executionCounter() 
 988         return bitwise_cast
<Profiler::ExecutionCounter
*>(m_opInfo
); 
 991     bool shouldGenerate() 
 996     bool willHaveCodeGenOrOSR() 
1002         case MovHintAndCheck
: 
1004         case ForwardInt32ToDouble
: 
1006         case UInt32ToNumber
: 
1008         case PhantomArguments
: 
1013             return child1().useKindUnchecked() != UntypedUse 
|| child2().useKindUnchecked() != UntypedUse 
|| child3().useKindUnchecked() != UntypedUse
; 
1015             return shouldGenerate(); 
1024     unsigned postfixRef() 
1026         return m_refCount
++; 
1029     unsigned adjustedRefCount() 
1031         return mustGenerate() ? m_refCount 
- 1 : m_refCount
; 
1034     void setRefCount(unsigned refCount
) 
1036         m_refCount 
= refCount
; 
1041         ASSERT(!(m_flags 
& NodeHasVarArgs
)); 
1042         return children
.child1(); 
1045     // This is useful if you want to do a fast check on the first child 
1046     // before also doing a check on the opcode. Use this with care and 
1047     // avoid it if possible. 
1048     Edge 
child1Unchecked() 
1050         return children
.child1Unchecked(); 
1055         ASSERT(!(m_flags 
& NodeHasVarArgs
)); 
1056         return children
.child2(); 
1061         ASSERT(!(m_flags 
& NodeHasVarArgs
)); 
1062         return children
.child3(); 
1065     unsigned firstChild() 
1067         ASSERT(m_flags 
& NodeHasVarArgs
); 
1068         return children
.firstChild(); 
1071     unsigned numChildren() 
1073         ASSERT(m_flags 
& NodeHasVarArgs
); 
1074         return children
.numChildren(); 
1077     UseKind 
binaryUseKind() 
1079         ASSERT(child1().useKind() == child2().useKind()); 
1080         return child1().useKind(); 
1083     bool isBinaryUseKind(UseKind useKind
) 
1085         return child1().useKind() == useKind 
&& child2().useKind() == useKind
; 
1088     SpeculatedType 
prediction() 
1090         return m_prediction
; 
1093     bool predict(SpeculatedType prediction
) 
1095         return mergeSpeculation(m_prediction
, prediction
); 
1098     bool shouldSpeculateInteger() 
1100         return isInt32Speculation(prediction()); 
1103     bool shouldSpeculateIntegerForArithmetic() 
1105         return isInt32SpeculationForArithmetic(prediction()); 
1108     bool shouldSpeculateIntegerExpectingDefined() 
1110         return isInt32SpeculationExpectingDefined(prediction()); 
1113     bool shouldSpeculateDouble() 
1115         return isDoubleSpeculation(prediction()); 
1118     bool shouldSpeculateDoubleForArithmetic() 
1120         return isDoubleSpeculationForArithmetic(prediction()); 
1123     bool shouldSpeculateNumber() 
1125         return isNumberSpeculation(prediction()); 
1128     bool shouldSpeculateNumberExpectingDefined() 
1130         return isNumberSpeculationExpectingDefined(prediction()); 
1133     bool shouldSpeculateBoolean() 
1135         return isBooleanSpeculation(prediction()); 
1138     bool shouldSpeculateString() 
1140         return isStringSpeculation(prediction()); 
1143     bool shouldSpeculateStringObject() 
1145         return isStringObjectSpeculation(prediction()); 
1148     bool shouldSpeculateStringOrStringObject() 
1150         return isStringOrStringObjectSpeculation(prediction()); 
1153     bool shouldSpeculateFinalObject() 
1155         return isFinalObjectSpeculation(prediction()); 
1158     bool shouldSpeculateFinalObjectOrOther() 
1160         return isFinalObjectOrOtherSpeculation(prediction()); 
1163     bool shouldSpeculateArray() 
1165         return isArraySpeculation(prediction()); 
1168     bool shouldSpeculateArguments() 
1170         return isArgumentsSpeculation(prediction()); 
1173     bool shouldSpeculateInt8Array() 
1175         return isInt8ArraySpeculation(prediction()); 
1178     bool shouldSpeculateInt16Array() 
1180         return isInt16ArraySpeculation(prediction()); 
1183     bool shouldSpeculateInt32Array() 
1185         return isInt32ArraySpeculation(prediction()); 
1188     bool shouldSpeculateUint8Array() 
1190         return isUint8ArraySpeculation(prediction()); 
1193     bool shouldSpeculateUint8ClampedArray() 
1195         return isUint8ClampedArraySpeculation(prediction()); 
1198     bool shouldSpeculateUint16Array() 
1200         return isUint16ArraySpeculation(prediction()); 
1203     bool shouldSpeculateUint32Array() 
1205         return isUint32ArraySpeculation(prediction()); 
1208     bool shouldSpeculateFloat32Array() 
1210         return isFloat32ArraySpeculation(prediction()); 
1213     bool shouldSpeculateFloat64Array() 
1215         return isFloat64ArraySpeculation(prediction()); 
1218     bool shouldSpeculateArrayOrOther() 
1220         return isArrayOrOtherSpeculation(prediction()); 
1223     bool shouldSpeculateObject() 
1225         return isObjectSpeculation(prediction()); 
1228     bool shouldSpeculateObjectOrOther() 
1230         return isObjectOrOtherSpeculation(prediction()); 
1233     bool shouldSpeculateCell() 
1235         return isCellSpeculation(prediction()); 
1238     static bool shouldSpeculateBoolean(Node
* op1
, Node
* op2
) 
1240         return op1
->shouldSpeculateBoolean() && op2
->shouldSpeculateBoolean(); 
1243     static bool shouldSpeculateInteger(Node
* op1
, Node
* op2
) 
1245         return op1
->shouldSpeculateInteger() && op2
->shouldSpeculateInteger(); 
1248     static bool shouldSpeculateIntegerForArithmetic(Node
* op1
, Node
* op2
) 
1250         return op1
->shouldSpeculateIntegerForArithmetic() && op2
->shouldSpeculateIntegerForArithmetic(); 
1253     static bool shouldSpeculateIntegerExpectingDefined(Node
* op1
, Node
* op2
) 
1255         return op1
->shouldSpeculateIntegerExpectingDefined() && op2
->shouldSpeculateIntegerExpectingDefined(); 
1258     static bool shouldSpeculateDoubleForArithmetic(Node
* op1
, Node
* op2
) 
1260         return op1
->shouldSpeculateDoubleForArithmetic() && op2
->shouldSpeculateDoubleForArithmetic(); 
1263     static bool shouldSpeculateNumber(Node
* op1
, Node
* op2
) 
1265         return op1
->shouldSpeculateNumber() && op2
->shouldSpeculateNumber(); 
1268     static bool shouldSpeculateNumberExpectingDefined(Node
* op1
, Node
* op2
) 
1270         return op1
->shouldSpeculateNumberExpectingDefined() && op2
->shouldSpeculateNumberExpectingDefined(); 
1273     static bool shouldSpeculateFinalObject(Node
* op1
, Node
* op2
) 
1275         return op1
->shouldSpeculateFinalObject() && op2
->shouldSpeculateFinalObject(); 
1278     static bool shouldSpeculateArray(Node
* op1
, Node
* op2
) 
1280         return op1
->shouldSpeculateArray() && op2
->shouldSpeculateArray(); 
1283     bool canSpeculateInteger() 
1285         return nodeCanSpeculateInteger(arithNodeFlags()); 
1288     void dumpChildren(PrintStream
& out
) 
1292         out
.printf("@%u", child1()->index()); 
1295         out
.printf(", @%u", child2()->index()); 
1298         out
.printf(", @%u", child3()->index()); 
1301     // NB. This class must have a trivial destructor. 
1303     // Used to look up exception handling information (currently implemented as a bytecode index). 
1304     CodeOrigin codeOrigin
; 
1305     // References to up to 3 children, or links to a variable length set of children. 
1306     AdjacencyList children
; 
1309     unsigned m_op 
: 10; // real type is NodeType 
1310     unsigned m_flags 
: 22; 
1311     // The virtual register number (spill location) associated with this . 
1312     VirtualRegister m_virtualRegister
; 
1313     // The number of uses of the result of this operation (+1 for 'must generate' nodes, which have side-effects). 
1314     unsigned m_refCount
; 
1315     // Immediate values, accesses type-checked via accessors above. The first one is 
1316     // big enough to store a pointer. 
1319     // The prediction ascribed to this node after propagation. 
1320     SpeculatedType m_prediction
; 
1323     // Fields used by various analyses. 
1324     AbstractValue value
; 
1328 } } // namespace JSC::DFG 
1332 void printInternal(PrintStream
&, JSC::DFG::Node
*);