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
*);