summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/dfg/DFGNode.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGNode.h')
-rw-r--r--Source/JavaScriptCore/dfg/DFGNode.h432
1 files changed, 100 insertions, 332 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGNode.h b/Source/JavaScriptCore/dfg/DFGNode.h
index b672b67c5..f79a93a69 100644
--- a/Source/JavaScriptCore/dfg/DFGNode.h
+++ b/Source/JavaScriptCore/dfg/DFGNode.h
@@ -32,15 +32,15 @@
#include "CodeBlock.h"
#include "CodeOrigin.h"
+#include "DFGAdjacencyList.h"
#include "DFGCommon.h"
-#include "DFGNodeReferenceBlob.h"
-#include "DFGOperands.h"
+#include "DFGNodeFlags.h"
+#include "DFGNodeType.h"
#include "DFGVariableAccessData.h"
#include "JSValue.h"
+#include "Operands.h"
#include "PredictedType.h"
#include "ValueProfile.h"
-#include <wtf/BoundsCheckedPointer.h>
-#include <wtf/Vector.h>
namespace JSC { namespace DFG {
@@ -57,240 +57,6 @@ struct StructureTransitionData {
}
};
-// Entries in the NodeType enum (below) are composed of an id, a result type (possibly none)
-// and some additional informative flags (must generate, is constant, etc).
-#define NodeResultMask 0xF
-#define NodeResultJS 0x1
-#define NodeResultNumber 0x2
-#define NodeResultInt32 0x3
-#define NodeResultBoolean 0x4
-#define NodeResultStorage 0x5
-#define NodeMustGenerate 0x10 // set on nodes that have side effects, and may not trivially be removed by DCE.
-#define NodeHasVarArgs 0x20
-#define NodeClobbersWorld 0x40
-#define NodeMightClobber 0x80
-#define NodeArithMask 0xF00
-#define NodeUseBottom 0x000
-#define NodeUsedAsNumber 0x100
-#define NodeNeedsNegZero 0x200
-#define NodeUsedAsMask 0x300
-#define NodeMayOverflow 0x400
-#define NodeMayNegZero 0x800
-#define NodeBehaviorMask 0xc00
-
-typedef uint16_t NodeFlags;
-
-static inline bool nodeUsedAsNumber(NodeFlags flags)
-{
- return !!(flags & NodeUsedAsNumber);
-}
-
-static inline bool nodeCanTruncateInteger(NodeFlags flags)
-{
- return !nodeUsedAsNumber(flags);
-}
-
-static inline bool nodeCanIgnoreNegativeZero(NodeFlags flags)
-{
- return !(flags & NodeNeedsNegZero);
-}
-
-static inline bool nodeMayOverflow(NodeFlags flags)
-{
- return !!(flags & NodeMayOverflow);
-}
-
-static inline bool nodeCanSpeculateInteger(NodeFlags flags)
-{
- if (flags & NodeMayOverflow)
- return !nodeUsedAsNumber(flags);
-
- if (flags & NodeMayNegZero)
- return nodeCanIgnoreNegativeZero(flags);
-
- return true;
-}
-
-const char* arithNodeFlagsAsString(NodeFlags);
-
-// This macro defines a set of information about all known node types, used to populate NodeId, NodeType below.
-#define FOR_EACH_DFG_OP(macro) \
- /* A constant in the CodeBlock's constant pool. */\
- macro(JSConstant, NodeResultJS) \
- \
- /* A constant not in the CodeBlock's constant pool. Uses get patched to jumps that exit the */\
- /* code block. */\
- macro(WeakJSConstant, NodeResultJS) \
- \
- /* Nodes for handling functions (both as call and as construct). */\
- macro(ConvertThis, NodeResultJS) \
- macro(CreateThis, NodeResultJS) /* Note this is not MustGenerate since we're returning it anyway. */ \
- macro(GetCallee, NodeResultJS) \
- \
- /* Nodes for local variable access. */\
- macro(GetLocal, NodeResultJS) \
- macro(SetLocal, 0) \
- macro(Phantom, NodeMustGenerate) \
- macro(Nop, 0) \
- macro(Phi, 0) \
- macro(Flush, NodeMustGenerate) \
- \
- /* Marker for arguments being set. */\
- macro(SetArgument, 0) \
- \
- /* Hint that inlining begins here. No code is generated for this node. It's only */\
- /* used for copying OSR data into inline frame data, to support reification of */\
- /* call frames of inlined functions. */\
- macro(InlineStart, 0) \
- \
- /* Nodes for bitwise operations. */\
- macro(BitAnd, NodeResultInt32) \
- macro(BitOr, NodeResultInt32) \
- macro(BitXor, NodeResultInt32) \
- macro(BitLShift, NodeResultInt32) \
- macro(BitRShift, NodeResultInt32) \
- macro(BitURShift, NodeResultInt32) \
- /* Bitwise operators call ToInt32 on their operands. */\
- macro(ValueToInt32, NodeResultInt32 | NodeMustGenerate) \
- /* Used to box the result of URShift nodes (result has range 0..2^32-1). */\
- macro(UInt32ToNumber, NodeResultNumber) \
- \
- /* Nodes for arithmetic operations. */\
- macro(ArithAdd, NodeResultNumber) \
- macro(ArithSub, NodeResultNumber) \
- macro(ArithNegate, NodeResultNumber) \
- macro(ArithMul, NodeResultNumber) \
- macro(ArithDiv, NodeResultNumber) \
- macro(ArithMod, NodeResultNumber) \
- macro(ArithAbs, NodeResultNumber) \
- macro(ArithMin, NodeResultNumber) \
- macro(ArithMax, NodeResultNumber) \
- macro(ArithSqrt, NodeResultNumber) \
- \
- /* Add of values may either be arithmetic, or result in string concatenation. */\
- macro(ValueAdd, NodeResultJS | NodeMustGenerate | NodeMightClobber) \
- \
- /* Property access. */\
- /* PutByValAlias indicates a 'put' aliases a prior write to the same property. */\
- /* Since a put to 'length' may invalidate optimizations here, */\
- /* this must be the directly subsequent property put. */\
- macro(GetByVal, NodeResultJS | NodeMustGenerate | NodeMightClobber) \
- macro(PutByVal, NodeMustGenerate | NodeClobbersWorld) \
- macro(PutByValAlias, NodeMustGenerate | NodeClobbersWorld) \
- macro(GetById, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
- macro(GetByIdFlush, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
- macro(PutById, NodeMustGenerate | NodeClobbersWorld) \
- macro(PutByIdDirect, NodeMustGenerate | NodeClobbersWorld) \
- macro(CheckStructure, NodeMustGenerate) \
- macro(PutStructure, NodeMustGenerate | NodeClobbersWorld) \
- macro(GetPropertyStorage, NodeResultStorage) \
- macro(GetIndexedPropertyStorage, NodeMustGenerate | NodeResultStorage) \
- macro(GetByOffset, NodeResultJS) \
- macro(PutByOffset, NodeMustGenerate | NodeClobbersWorld) \
- macro(GetArrayLength, NodeResultInt32) \
- macro(GetStringLength, NodeResultInt32) \
- macro(GetByteArrayLength, NodeResultInt32) \
- macro(GetInt8ArrayLength, NodeResultInt32) \
- macro(GetInt16ArrayLength, NodeResultInt32) \
- macro(GetInt32ArrayLength, NodeResultInt32) \
- macro(GetUint8ArrayLength, NodeResultInt32) \
- macro(GetUint8ClampedArrayLength, NodeResultInt32) \
- macro(GetUint16ArrayLength, NodeResultInt32) \
- macro(GetUint32ArrayLength, NodeResultInt32) \
- macro(GetFloat32ArrayLength, NodeResultInt32) \
- macro(GetFloat64ArrayLength, NodeResultInt32) \
- macro(GetScopeChain, NodeResultJS) \
- macro(GetScopedVar, NodeResultJS | NodeMustGenerate) \
- macro(PutScopedVar, NodeMustGenerate | NodeClobbersWorld) \
- macro(GetGlobalVar, NodeResultJS | NodeMustGenerate) \
- macro(PutGlobalVar, NodeMustGenerate | NodeClobbersWorld) \
- macro(CheckFunction, NodeMustGenerate) \
- \
- /* Optimizations for array mutation. */\
- macro(ArrayPush, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
- macro(ArrayPop, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
- \
- /* Optimizations for string access */ \
- macro(StringCharCodeAt, NodeResultInt32) \
- macro(StringCharAt, NodeResultJS) \
- \
- /* Nodes for comparison operations. */\
- macro(CompareLess, NodeResultBoolean | NodeMustGenerate | NodeMightClobber) \
- macro(CompareLessEq, NodeResultBoolean | NodeMustGenerate | NodeMightClobber) \
- macro(CompareGreater, NodeResultBoolean | NodeMustGenerate | NodeMightClobber) \
- macro(CompareGreaterEq, NodeResultBoolean | NodeMustGenerate | NodeMightClobber) \
- macro(CompareEq, NodeResultBoolean | NodeMustGenerate | NodeMightClobber) \
- macro(CompareStrictEq, NodeResultBoolean) \
- \
- /* Calls. */\
- macro(Call, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \
- macro(Construct, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \
- \
- /* Allocations. */\
- macro(NewObject, NodeResultJS) \
- macro(NewArray, NodeResultJS | NodeHasVarArgs) \
- macro(NewArrayBuffer, NodeResultJS) \
- macro(NewRegexp, NodeResultJS) \
- \
- /* Resolve nodes. */\
- macro(Resolve, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
- macro(ResolveBase, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
- macro(ResolveBaseStrictPut, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
- macro(ResolveGlobal, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
- \
- /* Nodes for misc operations. */\
- macro(Breakpoint, NodeMustGenerate | NodeClobbersWorld) \
- macro(CheckHasInstance, NodeMustGenerate) \
- macro(InstanceOf, NodeResultBoolean) \
- macro(LogicalNot, NodeResultBoolean | NodeMightClobber) \
- macro(ToPrimitive, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
- macro(StrCat, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \
- \
- /* Nodes used for activations. Activation support works by having it anchored at */\
- /* epilgoues via TearOffActivation, and all CreateActivation nodes kept alive by */\
- /* being threaded with each other. */\
- macro(CreateActivation, NodeResultJS) \
- macro(TearOffActivation, NodeMustGenerate) \
- \
- /* Nodes for creating functions. */\
- macro(NewFunctionNoCheck, NodeResultJS) \
- macro(NewFunction, NodeResultJS) \
- macro(NewFunctionExpression, NodeResultJS) \
- \
- /* Block terminals. */\
- macro(Jump, NodeMustGenerate) \
- macro(Branch, NodeMustGenerate) \
- macro(Return, NodeMustGenerate) \
- macro(Throw, NodeMustGenerate) \
- macro(ThrowReferenceError, NodeMustGenerate) \
- \
- /* This is a pseudo-terminal. It means that execution should fall out of DFG at */\
- /* this point, but execution does continue in the basic block - just in a */\
- /* different compiler. */\
- macro(ForceOSRExit, NodeMustGenerate)
-
-// This enum generates a monotonically increasing id for all Node types,
-// and is used by the subsequent enum to fill out the id (as accessed via the NodeIdMask).
-enum NodeType {
-#define DFG_OP_ENUM(opcode, flags) opcode,
- FOR_EACH_DFG_OP(DFG_OP_ENUM)
-#undef DFG_OP_ENUM
- LastNodeType
-};
-
-// Specifies the default flags for each node.
-inline NodeFlags defaultFlags(NodeType op)
-{
- switch (op) {
-#define DFG_OP_ENUM(opcode, flags) case opcode: return flags;
- FOR_EACH_DFG_OP(DFG_OP_ENUM)
-#undef DFG_OP_ENUM
- default:
- ASSERT_NOT_REACHED();
- return 0;
- }
-}
-
// This type used in passing an immediate argument to Node constructor;
// distinguishes an immediate value (typically an index into a CodeBlock data structure -
// a constant index, argument, or identifier) from a NodeIndex.
@@ -313,32 +79,32 @@ struct Node {
// Construct a node with up to 3 children, no immediate value.
Node(NodeType op, CodeOrigin codeOrigin, NodeIndex child1 = NoNode, NodeIndex child2 = NoNode, NodeIndex child3 = NoNode)
: codeOrigin(codeOrigin)
- , children(NodeReferenceBlob::Fixed, child1, child2, child3)
+ , children(AdjacencyList::Fixed, child1, child2, child3)
, m_virtualRegister(InvalidVirtualRegister)
, m_refCount(0)
, m_prediction(PredictNone)
{
setOpAndDefaultFlags(op);
- ASSERT(!(flags & NodeHasVarArgs));
+ ASSERT(!(m_flags & NodeHasVarArgs));
}
// Construct a node with up to 3 children and an immediate value.
Node(NodeType op, CodeOrigin codeOrigin, OpInfo imm, NodeIndex child1 = NoNode, NodeIndex child2 = NoNode, NodeIndex child3 = NoNode)
: codeOrigin(codeOrigin)
- , children(NodeReferenceBlob::Fixed, child1, child2, child3)
+ , children(AdjacencyList::Fixed, child1, child2, child3)
, m_virtualRegister(InvalidVirtualRegister)
, m_refCount(0)
, m_opInfo(imm.m_value)
, m_prediction(PredictNone)
{
setOpAndDefaultFlags(op);
- ASSERT(!(flags & NodeHasVarArgs));
+ ASSERT(!(m_flags & NodeHasVarArgs));
}
// Construct a node with up to 3 children and two immediate values.
Node(NodeType op, CodeOrigin codeOrigin, OpInfo imm1, OpInfo imm2, NodeIndex child1 = NoNode, NodeIndex child2 = NoNode, NodeIndex child3 = NoNode)
: codeOrigin(codeOrigin)
- , children(NodeReferenceBlob::Fixed, child1, child2, child3)
+ , children(AdjacencyList::Fixed, child1, child2, child3)
, m_virtualRegister(InvalidVirtualRegister)
, m_refCount(0)
, m_opInfo(imm1.m_value)
@@ -346,13 +112,13 @@ struct Node {
, m_prediction(PredictNone)
{
setOpAndDefaultFlags(op);
- ASSERT(!(flags & NodeHasVarArgs));
+ ASSERT(!(m_flags & NodeHasVarArgs));
}
// Construct a node with a variable number of children and two immediate values.
Node(VarArgTag, NodeType op, CodeOrigin codeOrigin, OpInfo imm1, OpInfo imm2, unsigned firstChild, unsigned numChildren)
: codeOrigin(codeOrigin)
- , children(NodeReferenceBlob::Variable, firstChild, numChildren)
+ , children(AdjacencyList::Variable, firstChild, numChildren)
, m_virtualRegister(InvalidVirtualRegister)
, m_refCount(0)
, m_opInfo(imm1.m_value)
@@ -360,28 +126,64 @@ struct Node {
, m_prediction(PredictNone)
{
setOpAndDefaultFlags(op);
- ASSERT(flags & NodeHasVarArgs);
+ ASSERT(m_flags & NodeHasVarArgs);
+ }
+
+ NodeType op() const { return static_cast<NodeType>(m_op); }
+ NodeFlags flags() const { return m_flags; }
+
+ void setOp(NodeType op)
+ {
+ m_op = op;
+ }
+
+ void setFlags(NodeFlags flags)
+ {
+ m_flags = flags;
+ }
+
+ bool mergeFlags(NodeFlags flags)
+ {
+ NodeFlags newFlags = m_flags | flags;
+ if (newFlags == m_flags)
+ return false;
+ m_flags = newFlags;
+ return true;
+ }
+
+ bool filterFlags(NodeFlags flags)
+ {
+ NodeFlags newFlags = m_flags & flags;
+ if (newFlags == m_flags)
+ return false;
+ m_flags = newFlags;
+ return true;
+ }
+
+ bool clearFlags(NodeFlags flags)
+ {
+ return filterFlags(~flags);
}
void setOpAndDefaultFlags(NodeType op)
{
- this->op = op;
- flags = defaultFlags(op);
+ m_op = op;
+ m_flags = defaultFlags(op);
}
bool mustGenerate()
{
- return flags & NodeMustGenerate;
+ return m_flags & NodeMustGenerate;
}
bool isConstant()
{
- return op == JSConstant;
+ return op() == JSConstant;
}
bool isWeakConstant()
{
- return op == WeakJSConstant;
+ return op() == WeakJSConstant;
}
bool hasConstant()
@@ -402,7 +204,7 @@ struct Node {
JSValue valueOfJSConstant(CodeBlock* codeBlock)
{
- if (op == WeakJSConstant)
+ if (op() == WeakJSConstant)
return JSValue(weakConstant());
return codeBlock->constantRegister(FirstConstantRegisterIndex + constantNumber()).get();
}
@@ -434,7 +236,7 @@ struct Node {
bool hasVariableAccessData()
{
- switch (op) {
+ switch (op()) {
case GetLocal:
case SetLocal:
case Phi:
@@ -464,7 +266,7 @@ struct Node {
bool hasIdentifier()
{
- switch (op) {
+ switch (op()) {
case GetById:
case GetByIdFlush:
case PutById:
@@ -486,13 +288,13 @@ struct Node {
unsigned resolveGlobalDataIndex()
{
- ASSERT(op == ResolveGlobal);
+ ASSERT(op() == ResolveGlobal);
return m_opInfo;
}
bool hasArithNodeFlags()
{
- switch (op) {
+ switch (op()) {
case UInt32ToNumber:
case ArithAdd:
case ArithSub:
@@ -515,33 +317,15 @@ struct Node {
// to know if it can speculate on negative zero.
NodeFlags arithNodeFlags()
{
- NodeFlags result = flags & NodeArithMask;
- if (op == ArithMul)
+ NodeFlags result = m_flags;
+ if (op() == ArithMul || op() == ArithDiv || op() == ArithMod)
return result;
return result & ~NodeNeedsNegZero;
}
- void setArithNodeFlag(NodeFlags newFlags)
- {
- ASSERT(!(newFlags & ~NodeArithMask));
-
- flags &= ~NodeArithMask;
- flags |= newFlags;
- }
-
- bool mergeArithNodeFlags(NodeFlags newFlags)
- {
- ASSERT(!(newFlags & ~NodeArithMask));
- newFlags = flags | newFlags;
- if (newFlags == flags)
- return false;
- flags = newFlags;
- return true;
- }
-
bool hasConstantBuffer()
{
- return op == NewArrayBuffer;
+ return op() == NewArrayBuffer;
}
unsigned startConstant()
@@ -558,7 +342,7 @@ struct Node {
bool hasRegexpIndex()
{
- return op == NewRegexp;
+ return op() == NewRegexp;
}
unsigned regexpIndex()
@@ -569,7 +353,7 @@ struct Node {
bool hasVarNumber()
{
- return op == GetGlobalVar || op == PutGlobalVar || op == GetScopedVar || op == PutScopedVar;
+ return op() == GetGlobalVar || op() == PutGlobalVar || op() == GetScopedVar || op() == PutScopedVar;
}
unsigned varNumber()
@@ -580,7 +364,7 @@ struct Node {
bool hasScopeChainDepth()
{
- return op == GetScopeChain;
+ return op() == GetScopeChain;
}
unsigned scopeChainDepth()
@@ -591,42 +375,42 @@ struct Node {
bool hasResult()
{
- return flags & NodeResultMask;
+ return m_flags & NodeResultMask;
}
bool hasInt32Result()
{
- return (flags & NodeResultMask) == NodeResultInt32;
+ return (m_flags & NodeResultMask) == NodeResultInt32;
}
bool hasNumberResult()
{
- return (flags & NodeResultMask) == NodeResultNumber;
+ return (m_flags & NodeResultMask) == NodeResultNumber;
}
bool hasJSResult()
{
- return (flags & NodeResultMask) == NodeResultJS;
+ return (m_flags & NodeResultMask) == NodeResultJS;
}
bool hasBooleanResult()
{
- return (flags & NodeResultMask) == NodeResultBoolean;
+ return (m_flags & NodeResultMask) == NodeResultBoolean;
}
bool isJump()
{
- return op == Jump;
+ return op() == Jump;
}
bool isBranch()
{
- return op == Branch;
+ return op() == Branch;
}
bool isTerminal()
{
- switch (op) {
+ switch (op()) {
case Jump:
case Branch:
case Return:
@@ -676,7 +460,7 @@ struct Node {
bool hasHeapPrediction()
{
- switch (op) {
+ switch (op()) {
case GetById:
case GetByIdFlush:
case GetByVal:
@@ -690,6 +474,9 @@ struct Node {
case ResolveGlobal:
case ArrayPop:
case ArrayPush:
+ case RegExpExec:
+ case RegExpTest:
+ case GetGlobalVar:
return true;
default:
return false;
@@ -711,7 +498,7 @@ struct Node {
bool hasFunctionCheckData()
{
- return op == CheckFunction;
+ return op() == CheckFunction;
}
JSFunction* function()
@@ -722,7 +509,7 @@ struct Node {
bool hasStructureTransitionData()
{
- return op == PutStructure;
+ return op() == PutStructure;
}
StructureTransitionData& structureTransitionData()
@@ -733,7 +520,7 @@ struct Node {
bool hasStructureSet()
{
- return op == CheckStructure;
+ return op() == CheckStructure;
}
StructureSet& structureSet()
@@ -744,7 +531,7 @@ struct Node {
bool hasStorageAccessData()
{
- return op == GetByOffset || op == PutByOffset;
+ return op() == GetByOffset || op() == PutByOffset;
}
unsigned storageAccessDataIndex()
@@ -755,8 +542,8 @@ struct Node {
bool hasFunctionDeclIndex()
{
- return op == NewFunction
- || op == NewFunctionNoCheck;
+ return op() == NewFunction
+ || op() == NewFunctionNoCheck;
}
unsigned functionDeclIndex()
@@ -767,7 +554,7 @@ struct Node {
bool hasFunctionExprIndex()
{
- return op == NewFunctionExpression;
+ return op() == NewFunctionExpression;
}
unsigned functionExprIndex()
@@ -830,41 +617,41 @@ struct Node {
return !--m_refCount;
}
- NodeUse child1()
+ Edge child1()
{
- ASSERT(!(flags & NodeHasVarArgs));
+ ASSERT(!(m_flags & NodeHasVarArgs));
return children.child1();
}
// This is useful if you want to do a fast check on the first child
// before also doing a check on the opcode. Use this with care and
// avoid it if possible.
- NodeUse child1Unchecked()
+ Edge child1Unchecked()
{
return children.child1Unchecked();
}
- NodeUse child2()
+ Edge child2()
{
- ASSERT(!(flags & NodeHasVarArgs));
+ ASSERT(!(m_flags & NodeHasVarArgs));
return children.child2();
}
- NodeUse child3()
+ Edge child3()
{
- ASSERT(!(flags & NodeHasVarArgs));
+ ASSERT(!(m_flags & NodeHasVarArgs));
return children.child3();
}
unsigned firstChild()
{
- ASSERT(flags & NodeHasVarArgs);
+ ASSERT(m_flags & NodeHasVarArgs);
return children.firstChild();
}
unsigned numChildren()
{
- ASSERT(flags & NodeHasVarArgs);
+ ASSERT(m_flags & NodeHasVarArgs);
return children.numChildren();
}
@@ -890,12 +677,12 @@ struct Node {
bool shouldSpeculateNumber()
{
- return isNumberPrediction(prediction()) || prediction() == PredictNone;
+ return isNumberPrediction(prediction());
}
- bool shouldNotSpeculateInteger()
+ bool shouldSpeculateBoolean()
{
- return !!(prediction() & PredictDouble);
+ return isBooleanPrediction(prediction());
}
bool shouldSpeculateFinalObject()
@@ -913,27 +700,14 @@ struct Node {
return isArrayPrediction(prediction());
}
- bool shouldSpeculateByteArray()
- {
- return !!(prediction() & PredictByteArray);
- }
-
bool shouldSpeculateInt8Array()
{
-#if CPU(X86) || CPU(X86_64)
return isInt8ArrayPrediction(prediction());
-#else
- return false;
-#endif
}
bool shouldSpeculateInt16Array()
{
-#if CPU(X86) || CPU(X86_64)
return isInt16ArrayPrediction(prediction());
-#else
- return false;
-#endif
}
bool shouldSpeculateInt32Array()
@@ -963,11 +737,7 @@ struct Node {
bool shouldSpeculateFloat32Array()
{
-#if CPU(X86) || CPU(X86_64)
return isFloat32ArrayPrediction(prediction());
-#else
- return false;
-#endif
}
bool shouldSpeculateFloat64Array()
@@ -1002,14 +772,12 @@ struct Node {
static bool shouldSpeculateFinalObject(Node& op1, Node& op2)
{
- return (op1.shouldSpeculateFinalObject() && op2.shouldSpeculateObject())
- || (op1.shouldSpeculateObject() && op2.shouldSpeculateFinalObject());
+ return op1.shouldSpeculateFinalObject() && op2.shouldSpeculateFinalObject();
}
static bool shouldSpeculateArray(Node& op1, Node& op2)
{
- return (op1.shouldSpeculateArray() && op2.shouldSpeculateObject())
- || (op1.shouldSpeculateObject() && op2.shouldSpeculateArray());
+ return op1.shouldSpeculateArray() && op2.shouldSpeculateArray();
}
bool canSpeculateInteger()
@@ -1030,14 +798,14 @@ struct Node {
fprintf(out, ", @%u", child3().index());
}
- uint16_t op; // real type is NodeType
- NodeFlags flags;
// Used to look up exception handling information (currently implemented as a bytecode index).
CodeOrigin codeOrigin;
// References to up to 3 children, or links to a variable length set of children.
- NodeReferenceBlob children;
+ AdjacencyList children;
private:
+ uint16_t m_op; // real type is NodeType
+ NodeFlags m_flags;
// The virtual register number (spill location) associated with this .
VirtualRegister m_virtualRegister;
// The number of uses of the result of this operation (+1 for 'must generate' nodes, which have side-effects).