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
;
686 unsigned takenBytecodeOffsetDuringParsing()
688 ASSERT(isBranch() || isJump());
692 unsigned notTakenBytecodeOffsetDuringParsing()
698 void setTakenBlockIndex(BlockIndex blockIndex
)
700 ASSERT(isBranch() || isJump());
701 m_opInfo
= blockIndex
;
704 void setNotTakenBlockIndex(BlockIndex blockIndex
)
707 m_opInfo2
= blockIndex
;
710 BlockIndex
takenBlockIndex()
712 ASSERT(isBranch() || isJump());
716 BlockIndex
notTakenBlockIndex()
722 unsigned numSuccessors()
734 BlockIndex
successor(unsigned index
)
738 return takenBlockIndex();
740 return notTakenBlockIndex();
742 RELEASE_ASSERT_NOT_REACHED();
747 BlockIndex
successorForCondition(bool condition
)
750 return condition
? takenBlockIndex() : notTakenBlockIndex();
753 bool hasHeapPrediction()
759 case GetMyArgumentByVal
:
760 case GetMyArgumentByValSafe
:
767 case ResolveBaseStrictPut
:
780 SpeculatedType
getHeapPrediction()
782 ASSERT(hasHeapPrediction());
783 return static_cast<SpeculatedType
>(m_opInfo2
);
786 bool predictHeap(SpeculatedType prediction
)
788 ASSERT(hasHeapPrediction());
790 return mergeSpeculation(m_opInfo2
, prediction
);
797 case AllocationProfileWatchpoint
:
806 ASSERT(hasFunction());
807 JSCell
* result
= reinterpret_cast<JSFunction
*>(m_opInfo
);
808 ASSERT(JSValue(result
).isFunction());
814 return op() == CheckExecutable
;
817 ExecutableBase
* executable()
819 return jsCast
<ExecutableBase
*>(reinterpret_cast<JSCell
*>(m_opInfo
));
822 bool hasStructureTransitionData()
826 case PhantomPutStructure
:
827 case AllocatePropertyStorage
:
828 case ReallocatePropertyStorage
:
835 StructureTransitionData
& structureTransitionData()
837 ASSERT(hasStructureTransitionData());
838 return *reinterpret_cast<StructureTransitionData
*>(m_opInfo
);
841 bool hasStructureSet()
845 case ForwardCheckStructure
:
852 StructureSet
& structureSet()
854 ASSERT(hasStructureSet());
855 return *reinterpret_cast<StructureSet
*>(m_opInfo
);
861 case StructureTransitionWatchpoint
:
862 case ForwardStructureTransitionWatchpoint
:
863 case ArrayifyToStructure
:
865 case NewStringObject
:
872 Structure
* structure()
874 ASSERT(hasStructure());
875 return reinterpret_cast<Structure
*>(m_opInfo
);
878 bool hasStorageAccessData()
880 return op() == GetByOffset
|| op() == PutByOffset
;
883 unsigned storageAccessDataIndex()
885 ASSERT(hasStorageAccessData());
889 bool hasFunctionDeclIndex()
891 return op() == NewFunction
892 || op() == NewFunctionNoCheck
;
895 unsigned functionDeclIndex()
897 ASSERT(hasFunctionDeclIndex());
901 bool hasFunctionExprIndex()
903 return op() == NewFunctionExpression
;
906 unsigned functionExprIndex()
908 ASSERT(hasFunctionExprIndex());
915 case GetIndexedPropertyStorage
:
921 case StringCharCodeAt
:
924 case ArrayifyToStructure
:
933 ArrayMode
arrayMode()
935 ASSERT(hasArrayMode());
936 if (op() == ArrayifyToStructure
)
937 return ArrayMode::fromWord(m_opInfo2
);
938 return ArrayMode::fromWord(m_opInfo
);
941 bool setArrayMode(ArrayMode arrayMode
)
943 ASSERT(hasArrayMode());
944 if (this->arrayMode() == arrayMode
)
946 m_opInfo
= arrayMode
.asWord();
950 bool hasVirtualRegister()
952 return m_virtualRegister
!= InvalidVirtualRegister
;
955 VirtualRegister
virtualRegister()
958 ASSERT(m_virtualRegister
!= InvalidVirtualRegister
);
959 return m_virtualRegister
;
962 void setVirtualRegister(VirtualRegister virtualRegister
)
965 ASSERT(m_virtualRegister
== InvalidVirtualRegister
);
966 m_virtualRegister
= virtualRegister
;
969 bool hasArgumentPositionStart()
971 return op() == InlineStart
;
974 unsigned argumentPositionStart()
976 ASSERT(hasArgumentPositionStart());
980 bool hasExecutionCounter()
982 return op() == CountExecution
;
985 Profiler::ExecutionCounter
* executionCounter()
987 return bitwise_cast
<Profiler::ExecutionCounter
*>(m_opInfo
);
990 bool shouldGenerate()
995 bool willHaveCodeGenOrOSR()
1001 case MovHintAndCheck
:
1003 case ForwardInt32ToDouble
:
1005 case UInt32ToNumber
:
1007 case PhantomArguments
:
1012 return child1().useKindUnchecked() != UntypedUse
|| child2().useKindUnchecked() != UntypedUse
|| child3().useKindUnchecked() != UntypedUse
;
1014 return shouldGenerate();
1023 unsigned postfixRef()
1025 return m_refCount
++;
1028 unsigned adjustedRefCount()
1030 return mustGenerate() ? m_refCount
- 1 : m_refCount
;
1033 void setRefCount(unsigned refCount
)
1035 m_refCount
= refCount
;
1040 ASSERT(!(m_flags
& NodeHasVarArgs
));
1041 return children
.child1();
1044 // This is useful if you want to do a fast check on the first child
1045 // before also doing a check on the opcode. Use this with care and
1046 // avoid it if possible.
1047 Edge
child1Unchecked()
1049 return children
.child1Unchecked();
1054 ASSERT(!(m_flags
& NodeHasVarArgs
));
1055 return children
.child2();
1060 ASSERT(!(m_flags
& NodeHasVarArgs
));
1061 return children
.child3();
1064 unsigned firstChild()
1066 ASSERT(m_flags
& NodeHasVarArgs
);
1067 return children
.firstChild();
1070 unsigned numChildren()
1072 ASSERT(m_flags
& NodeHasVarArgs
);
1073 return children
.numChildren();
1076 UseKind
binaryUseKind()
1078 ASSERT(child1().useKind() == child2().useKind());
1079 return child1().useKind();
1082 bool isBinaryUseKind(UseKind useKind
)
1084 return child1().useKind() == useKind
&& child2().useKind() == useKind
;
1087 SpeculatedType
prediction()
1089 return m_prediction
;
1092 bool predict(SpeculatedType prediction
)
1094 return mergeSpeculation(m_prediction
, prediction
);
1097 bool shouldSpeculateInteger()
1099 return isInt32Speculation(prediction());
1102 bool shouldSpeculateIntegerForArithmetic()
1104 return isInt32SpeculationForArithmetic(prediction());
1107 bool shouldSpeculateIntegerExpectingDefined()
1109 return isInt32SpeculationExpectingDefined(prediction());
1112 bool shouldSpeculateDouble()
1114 return isDoubleSpeculation(prediction());
1117 bool shouldSpeculateDoubleForArithmetic()
1119 return isDoubleSpeculationForArithmetic(prediction());
1122 bool shouldSpeculateNumber()
1124 return isNumberSpeculation(prediction());
1127 bool shouldSpeculateNumberExpectingDefined()
1129 return isNumberSpeculationExpectingDefined(prediction());
1132 bool shouldSpeculateBoolean()
1134 return isBooleanSpeculation(prediction());
1137 bool shouldSpeculateString()
1139 return isStringSpeculation(prediction());
1142 bool shouldSpeculateStringObject()
1144 return isStringObjectSpeculation(prediction());
1147 bool shouldSpeculateStringOrStringObject()
1149 return isStringOrStringObjectSpeculation(prediction());
1152 bool shouldSpeculateFinalObject()
1154 return isFinalObjectSpeculation(prediction());
1157 bool shouldSpeculateFinalObjectOrOther()
1159 return isFinalObjectOrOtherSpeculation(prediction());
1162 bool shouldSpeculateArray()
1164 return isArraySpeculation(prediction());
1167 bool shouldSpeculateArguments()
1169 return isArgumentsSpeculation(prediction());
1172 bool shouldSpeculateInt8Array()
1174 return isInt8ArraySpeculation(prediction());
1177 bool shouldSpeculateInt16Array()
1179 return isInt16ArraySpeculation(prediction());
1182 bool shouldSpeculateInt32Array()
1184 return isInt32ArraySpeculation(prediction());
1187 bool shouldSpeculateUint8Array()
1189 return isUint8ArraySpeculation(prediction());
1192 bool shouldSpeculateUint8ClampedArray()
1194 return isUint8ClampedArraySpeculation(prediction());
1197 bool shouldSpeculateUint16Array()
1199 return isUint16ArraySpeculation(prediction());
1202 bool shouldSpeculateUint32Array()
1204 return isUint32ArraySpeculation(prediction());
1207 bool shouldSpeculateFloat32Array()
1209 return isFloat32ArraySpeculation(prediction());
1212 bool shouldSpeculateFloat64Array()
1214 return isFloat64ArraySpeculation(prediction());
1217 bool shouldSpeculateArrayOrOther()
1219 return isArrayOrOtherSpeculation(prediction());
1222 bool shouldSpeculateObject()
1224 return isObjectSpeculation(prediction());
1227 bool shouldSpeculateObjectOrOther()
1229 return isObjectOrOtherSpeculation(prediction());
1232 bool shouldSpeculateCell()
1234 return isCellSpeculation(prediction());
1237 static bool shouldSpeculateBoolean(Node
* op1
, Node
* op2
)
1239 return op1
->shouldSpeculateBoolean() && op2
->shouldSpeculateBoolean();
1242 static bool shouldSpeculateInteger(Node
* op1
, Node
* op2
)
1244 return op1
->shouldSpeculateInteger() && op2
->shouldSpeculateInteger();
1247 static bool shouldSpeculateIntegerForArithmetic(Node
* op1
, Node
* op2
)
1249 return op1
->shouldSpeculateIntegerForArithmetic() && op2
->shouldSpeculateIntegerForArithmetic();
1252 static bool shouldSpeculateIntegerExpectingDefined(Node
* op1
, Node
* op2
)
1254 return op1
->shouldSpeculateIntegerExpectingDefined() && op2
->shouldSpeculateIntegerExpectingDefined();
1257 static bool shouldSpeculateDoubleForArithmetic(Node
* op1
, Node
* op2
)
1259 return op1
->shouldSpeculateDoubleForArithmetic() && op2
->shouldSpeculateDoubleForArithmetic();
1262 static bool shouldSpeculateNumber(Node
* op1
, Node
* op2
)
1264 return op1
->shouldSpeculateNumber() && op2
->shouldSpeculateNumber();
1267 static bool shouldSpeculateNumberExpectingDefined(Node
* op1
, Node
* op2
)
1269 return op1
->shouldSpeculateNumberExpectingDefined() && op2
->shouldSpeculateNumberExpectingDefined();
1272 static bool shouldSpeculateFinalObject(Node
* op1
, Node
* op2
)
1274 return op1
->shouldSpeculateFinalObject() && op2
->shouldSpeculateFinalObject();
1277 static bool shouldSpeculateArray(Node
* op1
, Node
* op2
)
1279 return op1
->shouldSpeculateArray() && op2
->shouldSpeculateArray();
1282 bool canSpeculateInteger()
1284 return nodeCanSpeculateInteger(arithNodeFlags());
1287 void dumpChildren(PrintStream
& out
)
1291 out
.printf("@%u", child1()->index());
1294 out
.printf(", @%u", child2()->index());
1297 out
.printf(", @%u", child3()->index());
1300 // NB. This class must have a trivial destructor.
1302 // Used to look up exception handling information (currently implemented as a bytecode index).
1303 CodeOrigin codeOrigin
;
1304 // References to up to 3 children, or links to a variable length set of children.
1305 AdjacencyList children
;
1308 unsigned m_op
: 10; // real type is NodeType
1309 unsigned m_flags
: 22;
1310 // The virtual register number (spill location) associated with this .
1311 VirtualRegister m_virtualRegister
;
1312 // The number of uses of the result of this operation (+1 for 'must generate' nodes, which have side-effects).
1313 unsigned m_refCount
;
1314 // Immediate values, accesses type-checked via accessors above. The first one is
1315 // big enough to store a pointer.
1318 // The prediction ascribed to this node after propagation.
1319 SpeculatedType m_prediction
;
1322 // Fields used by various analyses.
1323 AbstractValue value
;
1327 } } // namespace JSC::DFG
1331 void printInternal(PrintStream
&, JSC::DFG::Node
*);