summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/dfg
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-02-09 14:16:12 +0100
committerSimon Hausmann <simon.hausmann@nokia.com>2012-02-09 14:16:12 +0100
commit03e12282df9aa1e1fb05a8b90f1cfc2e08764cec (patch)
tree52599cd0ab782b1768e23ad176f7618f98333cb6 /Source/JavaScriptCore/dfg
parentcd44dc59cdfc39534aef4d417e9f3c412e3be139 (diff)
downloadqtwebkit-03e12282df9aa1e1fb05a8b90f1cfc2e08764cec.tar.gz
Imported WebKit commit e09a82039aa4273ab318b71122e92d8e5f233525 (http://svn.webkit.org/repository/webkit/trunk@107223)
Diffstat (limited to 'Source/JavaScriptCore/dfg')
-rw-r--r--Source/JavaScriptCore/dfg/DFGAbstractState.cpp16
-rw-r--r--Source/JavaScriptCore/dfg/DFGAbstractState.h5
-rw-r--r--Source/JavaScriptCore/dfg/DFGAbstractValue.h4
-rw-r--r--Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h4
-rw-r--r--Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp91
-rw-r--r--Source/JavaScriptCore/dfg/DFGCommon.h5
-rw-r--r--Source/JavaScriptCore/dfg/DFGFPRInfo.h4
-rw-r--r--Source/JavaScriptCore/dfg/DFGGPRInfo.h6
-rw-r--r--Source/JavaScriptCore/dfg/DFGGraph.cpp32
-rw-r--r--Source/JavaScriptCore/dfg/DFGGraph.h41
-rw-r--r--Source/JavaScriptCore/dfg/DFGJITCompiler.h1
-rw-r--r--Source/JavaScriptCore/dfg/DFGNode.h73
-rw-r--r--Source/JavaScriptCore/dfg/DFGNodeReferenceBlob.h155
-rw-r--r--Source/JavaScriptCore/dfg/DFGNodeUse.h130
-rw-r--r--Source/JavaScriptCore/dfg/DFGOSRExit.cpp2
-rw-r--r--Source/JavaScriptCore/dfg/DFGOSRExit.h2
-rw-r--r--Source/JavaScriptCore/dfg/DFGPropagator.cpp167
-rw-r--r--Source/JavaScriptCore/dfg/DFGScoreBoard.h6
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp140
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h113
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp126
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp130
22 files changed, 678 insertions, 575 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
index bd35e1d43..72c1759c7 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
+++ b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
@@ -262,22 +262,6 @@ bool AbstractState::execute(NodeIndex nodeIndex)
forNode(nodeIndex).set(PredictInt32);
break;
- case ValueToNumber:
- if (m_graph[node.child1()].shouldNotSpeculateInteger()) {
- forNode(node.child1()).filter(PredictNumber);
- forNode(nodeIndex).set(PredictDouble);
- break;
- }
-
- forNode(node.child1()).filter(PredictInt32);
- forNode(nodeIndex).set(PredictInt32);
- break;
-
- case ValueToDouble:
- forNode(node.child1()).filter(PredictNumber);
- forNode(nodeIndex).set(PredictDouble);
- break;
-
case ValueAdd:
case ArithAdd: {
if (m_graph.addShouldSpeculateInteger(node, m_codeBlock)) {
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractState.h b/Source/JavaScriptCore/dfg/DFGAbstractState.h
index 337a4d0b4..015563485 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractState.h
+++ b/Source/JavaScriptCore/dfg/DFGAbstractState.h
@@ -101,6 +101,11 @@ public:
return m_nodes[nodeIndex - m_block->begin];
}
+ AbstractValue& forNode(NodeUse nodeUse)
+ {
+ return forNode(nodeUse.index());
+ }
+
// Call this before beginning CFA to initialize the abstract values of
// arguments, and to indicate which blocks should be listed for CFA
// execution.
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractValue.h b/Source/JavaScriptCore/dfg/DFGAbstractValue.h
index 15bc0d496..aa5518187 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractValue.h
+++ b/Source/JavaScriptCore/dfg/DFGAbstractValue.h
@@ -287,7 +287,6 @@ public:
return m_structure == other.m_structure;
}
-#ifndef NDEBUG
void dump(FILE* out) const
{
if (isTop()) {
@@ -300,7 +299,6 @@ public:
fprintf(out, "%p", m_structure);
fprintf(out, "]");
}
-#endif
private:
static Structure* topValue() { return reinterpret_cast<Structure*>(1); }
@@ -466,14 +464,12 @@ struct AbstractValue {
// complexity of the code.
}
-#ifndef NDEBUG
void dump(FILE* out) const
{
fprintf(out, "(%s, ", predictionToString(m_type));
m_structure.dump(out);
fprintf(out, ")");
}
-#endif
StructureAbstractValue m_structure;
PredictedType m_type;
diff --git a/Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h b/Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h
index e0d817c9f..0d7dd3a27 100644
--- a/Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h
+++ b/Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h
@@ -39,9 +39,7 @@
namespace JSC { namespace DFG {
-#ifndef NDEBUG
typedef void (*V_DFGDebugOperation_EP)(ExecState*, void*);
-#endif
class AssemblyHelpers : public MacroAssembler {
public:
@@ -152,7 +150,6 @@ public:
return branch8(Below, Address(structureReg, Structure::typeInfoTypeOffset()), TrustedImm32(ObjectType));
}
-#ifndef NDEBUG
// Add a debug call. This call has no effect on JIT code execution state.
void debugCall(V_DFGDebugOperation_EP function, void* argument)
{
@@ -182,7 +179,6 @@ public:
for (unsigned i = 0; i < GPRInfo::numberOfRegisters; ++i)
loadPtr(buffer + i, GPRInfo::toRegister(i));
}
-#endif
// These methods JIT generate dynamic, debug-only checks - akin to ASSERTs.
#if DFG_ENABLE(JIT_ASSERT)
diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
index 87c3a23b9..2a5d249b3 100644
--- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
+++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
@@ -170,7 +170,7 @@ private:
Node& flushChild = m_graph[nodePtr->child1()];
if (flushChild.op == Phi) {
VariableAccessData* variableAccessData = flushChild.variableAccessData();
- nodeIndex = addToGraph(GetLocal, OpInfo(variableAccessData), nodePtr->child1());
+ nodeIndex = addToGraph(GetLocal, OpInfo(variableAccessData), nodePtr->child1().index());
m_currentBlock->variablesAtTail.local(operand) = nodeIndex;
return nodeIndex;
}
@@ -179,7 +179,7 @@ private:
if (nodePtr->op == GetLocal)
return nodeIndex;
ASSERT(nodePtr->op == SetLocal);
- return nodePtr->child1();
+ return nodePtr->child1().index();
}
// Check for reads of temporaries from prior blocks,
@@ -219,7 +219,7 @@ private:
Node& flushChild = m_graph[nodePtr->child1()];
if (flushChild.op == Phi) {
VariableAccessData* variableAccessData = flushChild.variableAccessData();
- nodeIndex = addToGraph(GetLocal, OpInfo(variableAccessData), nodePtr->child1());
+ nodeIndex = addToGraph(GetLocal, OpInfo(variableAccessData), nodePtr->child1().index());
m_currentBlock->variablesAtTail.local(operand) = nodeIndex;
return nodeIndex;
}
@@ -238,7 +238,7 @@ private:
return nodeIndex;
ASSERT(nodePtr->op == SetLocal);
- return nodePtr->child1();
+ return nodePtr->child1().index();
}
VariableAccessData* variableAccessData = newVariableAccessData(operand);
@@ -313,10 +313,6 @@ private:
{
return toInt32(get(operand));
}
- NodeIndex getToNumber(int operand)
- {
- return toNumber(get(operand));
- }
// Perform an ES5 ToInt32 operation - returns a node of type NodeResultInt32.
NodeIndex toInt32(NodeIndex index)
@@ -327,7 +323,7 @@ private:
return index;
if (node.op == UInt32ToNumber)
- return node.child1();
+ return node.child1().index();
// Check for numeric constants boxed as JSValues.
if (node.op == JSConstant) {
@@ -341,23 +337,6 @@ private:
return addToGraph(ValueToInt32, index);
}
- // Perform an ES5 ToNumber operation - returns a node of type NodeResultDouble.
- NodeIndex toNumber(NodeIndex index)
- {
- Node& node = m_graph[index];
-
- if (node.hasNumberResult())
- return index;
-
- if (node.op == JSConstant) {
- JSValue v = valueOfJSConstant(index);
- if (v.isNumber())
- return getJSConstant(node.constantNumber());
- }
-
- return addToGraph(ValueToNumber, OpInfo(NodeUseBottom), index);
- }
-
NodeIndex getJSConstantForValue(JSValue constantValue)
{
unsigned constantIndex = m_codeBlock->addOrFindConstant(constantValue);
@@ -572,7 +551,7 @@ private:
}
void addVarArgChild(NodeIndex child)
{
- m_graph.m_varArgChildren.append(child);
+ m_graph.m_varArgChildren.append(NodeUse(child));
m_numPassedVarArgs++;
}
@@ -1198,12 +1177,12 @@ bool ByteCodeParser::handleMinMax(bool usesResult, int resultOperand, NodeType o
}
if (argumentCountIncludingThis == 2) { // Math.min(x)
- set(resultOperand, getToNumber(registerOffset + argumentToOperand(1)));
+ set(resultOperand, get(registerOffset + argumentToOperand(1)));
return true;
}
if (argumentCountIncludingThis == 3) { // Math.min(x, y)
- set(resultOperand, addToGraph(op, OpInfo(NodeUseBottom), getToNumber(registerOffset + argumentToOperand(1)), getToNumber(registerOffset + argumentToOperand(2))));
+ set(resultOperand, addToGraph(op, OpInfo(NodeUseBottom), get(registerOffset + argumentToOperand(1)), get(registerOffset + argumentToOperand(2))));
return true;
}
@@ -1231,7 +1210,7 @@ bool ByteCodeParser::handleIntrinsic(bool usesResult, int resultOperand, Intrins
if (!MacroAssembler::supportsFloatingPointAbs())
return false;
- NodeIndex nodeIndex = addToGraph(ArithAbs, OpInfo(NodeUseBottom), getToNumber(registerOffset + argumentToOperand(1)));
+ NodeIndex nodeIndex = addToGraph(ArithAbs, OpInfo(NodeUseBottom), get(registerOffset + argumentToOperand(1)));
if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow))
m_graph[nodeIndex].mergeArithNodeFlags(NodeMayOverflow);
set(resultOperand, nodeIndex);
@@ -1256,7 +1235,7 @@ bool ByteCodeParser::handleIntrinsic(bool usesResult, int resultOperand, Intrins
if (!MacroAssembler::supportsFloatingPointSqrt())
return false;
- set(resultOperand, addToGraph(ArithSqrt, getToNumber(registerOffset + argumentToOperand(1))));
+ set(resultOperand, addToGraph(ArithSqrt, get(registerOffset + argumentToOperand(1))));
return true;
}
@@ -1512,7 +1491,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
case op_pre_inc: {
unsigned srcDst = currentInstruction[1].u.operand;
- NodeIndex op = getToNumber(srcDst);
+ NodeIndex op = get(srcDst);
set(srcDst, makeSafe(addToGraph(ArithAdd, OpInfo(NodeUseBottom), op, one())));
NEXT_OPCODE(op_pre_inc);
}
@@ -1521,7 +1500,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
unsigned result = currentInstruction[1].u.operand;
unsigned srcDst = currentInstruction[2].u.operand;
ASSERT(result != srcDst); // Required for assumptions we make during OSR.
- NodeIndex op = getToNumber(srcDst);
+ NodeIndex op = get(srcDst);
set(result, op);
set(srcDst, makeSafe(addToGraph(ArithAdd, OpInfo(NodeUseBottom), op, one())));
NEXT_OPCODE(op_post_inc);
@@ -1529,7 +1508,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
case op_pre_dec: {
unsigned srcDst = currentInstruction[1].u.operand;
- NodeIndex op = getToNumber(srcDst);
+ NodeIndex op = get(srcDst);
set(srcDst, makeSafe(addToGraph(ArithSub, OpInfo(NodeUseBottom), op, one())));
NEXT_OPCODE(op_pre_dec);
}
@@ -1537,7 +1516,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
case op_post_dec: {
unsigned result = currentInstruction[1].u.operand;
unsigned srcDst = currentInstruction[2].u.operand;
- NodeIndex op = getToNumber(srcDst);
+ NodeIndex op = get(srcDst);
set(result, op);
set(srcDst, makeSafe(addToGraph(ArithSub, OpInfo(NodeUseBottom), op, one())));
NEXT_OPCODE(op_post_dec);
@@ -1549,37 +1528,37 @@ bool ByteCodeParser::parseBlock(unsigned limit)
NodeIndex op1 = get(currentInstruction[2].u.operand);
NodeIndex op2 = get(currentInstruction[3].u.operand);
if (m_graph[op1].hasNumberResult() && m_graph[op2].hasNumberResult())
- set(currentInstruction[1].u.operand, makeSafe(addToGraph(ArithAdd, OpInfo(NodeUseBottom), toNumber(op1), toNumber(op2))));
+ set(currentInstruction[1].u.operand, makeSafe(addToGraph(ArithAdd, OpInfo(NodeUseBottom), op1, op2)));
else
set(currentInstruction[1].u.operand, makeSafe(addToGraph(ValueAdd, OpInfo(NodeUseBottom), op1, op2)));
NEXT_OPCODE(op_add);
}
case op_sub: {
- NodeIndex op1 = getToNumber(currentInstruction[2].u.operand);
- NodeIndex op2 = getToNumber(currentInstruction[3].u.operand);
+ NodeIndex op1 = get(currentInstruction[2].u.operand);
+ NodeIndex op2 = get(currentInstruction[3].u.operand);
set(currentInstruction[1].u.operand, makeSafe(addToGraph(ArithSub, OpInfo(NodeUseBottom), op1, op2)));
NEXT_OPCODE(op_sub);
}
case op_mul: {
// Multiply requires that the inputs are not truncated, unfortunately.
- NodeIndex op1 = getToNumber(currentInstruction[2].u.operand);
- NodeIndex op2 = getToNumber(currentInstruction[3].u.operand);
+ NodeIndex op1 = get(currentInstruction[2].u.operand);
+ NodeIndex op2 = get(currentInstruction[3].u.operand);
set(currentInstruction[1].u.operand, makeSafe(addToGraph(ArithMul, OpInfo(NodeUseBottom), op1, op2)));
NEXT_OPCODE(op_mul);
}
case op_mod: {
- NodeIndex op1 = getToNumber(currentInstruction[2].u.operand);
- NodeIndex op2 = getToNumber(currentInstruction[3].u.operand);
+ NodeIndex op1 = get(currentInstruction[2].u.operand);
+ NodeIndex op2 = get(currentInstruction[3].u.operand);
set(currentInstruction[1].u.operand, makeSafe(addToGraph(ArithMod, OpInfo(NodeUseBottom), op1, op2)));
NEXT_OPCODE(op_mod);
}
case op_div: {
- NodeIndex op1 = getToNumber(currentInstruction[2].u.operand);
- NodeIndex op2 = getToNumber(currentInstruction[3].u.operand);
+ NodeIndex op1 = get(currentInstruction[2].u.operand);
+ NodeIndex op2 = get(currentInstruction[3].u.operand);
set(currentInstruction[1].u.operand, makeDivSafe(addToGraph(ArithDiv, OpInfo(NodeUseBottom), op1, op2)));
NEXT_OPCODE(op_div);
}
@@ -2241,9 +2220,9 @@ void ByteCodeParser::processPhiStack()
// GetLocal and its block-local Phi. Strictly speaking we only need the two
// to be unified. But for efficiency, we want the code that creates GetLocals
// and Phis to try to reuse VariableAccessDatas as much as possible.
- ASSERT(m_graph[valueInPredecessor].variableAccessData() == m_graph[m_graph[valueInPredecessor].child1()].variableAccessData());
+ ASSERT(m_graph[valueInPredecessor].variableAccessData() == m_graph[m_graph[valueInPredecessor].child1().index()].variableAccessData());
- valueInPredecessor = m_graph[valueInPredecessor].child1();
+ valueInPredecessor = m_graph[valueInPredecessor].child1().index();
} else {
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
printf(" Found @%u.\n", valueInPredecessor);
@@ -2266,11 +2245,11 @@ void ByteCodeParser::processPhiStack()
m_graph.ref(valueInPredecessor);
}
- if (phiNode->child1() == NoNode) {
+ if (!phiNode->child1()) {
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
printf(" Setting @%u->child1 = @%u.\n", entry.m_phi, valueInPredecessor);
#endif
- phiNode->children.fixed.child1 = valueInPredecessor;
+ phiNode->children.setChild1(NodeUse(valueInPredecessor));
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
printf(" Children of @%u: ", entry.m_phi);
phiNode->dumpChildren(stdout);
@@ -2278,11 +2257,11 @@ void ByteCodeParser::processPhiStack()
#endif
continue;
}
- if (phiNode->child2() == NoNode) {
+ if (!phiNode->child2()) {
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
printf(" Setting @%u->child2 = @%u.\n", entry.m_phi, valueInPredecessor);
#endif
- phiNode->children.fixed.child2 = valueInPredecessor;
+ phiNode->children.setChild2(NodeUse(valueInPredecessor));
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
printf(" Children of @%u: ", entry.m_phi);
phiNode->dumpChildren(stdout);
@@ -2290,11 +2269,11 @@ void ByteCodeParser::processPhiStack()
#endif
continue;
}
- if (phiNode->child3() == NoNode) {
+ if (!phiNode->child3()) {
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
printf(" Setting @%u->child3 = @%u.\n", entry.m_phi, valueInPredecessor);
#endif
- phiNode->children.fixed.child3 = valueInPredecessor;
+ phiNode->children.setChild3(NodeUse(valueInPredecessor));
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
printf(" Children of @%u: ", entry.m_phi);
phiNode->dumpChildren(stdout);
@@ -2314,9 +2293,7 @@ void ByteCodeParser::processPhiStack()
if (phiNode->refCount())
m_graph.ref(newPhi);
- newPhiNode.children.fixed.child1 = phiNode->child1();
- newPhiNode.children.fixed.child2 = phiNode->child2();
- newPhiNode.children.fixed.child3 = phiNode->child3();
+ newPhiNode.children = phiNode->children;
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
printf(" Children of @%u: ", newPhi);
@@ -2324,9 +2301,7 @@ void ByteCodeParser::processPhiStack()
printf(".\n");
#endif
- phiNode->children.fixed.child1 = newPhi;
- phiNode->children.fixed.child2 = valueInPredecessor;
- phiNode->children.fixed.child3 = NoNode;
+ phiNode->children.initialize(newPhi, valueInPredecessor, NoNode);
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
printf(" Children of @%u: ", entry.m_phi);
diff --git a/Source/JavaScriptCore/dfg/DFGCommon.h b/Source/JavaScriptCore/dfg/DFGCommon.h
index 469dbd33e..14edff3a5 100644
--- a/Source/JavaScriptCore/dfg/DFGCommon.h
+++ b/Source/JavaScriptCore/dfg/DFGCommon.h
@@ -92,6 +92,11 @@ struct NodeIndexTraits {
}
};
+enum UseKind {
+ UntypedUse,
+ LastUseKind // Must always be the last entry in the enum, as it is used to denote the number of enum elements.
+};
+
} } // namespace JSC::DFG
#endif // ENABLE(DFG_JIT)
diff --git a/Source/JavaScriptCore/dfg/DFGFPRInfo.h b/Source/JavaScriptCore/dfg/DFGFPRInfo.h
index dbd60a4e6..6af45dd81 100644
--- a/Source/JavaScriptCore/dfg/DFGFPRInfo.h
+++ b/Source/JavaScriptCore/dfg/DFGFPRInfo.h
@@ -78,7 +78,6 @@ public:
return (unsigned)reg;
}
-#ifndef NDEBUG
static const char* debugName(FPRReg reg)
{
ASSERT(reg != InvalidFPRReg);
@@ -99,7 +98,6 @@ public:
#endif
return nameForRegister[reg];
}
-#endif
};
#endif
@@ -141,7 +139,6 @@ public:
return (unsigned)reg;
}
-#ifndef NDEBUG
static const char* debugName(FPRReg reg)
{
ASSERT(reg != InvalidFPRReg);
@@ -158,7 +155,6 @@ public:
};
return nameForRegister[reg];
}
-#endif
};
#endif
diff --git a/Source/JavaScriptCore/dfg/DFGGPRInfo.h b/Source/JavaScriptCore/dfg/DFGGPRInfo.h
index 2f779d645..f010d8c18 100644
--- a/Source/JavaScriptCore/dfg/DFGGPRInfo.h
+++ b/Source/JavaScriptCore/dfg/DFGGPRInfo.h
@@ -292,7 +292,6 @@ public:
return result;
}
-#ifndef NDEBUG
static const char* debugName(GPRReg reg)
{
ASSERT(reg != InvalidGPRReg);
@@ -303,7 +302,6 @@ public:
};
return nameForRegister[reg];
}
-#endif
private:
static const unsigned InvalidIndex = 0xffffffff;
@@ -363,7 +361,6 @@ public:
return result;
}
-#ifndef NDEBUG
static const char* debugName(GPRReg reg)
{
ASSERT(reg != InvalidGPRReg);
@@ -376,7 +373,6 @@ public:
};
return nameForRegister[reg];
}
-#endif
private:
static const unsigned InvalidIndex = 0xffffffff;
@@ -436,7 +432,6 @@ public:
return result;
}
-#ifndef NDEBUG
static const char* debugName(GPRReg reg)
{
ASSERT(reg != InvalidGPRReg);
@@ -449,7 +444,6 @@ public:
};
return nameForRegister[reg];
}
-#endif
private:
static const unsigned InvalidIndex = 0xffffffff;
diff --git a/Source/JavaScriptCore/dfg/DFGGraph.cpp b/Source/JavaScriptCore/dfg/DFGGraph.cpp
index e01bea195..c304dc8e7 100644
--- a/Source/JavaScriptCore/dfg/DFGGraph.cpp
+++ b/Source/JavaScriptCore/dfg/DFGGraph.cpp
@@ -32,8 +32,6 @@
namespace JSC { namespace DFG {
-#ifndef NDEBUG
-
// Creates an array of stringized names.
static const char* dfgOpNames[] = {
#define STRINGIZE_DFG_OP_ENUM(opcode, flags) #opcode ,
@@ -165,16 +163,16 @@ void Graph::dump(NodeIndex nodeIndex, CodeBlock* codeBlock)
printf(", ");
else
hasPrinted = true;
- printf("@%u", m_varArgChildren[childIdx]);
+ printf("@%u", m_varArgChildren[childIdx].index());
}
} else {
- if (node.child1() != NoNode)
- printf("@%u", node.child1());
- if (node.child2() != NoNode)
- printf(", @%u", node.child2());
- if (node.child3() != NoNode)
- printf(", @%u", node.child3());
- hasPrinted = node.child1() != NoNode;
+ if (!!node.child1())
+ printf("@%u", node.child1().index());
+ if (!!node.child2())
+ printf(", @%u", node.child2().index());
+ if (!!node.child3())
+ printf(", @%u", node.child3().index());
+ hasPrinted = !!node.child1();
}
if (node.hasArithNodeFlags()) {
@@ -298,8 +296,6 @@ void Graph::dump(CodeBlock* codeBlock)
dump(i, codeBlock);
}
-#endif
-
// FIXME: Convert this to be iterative, not recursive.
#define DO_TO_CHILDREN(node, thingToDo) do { \
Node& _node = (node); \
@@ -309,20 +305,20 @@ void Graph::dump(CodeBlock* codeBlock)
_childIdx++) \
thingToDo(m_varArgChildren[_childIdx]); \
} else { \
- if (_node.child1() == NoNode) { \
- ASSERT(_node.child2() == NoNode \
- && _node.child3() == NoNode); \
+ if (!_node.child1()) { \
+ ASSERT(!_node.child2() \
+ && !_node.child3()); \
break; \
} \
thingToDo(_node.child1()); \
\
- if (_node.child2() == NoNode) { \
- ASSERT(_node.child3() == NoNode); \
+ if (!_node.child2()) { \
+ ASSERT(!_node.child3()); \
break; \
} \
thingToDo(_node.child2()); \
\
- if (_node.child3() == NoNode) \
+ if (!_node.child3()) \
break; \
thingToDo(_node.child3()); \
} \
diff --git a/Source/JavaScriptCore/dfg/DFGGraph.h b/Source/JavaScriptCore/dfg/DFGGraph.h
index d3f16a0f4..ecd77b3a4 100644
--- a/Source/JavaScriptCore/dfg/DFGGraph.h
+++ b/Source/JavaScriptCore/dfg/DFGGraph.h
@@ -71,6 +71,15 @@ struct ResolveGlobalData {
// Nodes that are 'dead' remain in the vector with refCount 0.
class Graph : public Vector<Node, 64> {
public:
+ using Vector<Node, 64>::operator[];
+ using Vector<Node, 64>::at;
+
+ Node& operator[](NodeUse nodeUse) { return at(nodeUse.index()); }
+ const Node& operator[](NodeUse nodeUse) const { return at(nodeUse.index()); }
+
+ Node& at(NodeUse nodeUse) { return at(nodeUse.index()); }
+ const Node& at(NodeUse nodeUse) const { return at(nodeUse.index()); }
+
// Mark a node as being referenced.
void ref(NodeIndex nodeIndex)
{
@@ -79,38 +88,45 @@ public:
if (node.ref())
refChildren(nodeIndex);
}
+ void ref(NodeUse nodeUse)
+ {
+ ref(nodeUse.index());
+ }
void deref(NodeIndex nodeIndex)
{
if (at(nodeIndex).deref())
derefChildren(nodeIndex);
}
+ void deref(NodeUse nodeUse)
+ {
+ deref(nodeUse.index());
+ }
void clearAndDerefChild1(Node& node)
{
- if (node.children.fixed.child1 == NoNode)
+ if (!node.child1())
return;
- deref(node.children.fixed.child1);
- node.children.fixed.child1 = NoNode;
+ deref(node.child1());
+ node.children.child1() = NodeUse();
}
void clearAndDerefChild2(Node& node)
{
- if (node.children.fixed.child2 == NoNode)
+ if (!node.child2())
return;
- deref(node.children.fixed.child2);
- node.children.fixed.child2 = NoNode;
+ deref(node.child2());
+ node.children.child2() = NodeUse();
}
void clearAndDerefChild3(Node& node)
{
- if (node.children.fixed.child3 == NoNode)
+ if (!node.child3())
return;
- deref(node.children.fixed.child3);
- node.children.fixed.child3 = NoNode;
+ deref(node.child3());
+ node.children.child3() = NodeUse();
}
-#ifndef NDEBUG
// CodeBlock is optional, but may allow additional information to be dumped (e.g. Identifier names).
void dump(CodeBlock* = 0);
void dump(NodeIndex, CodeBlock* = 0);
@@ -118,7 +134,6 @@ public:
// Dump the code origin of the given node as a diff from the code origin of the
// preceding node.
void dumpCodeOrigin(NodeIndex);
-#endif
BlockIndex blockIndexForBytecodeOffset(Vector<BlockIndex>& blocks, unsigned bytecodeBegin);
@@ -214,12 +229,10 @@ public:
return asFunction(function);
}
-#ifndef NDEBUG
static const char *opName(NodeType);
// This is O(n), and should only be used for verbose dumps.
const char* nameOfVariableAccessData(VariableAccessData*);
-#endif
void predictArgumentTypes(CodeBlock*);
@@ -259,7 +272,7 @@ public:
}
Vector< OwnPtr<BasicBlock> , 8> m_blocks;
- Vector<NodeIndex, 16> m_varArgChildren;
+ Vector<NodeUse, 16> m_varArgChildren;
Vector<StorageAccessData> m_storageAccessData;
Vector<ResolveGlobalData> m_resolveGlobalData;
Vector<NodeIndex, 8> m_arguments;
diff --git a/Source/JavaScriptCore/dfg/DFGJITCompiler.h b/Source/JavaScriptCore/dfg/DFGJITCompiler.h
index 451bee6ca..5596876fc 100644
--- a/Source/JavaScriptCore/dfg/DFGJITCompiler.h
+++ b/Source/JavaScriptCore/dfg/DFGJITCompiler.h
@@ -272,6 +272,7 @@ public:
// Helper methods to get predictions
PredictedType getPrediction(Node& node) { return node.prediction(); }
PredictedType getPrediction(NodeIndex nodeIndex) { return getPrediction(graph()[nodeIndex]); }
+ PredictedType getPrediction(NodeUse nodeUse) { return getPrediction(nodeUse.index()); }
#if USE(JSVALUE32_64)
void* addressOfDoubleConstant(NodeIndex nodeIndex)
diff --git a/Source/JavaScriptCore/dfg/DFGNode.h b/Source/JavaScriptCore/dfg/DFGNode.h
index 7366c1c40..2b6ebdb7f 100644
--- a/Source/JavaScriptCore/dfg/DFGNode.h
+++ b/Source/JavaScriptCore/dfg/DFGNode.h
@@ -33,6 +33,7 @@
#include "CodeBlock.h"
#include "CodeOrigin.h"
#include "DFGCommon.h"
+#include "DFGNodeReferenceBlob.h"
#include "DFGOperands.h"
#include "DFGVariableAccessData.h"
#include "JSValue.h"
@@ -96,7 +97,6 @@ static inline bool nodeCanSpeculateInteger(ArithNodeFlags flags)
return true;
}
-#ifndef NDEBUG
static inline const char* arithNodeFlagsAsString(ArithNodeFlags flags)
{
if (!flags)
@@ -138,7 +138,6 @@ static inline const char* arithNodeFlagsAsString(ArithNodeFlags flags)
return description;
}
-#endif
// 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).
@@ -212,11 +211,6 @@ static inline const char* arithNodeFlagsAsString(ArithNodeFlags flags)
macro(ArithMin, NodeResultNumber) \
macro(ArithMax, NodeResultNumber) \
macro(ArithSqrt, NodeResultNumber) \
- /* Arithmetic operators call ToNumber on their operands. */\
- macro(ValueToNumber, NodeResultNumber | NodeMustGenerate) \
- \
- /* A variant of ValueToNumber, which a hint that the parents will always use this as a double. */\
- macro(ValueToDouble, NodeResultNumber | NodeMustGenerate) \
\
/* Add of values may either be arithmetic, or result in string concatenation. */\
macro(ValueAdd, NodeResultJS | NodeMustGenerate | NodeMightClobber) \
@@ -349,36 +343,33 @@ struct Node {
Node(NodeType op, CodeOrigin codeOrigin, NodeIndex child1 = NoNode, NodeIndex child2 = NoNode, NodeIndex child3 = NoNode)
: op(op)
, codeOrigin(codeOrigin)
+ , children(NodeReferenceBlob::Fixed, child1, child2, child3)
, m_virtualRegister(InvalidVirtualRegister)
, m_refCount(0)
, m_prediction(PredictNone)
{
ASSERT(!(op & NodeHasVarArgs));
ASSERT(!hasArithNodeFlags());
- children.fixed.child1 = child1;
- children.fixed.child2 = child2;
- children.fixed.child3 = child3;
}
// 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)
: op(op)
, codeOrigin(codeOrigin)
+ , children(NodeReferenceBlob::Fixed, child1, child2, child3)
, m_virtualRegister(InvalidVirtualRegister)
, m_refCount(0)
, m_opInfo(imm.m_value)
, m_prediction(PredictNone)
{
ASSERT(!(op & NodeHasVarArgs));
- children.fixed.child1 = child1;
- children.fixed.child2 = child2;
- children.fixed.child3 = child3;
}
// 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)
: op(op)
, codeOrigin(codeOrigin)
+ , children(NodeReferenceBlob::Fixed, child1, child2, child3)
, m_virtualRegister(InvalidVirtualRegister)
, m_refCount(0)
, m_opInfo(imm1.m_value)
@@ -386,15 +377,13 @@ struct Node {
, m_prediction(PredictNone)
{
ASSERT(!(op & NodeHasVarArgs));
- children.fixed.child1 = child1;
- children.fixed.child2 = child2;
- children.fixed.child3 = child3;
}
// 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)
: op(op)
, codeOrigin(codeOrigin)
+ , children(NodeReferenceBlob::Variable, firstChild, numChildren)
, m_virtualRegister(InvalidVirtualRegister)
, m_refCount(0)
, m_opInfo(imm1.m_value)
@@ -402,8 +391,6 @@ struct Node {
, m_prediction(PredictNone)
{
ASSERT(op & NodeHasVarArgs);
- children.variable.firstChild = firstChild;
- children.variable.numChildren = numChildren;
}
bool mustGenerate()
@@ -499,7 +486,6 @@ struct Node {
return variableAccessData()->local();
}
-#ifndef NDEBUG
bool hasIdentifier()
{
switch (op) {
@@ -515,7 +501,6 @@ struct Node {
return false;
}
}
-#endif
unsigned identifierNumber()
{
@@ -532,8 +517,6 @@ struct Node {
bool hasArithNodeFlags()
{
switch (op) {
- case ValueToNumber:
- case ValueToDouble:
case UInt32ToNumber:
case ArithAdd:
case ArithSub:
@@ -849,42 +832,42 @@ struct Node {
return !--m_refCount;
}
- NodeIndex child1()
+ NodeUse child1()
{
ASSERT(!(op & NodeHasVarArgs));
- return children.fixed.child1;
+ 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.
- NodeIndex child1Unchecked()
+ NodeUse child1Unchecked()
{
- return children.fixed.child1;
+ return children.child1Unchecked();
}
- NodeIndex child2()
+ NodeUse child2()
{
ASSERT(!(op & NodeHasVarArgs));
- return children.fixed.child2;
+ return children.child2();
}
- NodeIndex child3()
+ NodeUse child3()
{
ASSERT(!(op & NodeHasVarArgs));
- return children.fixed.child3;
+ return children.child3();
}
unsigned firstChild()
{
ASSERT(op & NodeHasVarArgs);
- return children.variable.firstChild;
+ return children.firstChild();
}
unsigned numChildren()
{
ASSERT(op & NodeHasVarArgs);
- return children.variable.numChildren;
+ return children.numChildren();
}
PredictedType prediction()
@@ -1036,35 +1019,25 @@ struct Node {
return nodeCanSpeculateInteger(arithNodeFlags());
}
-#ifndef NDEBUG
void dumpChildren(FILE* out)
{
- if (child1() == NoNode)
+ if (!child1())
return;
- fprintf(out, "@%u", child1());
- if (child2() == NoNode)
+ fprintf(out, "@%u", child1().index());
+ if (!child2())
return;
- fprintf(out, ", @%u", child2());
- if (child3() == NoNode)
+ fprintf(out, ", @%u", child2().index());
+ if (!child3())
return;
- fprintf(out, ", @%u", child3());
+ fprintf(out, ", @%u", child3().index());
}
-#endif
// This enum value describes the type of the node.
NodeType op;
// Used to look up exception handling information (currently implemented as a bytecode index).
CodeOrigin codeOrigin;
- // References to up to 3 children (0 for no child).
- union {
- struct {
- NodeIndex child1, child2, child3;
- } fixed;
- struct {
- unsigned firstChild;
- unsigned numChildren;
- } variable;
- } children;
+ // References to up to 3 children, or links to a variable length set of children.
+ NodeReferenceBlob children;
private:
// The virtual register number (spill location) associated with this .
diff --git a/Source/JavaScriptCore/dfg/DFGNodeReferenceBlob.h b/Source/JavaScriptCore/dfg/DFGNodeReferenceBlob.h
new file mode 100644
index 000000000..df3ff5f5f
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGNodeReferenceBlob.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DFGNodeReferenceBlob_h
+#define DFGNodeReferenceBlob_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGCommon.h"
+#include "DFGNodeUse.h"
+
+namespace JSC { namespace DFG {
+
+class NodeReferenceBlob {
+public:
+ enum Kind {
+ Fixed,
+ Variable
+ };
+
+ NodeReferenceBlob(Kind kind)
+#if !ASSERT_DISABLED
+ : m_kind(kind)
+#endif
+ {
+ if (kind == Variable) {
+ m_words[0].m_encodedWord = UINT_MAX;
+ m_words[1].m_encodedWord = UINT_MAX;
+ }
+ }
+
+ NodeReferenceBlob(Kind kind, NodeIndex child1, NodeIndex child2, NodeIndex child3)
+#if !ASSERT_DISABLED
+ : m_kind(Fixed)
+#endif
+ {
+ ASSERT_UNUSED(kind, kind == Fixed);
+ initialize(child1, child2, child3);
+ }
+
+ NodeReferenceBlob(Kind kind, unsigned firstChild, unsigned numChildren)
+#if !ASSERT_DISABLED
+ : m_kind(Variable)
+#endif
+ {
+ ASSERT_UNUSED(kind, kind == Variable);
+ setFirstChild(firstChild);
+ setNumChildren(numChildren);
+ }
+
+ const NodeUse& child(unsigned i) const
+ {
+ ASSERT(i < 3);
+ ASSERT(m_kind == Fixed);
+ return m_words[i];
+ }
+
+ NodeUse& child(unsigned i)
+ {
+ ASSERT(i < 3);
+ ASSERT(m_kind == Fixed);
+ return m_words[i];
+ }
+
+ void setChild(unsigned i, NodeUse nodeUse)
+ {
+ ASSERT(i < 30);
+ ASSERT(m_kind == Fixed);
+ m_words[i] = nodeUse;
+ }
+
+ NodeUse child1() const { return child(0); }
+ NodeUse child2() const { return child(1); }
+ NodeUse child3() const { return child(2); }
+
+ NodeUse& child1() { return child(0); }
+ NodeUse& child2() { return child(1); }
+ NodeUse& child3() { return child(2); }
+
+ void setChild1(NodeUse nodeUse) { setChild(0, nodeUse); }
+ void setChild2(NodeUse nodeUse) { setChild(1, nodeUse); }
+ void setChild3(NodeUse nodeUse) { setChild(2, nodeUse); }
+
+ NodeUse child1Unchecked() const { return m_words[0]; }
+
+ void initialize(NodeUse child1, NodeUse child2, NodeUse child3)
+ {
+ child(0) = child1;
+ child(1) = child2;
+ child(2) = child3;
+ }
+
+ void initialize(NodeIndex child1, NodeIndex child2, NodeIndex child3)
+ {
+ initialize(NodeUse(child1), NodeUse(child2), NodeUse(child3));
+ }
+
+ unsigned firstChild() const
+ {
+ ASSERT(m_kind == Variable);
+ return m_words[0].m_encodedWord;
+ }
+ void setFirstChild(unsigned firstChild)
+ {
+ ASSERT(m_kind == Variable);
+ m_words[0].m_encodedWord = firstChild;
+ }
+
+ unsigned numChildren() const
+ {
+ ASSERT(m_kind == Variable);
+ return m_words[1].m_encodedWord;
+ }
+ void setNumChildren(unsigned numChildren)
+ {
+ ASSERT(m_kind == Variable);
+ m_words[1].m_encodedWord = numChildren;
+ }
+
+private:
+ NodeUse m_words[3];
+#if !ASSERT_DISABLED
+ Kind m_kind;
+#endif
+};
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGNodeReferenceBlob_h
diff --git a/Source/JavaScriptCore/dfg/DFGNodeUse.h b/Source/JavaScriptCore/dfg/DFGNodeUse.h
new file mode 100644
index 000000000..71154997c
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGNodeUse.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DFGNodeUse_h
+#define DFGNodeUse_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGCommon.h"
+
+namespace JSC { namespace DFG {
+
+class NodeReferenceBlob;
+
+class NodeUse {
+public:
+ NodeUse()
+ : m_encodedWord(makeWord(NoNode, UntypedUse))
+ {
+ }
+
+ explicit NodeUse(NodeIndex nodeIndex)
+ : m_encodedWord(makeWord(nodeIndex, UntypedUse))
+ {
+ }
+
+ NodeUse(NodeIndex nodeIndex, UseKind useKind)
+ : m_encodedWord(makeWord(nodeIndex, useKind))
+ {
+ }
+
+ NodeIndex indexUnchecked() const { return m_encodedWord >> shift(); }
+ NodeIndex index() const
+ {
+ ASSERT(isSet());
+ return m_encodedWord >> shift();
+ }
+ void setIndex(NodeIndex nodeIndex)
+ {
+ m_encodedWord = makeWord(nodeIndex, useKind());
+ }
+
+ UseKind useKind() const
+ {
+ ASSERT(isSet());
+ unsigned masked = m_encodedWord & (((1 << shift()) - 1));
+ ASSERT(masked < LastUseKind);
+ return static_cast<UseKind>(masked);
+ }
+ void setUseKind(UseKind useKind)
+ {
+ ASSERT(isSet());
+ m_encodedWord = makeWord(index(), useKind);
+ }
+
+ bool isSet() const { return indexUnchecked() != NoNode; }
+ bool operator!() const { return !isSet(); }
+
+ bool operator==(NodeUse other) const
+ {
+ return m_encodedWord == other.m_encodedWord;
+ }
+ bool operator!=(NodeUse other) const
+ {
+ return m_encodedWord != other.m_encodedWord;
+ }
+
+private:
+ friend class NodeReferenceBlob;
+
+ static uint32_t shift() { return 4; }
+
+ static int32_t makeWord(NodeIndex nodeIndex, UseKind useKind)
+ {
+ ASSERT(static_cast<uint32_t>(((static_cast<int32_t>(nodeIndex) << shift()) >> shift())) == nodeIndex);
+ ASSERT(useKind >= 0 && useKind < LastUseKind);
+ ASSERT(LastUseKind <= (1 << shift()));
+ return (nodeIndex << shift()) | useKind;
+ }
+
+ int32_t m_encodedWord;
+};
+
+inline bool operator==(NodeUse nodeUse, NodeIndex nodeIndex)
+{
+ return nodeUse.indexUnchecked() == nodeIndex;
+}
+inline bool operator==(NodeIndex nodeIndex, NodeUse nodeUse)
+{
+ return nodeUse.indexUnchecked() == nodeIndex;
+}
+inline bool operator!=(NodeUse nodeUse, NodeIndex nodeIndex)
+{
+ return nodeUse.indexUnchecked() != nodeIndex;
+}
+inline bool operator!=(NodeIndex nodeIndex, NodeUse nodeUse)
+{
+ return nodeUse.indexUnchecked() != nodeIndex;
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGNodeUse_h
+
diff --git a/Source/JavaScriptCore/dfg/DFGOSRExit.cpp b/Source/JavaScriptCore/dfg/DFGOSRExit.cpp
index 7b1941146..113f2ea0d 100644
--- a/Source/JavaScriptCore/dfg/DFGOSRExit.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOSRExit.cpp
@@ -53,7 +53,6 @@ OSRExit::OSRExit(ExitKind kind, JSValueSource jsValueSource, ValueProfile* value
m_variables[variable] = jit->computeValueRecoveryFor(jit->m_variables[variable]);
}
-#ifndef NDEBUG
void OSRExit::dump(FILE* out) const
{
for (unsigned argument = 0; argument < m_arguments.size(); ++argument)
@@ -62,7 +61,6 @@ void OSRExit::dump(FILE* out) const
for (unsigned variable = 0; variable < m_variables.size(); ++variable)
m_variables[variable].dump(out);
}
-#endif
bool OSRExit::considerAddingAsFrequentExitSiteSlow(CodeBlock* dfgCodeBlock, CodeBlock* profiledCodeBlock)
{
diff --git a/Source/JavaScriptCore/dfg/DFGOSRExit.h b/Source/JavaScriptCore/dfg/DFGOSRExit.h
index cf96f4f3a..8e3fa6a5d 100644
--- a/Source/JavaScriptCore/dfg/DFGOSRExit.h
+++ b/Source/JavaScriptCore/dfg/DFGOSRExit.h
@@ -137,9 +137,7 @@ struct OSRExit {
return considerAddingAsFrequentExitSiteSlow(dfgCodeBlock, profiledCodeBlock);
}
-#ifndef NDEBUG
void dump(FILE* out) const;
-#endif
Vector<ValueRecovery, 0> m_arguments;
Vector<ValueRecovery, 0> m_variables;
diff --git a/Source/JavaScriptCore/dfg/DFGPropagator.cpp b/Source/JavaScriptCore/dfg/DFGPropagator.cpp
index acfd2d364..f00f13e96 100644
--- a/Source/JavaScriptCore/dfg/DFGPropagator.cpp
+++ b/Source/JavaScriptCore/dfg/DFGPropagator.cpp
@@ -138,8 +138,6 @@ private:
break;
}
- case ValueToNumber:
- case ValueToDouble:
case UInt32ToNumber: {
changed |= m_graph[node.child1()].mergeArithNodeFlags(flags);
break;
@@ -147,7 +145,7 @@ private:
case ArithAdd:
case ValueAdd: {
- if (isNotNegZero(node.child1()) || isNotNegZero(node.child2()))
+ if (isNotNegZero(node.child1().index()) || isNotNegZero(node.child2().index()))
flags &= ~NodeNeedsNegZero;
changed |= m_graph[node.child1()].mergeArithNodeFlags(flags);
@@ -156,7 +154,7 @@ private:
}
case ArithSub: {
- if (isNotZero(node.child1()) || isNotZero(node.child2()))
+ if (isNotZero(node.child1().index()) || isNotZero(node.child2().index()))
flags &= ~NodeNeedsNegZero;
changed |= m_graph[node.child1()].mergeArithNodeFlags(flags);
@@ -210,13 +208,13 @@ private:
for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); childIdx++)
changed |= m_graph[m_graph.m_varArgChildren[childIdx]].mergeArithNodeFlags(flags);
} else {
- if (node.child1() == NoNode)
+ if (!node.child1())
break;
changed |= m_graph[node.child1()].mergeArithNodeFlags(flags);
- if (node.child2() == NoNode)
+ if (!node.child2())
break;
changed |= m_graph[node.child2()].mergeArithNodeFlags(flags);
- if (node.child3() == NoNode)
+ if (!node.child3())
break;
changed |= m_graph[node.child3()].mergeArithNodeFlags(flags);
}
@@ -363,19 +361,6 @@ private:
break;
}
- case ValueToNumber: {
- PredictedType prediction = m_graph[node.child1()].prediction();
-
- if (prediction) {
- if (!(prediction & PredictDouble) && nodeCanSpeculateInteger(node.arithNodeFlags()))
- changed |= mergePrediction(PredictInt32);
- else
- changed |= mergePrediction(PredictNumber);
- }
-
- break;
- }
-
case ValueAdd: {
PredictedType left = m_graph[node.child1()].prediction();
PredictedType right = m_graph[node.child2()].prediction();
@@ -597,7 +582,6 @@ private:
break;
}
- case ValueToDouble:
case GetArrayLength:
case GetByteArrayLength:
case GetInt8ArrayLength:
@@ -676,21 +660,19 @@ private:
propagateNodePredictions(m_graph[m_compileIndex]);
}
- void vote(NodeIndex nodeIndex, VariableAccessData::Ballot ballot)
+ void vote(NodeUse nodeUse, VariableAccessData::Ballot ballot)
{
- switch (m_graph[nodeIndex].op) {
- case ValueToNumber:
- case ValueToDouble:
+ switch (m_graph[nodeUse].op) {
case ValueToInt32:
case UInt32ToNumber:
- nodeIndex = m_graph[nodeIndex].child1();
+ nodeUse = m_graph[nodeUse].child1();
break;
default:
break;
}
- if (m_graph[nodeIndex].op == GetLocal)
- m_graph[nodeIndex].variableAccessData()->vote(ballot);
+ if (m_graph[nodeUse].op == GetLocal)
+ m_graph[nodeUse].variableAccessData()->vote(ballot);
}
void vote(Node& node, VariableAccessData::Ballot ballot)
@@ -701,13 +683,13 @@ private:
return;
}
- if (node.child1() == NoNode)
+ if (!node.child1())
return;
vote(node.child1(), ballot);
- if (node.child2() == NoNode)
+ if (!node.child2())
return;
vote(node.child2(), ballot);
- if (node.child3() == NoNode)
+ if (!node.child3())
return;
vote(node.child3(), ballot);
}
@@ -775,11 +757,6 @@ private:
vote(node.child1(), VariableAccessData::VoteDouble);
break;
- case ValueToNumber:
- case ValueToDouble:
- // Don't vote.
- break;
-
case SetLocal: {
PredictedType prediction = m_graph[node.child1()].prediction();
if (isDoublePrediction(prediction))
@@ -835,16 +812,6 @@ private:
} while (m_changed);
}
- void toDouble(NodeIndex nodeIndex)
- {
- if (m_graph[nodeIndex].op == ValueToNumber) {
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- printf(" @%u -> ValueToDouble", nodeIndex);
-#endif
- m_graph[nodeIndex].op = ValueToDouble;
- }
- }
-
void fixupNode(Node& node)
{
if (!node.shouldGenerate())
@@ -857,60 +824,6 @@ private:
#endif
switch (op) {
- case ValueAdd:
- case ArithAdd:
- case ArithSub: {
- PredictedType left = m_graph[node.child1()].prediction();
- PredictedType right = m_graph[node.child2()].prediction();
-
- if (left && right
- && isNumberPrediction(left) && isNumberPrediction(right)
- && !m_graph.addShouldSpeculateInteger(node, m_codeBlock)) {
- toDouble(node.child1());
- toDouble(node.child2());
- }
- break;
- }
-
- case ArithMul:
- case ArithMin:
- case ArithMax:
- case ArithMod:
- case ArithDiv: {
- if (!nodeCanSpeculateInteger(node.arithNodeFlags())) {
- toDouble(node.child1());
- toDouble(node.child2());
- break;
- }
-
- PredictedType left = m_graph[node.child1()].prediction();
- PredictedType right = m_graph[node.child2()].prediction();
-
- if (left && right
- && ((left & PredictDouble) || (right & PredictDouble))) {
- toDouble(node.child1());
- toDouble(node.child2());
- }
- break;
- }
-
- case ArithAbs: {
- if (!nodeCanSpeculateInteger(node.arithNodeFlags())) {
- toDouble(node.child1());
- break;
- }
-
- PredictedType prediction = m_graph[node.child1()].prediction();
- if (prediction & PredictDouble)
- toDouble(node.child1());
- break;
- }
-
- case ArithSqrt: {
- toDouble(node.child1());
- break;
- }
-
case GetById: {
if (!isInt32Prediction(m_graph[m_compileIndex].prediction()))
break;
@@ -977,8 +890,8 @@ private:
case GetByVal:
case StringCharAt:
case StringCharCodeAt: {
- if (node.child3() != NoNode && m_graph[node.child3()].op == Nop)
- node.children.fixed.child3 = NoNode;
+ if (!!node.child3() && m_graph[node.child3()].op == Nop)
+ node.children.child3() = NodeUse();
break;
}
default:
@@ -1004,14 +917,15 @@ private:
if (nodeIndex == NoNode)
return NoNode;
- if (m_graph[nodeIndex].op == ValueToNumber)
- nodeIndex = m_graph[nodeIndex].child1();
-
if (m_graph[nodeIndex].op == ValueToInt32)
- nodeIndex = m_graph[nodeIndex].child1();
+ nodeIndex = m_graph[nodeIndex].child1().index();
return nodeIndex;
}
+ NodeIndex canonicalize(NodeUse nodeUse)
+ {
+ return canonicalize(nodeUse.indexUnchecked());
+ }
// Computes where the search for a candidate for CSE should start. Don't call
// this directly; call startIndex() instead as it does logging in debug mode.
@@ -1061,7 +975,10 @@ private:
NodeIndex startIndex()
{
Node& node = m_graph[m_compileIndex];
- return startIndexForChildren(node.child1(), node.child2(), node.child3());
+ return startIndexForChildren(
+ node.child1().indexUnchecked(),
+ node.child2().indexUnchecked(),
+ node.child3().indexUnchecked());
}
NodeIndex endIndexForPureCSE()
@@ -1207,7 +1124,7 @@ private:
break;
case PutGlobalVar:
if (node.varNumber() == varNumber && m_codeBlock->globalObjectFor(node.codeOrigin) == globalObject)
- return node.child1();
+ return node.child1().index();
break;
default:
break;
@@ -1235,7 +1152,7 @@ private:
if (!byValIsPure(node))
return NoNode;
if (node.child1() == child1 && canonicalize(node.child2()) == canonicalize(child2))
- return node.child3();
+ return node.child3().index();
// We must assume that the PutByVal will clobber the location we're getting from.
// FIXME: We can do better; if we know that the PutByVal is accessing an array of a
// different type than the GetByVal, then we know that they won't clobber each other.
@@ -1328,7 +1245,7 @@ private:
case PutByOffset:
if (m_graph.m_storageAccessData[node.storageAccessDataIndex()].identifierNumber == identifierNumber) {
if (node.child2() == child1)
- return node.child3();
+ return node.child3().index();
return NoNode;
}
break;
@@ -1442,22 +1359,22 @@ private:
return NoNode;
}
- void performSubstitution(NodeIndex& child, bool addRef = true)
+ void performSubstitution(NodeUse& child, bool addRef = true)
{
// Check if this operand is actually unused.
- if (child == NoNode)
+ if (!child)
return;
// Check if there is any replacement.
- NodeIndex replacement = m_replacements[child];
+ NodeIndex replacement = m_replacements[child.index()];
if (replacement == NoNode)
return;
- child = replacement;
+ child.setIndex(replacement);
// There is definitely a replacement. Assert that the replacement does not
// have a replacement.
- ASSERT(m_replacements[child] == NoNode);
+ ASSERT(m_replacements[child.index()] == NoNode);
if (addRef)
m_graph[child].ref();
@@ -1505,9 +1422,9 @@ private:
for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); childIdx++)
performSubstitution(m_graph.m_varArgChildren[childIdx], shouldGenerate);
} else {
- performSubstitution(node.children.fixed.child1, shouldGenerate);
- performSubstitution(node.children.fixed.child2, shouldGenerate);
- performSubstitution(node.children.fixed.child3, shouldGenerate);
+ performSubstitution(node.children.child1(), shouldGenerate);
+ performSubstitution(node.children.child2(), shouldGenerate);
+ performSubstitution(node.children.child3(), shouldGenerate);
}
if (!shouldGenerate)
@@ -1602,37 +1519,37 @@ private:
case GetByVal:
if (byValIsPure(node))
- setReplacement(getByValLoadElimination(node.child1(), node.child2()));
+ setReplacement(getByValLoadElimination(node.child1().index(), node.child2().index()));
break;
case PutByVal:
- if (byValIsPure(node) && getByValLoadElimination(node.child1(), node.child2()) != NoNode)
+ if (byValIsPure(node) && getByValLoadElimination(node.child1().index(), node.child2().index()) != NoNode)
node.op = PutByValAlias;
break;
case CheckStructure:
- if (checkStructureLoadElimination(node.structureSet(), node.child1()))
+ if (checkStructureLoadElimination(node.structureSet(), node.child1().index()))
eliminate();
break;
case CheckFunction:
- if (checkFunctionElimination(node.function(), node.child1()))
+ if (checkFunctionElimination(node.function(), node.child1().index()))
eliminate();
break;
case GetIndexedPropertyStorage: {
PredictedType basePrediction = m_graph[node.child2()].prediction();
bool nodeHasIntegerIndexPrediction = !(!(basePrediction & PredictInt32) && basePrediction);
- setReplacement(getIndexedPropertyStorageLoadElimination(node.child1(), nodeHasIntegerIndexPrediction));
+ setReplacement(getIndexedPropertyStorageLoadElimination(node.child1().index(), nodeHasIntegerIndexPrediction));
break;
}
case GetPropertyStorage:
- setReplacement(getPropertyStorageLoadElimination(node.child1()));
+ setReplacement(getPropertyStorageLoadElimination(node.child1().index()));
break;
case GetByOffset:
- setReplacement(getByOffsetLoadElimination(m_graph.m_storageAccessData[node.storageAccessDataIndex()].identifierNumber, node.child1()));
+ setReplacement(getByOffsetLoadElimination(m_graph.m_storageAccessData[node.storageAccessDataIndex()].identifierNumber, node.child1().index()));
break;
default:
diff --git a/Source/JavaScriptCore/dfg/DFGScoreBoard.h b/Source/JavaScriptCore/dfg/DFGScoreBoard.h
index 7f9211a26..cc3272812 100644
--- a/Source/JavaScriptCore/dfg/DFGScoreBoard.h
+++ b/Source/JavaScriptCore/dfg/DFGScoreBoard.h
@@ -28,7 +28,7 @@
#if ENABLE(DFG_JIT)
-#include <dfg/DFGGraph.h>
+#include "DFGGraph.h"
#include <wtf/BitVector.h>
#include <wtf/Vector.h>
@@ -106,6 +106,10 @@ public:
m_free.append(index);
}
}
+ void use(NodeUse child)
+ {
+ use(child.indexUnchecked());
+ }
unsigned highWatermark()
{
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
index e647fb87a..77b3e54b1 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
@@ -87,22 +87,22 @@ void SpeculativeJIT::useChildren(Node& node)
for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); childIdx++)
use(m_jit.graph().m_varArgChildren[childIdx]);
} else {
- NodeIndex child1 = node.child1();
- if (child1 == NoNode) {
- ASSERT(node.child2() == NoNode && node.child3() == NoNode);
+ NodeUse child1 = node.child1();
+ if (!child1) {
+ ASSERT(!node.child2() && !node.child3());
return;
}
use(child1);
- NodeIndex child2 = node.child2();
- if (child2 == NoNode) {
- ASSERT(node.child3() == NoNode);
+ NodeUse child2 = node.child2();
+ if (!child2) {
+ ASSERT(!node.child3());
return;
}
use(child2);
- NodeIndex child3 = node.child3();
- if (child3 == NoNode)
+ NodeUse child3 = node.child3();
+ if (!child3)
return;
use(child3);
}
@@ -249,7 +249,7 @@ void SpeculativeJIT::markCellCard(MacroAssembler& jit, GPRReg owner, GPRReg scra
#endif
}
-void SpeculativeJIT::writeBarrier(GPRReg ownerGPR, GPRReg valueGPR, NodeIndex valueIndex, WriteBarrierUseKind useKind, GPRReg scratch1, GPRReg scratch2)
+void SpeculativeJIT::writeBarrier(GPRReg ownerGPR, GPRReg valueGPR, NodeUse valueUse, WriteBarrierUseKind useKind, GPRReg scratch1, GPRReg scratch2)
{
UNUSED_PARAM(ownerGPR);
UNUSED_PARAM(valueGPR);
@@ -257,7 +257,7 @@ void SpeculativeJIT::writeBarrier(GPRReg ownerGPR, GPRReg valueGPR, NodeIndex va
UNUSED_PARAM(scratch2);
UNUSED_PARAM(useKind);
- if (isKnownNotCell(valueIndex))
+ if (isKnownNotCell(valueUse.index()))
return;
#if ENABLE(WRITE_BARRIER_PROFILING)
@@ -280,7 +280,7 @@ void SpeculativeJIT::writeBarrier(GPRReg ownerGPR, GPRReg valueGPR, NodeIndex va
JITCompiler::Jump rhsNotCell;
bool hadCellCheck = false;
- if (!isKnownCell(valueIndex) && !isCellPrediction(m_jit.getPrediction(valueIndex))) {
+ if (!isKnownCell(valueUse.index()) && !isCellPrediction(m_jit.getPrediction(valueUse.index()))) {
hadCellCheck = true;
rhsNotCell = m_jit.branchIfNotCell(valueGPR);
}
@@ -325,14 +325,14 @@ void SpeculativeJIT::writeBarrier(GPRReg ownerGPR, JSCell* value, WriteBarrierUs
#endif
}
-void SpeculativeJIT::writeBarrier(JSCell* owner, GPRReg valueGPR, NodeIndex valueIndex, WriteBarrierUseKind useKind, GPRReg scratch)
+void SpeculativeJIT::writeBarrier(JSCell* owner, GPRReg valueGPR, NodeUse valueUse, WriteBarrierUseKind useKind, GPRReg scratch)
{
UNUSED_PARAM(owner);
UNUSED_PARAM(valueGPR);
UNUSED_PARAM(scratch);
UNUSED_PARAM(useKind);
- if (isKnownNotCell(valueIndex))
+ if (isKnownNotCell(valueUse.index()))
return;
#if ENABLE(WRITE_BARRIER_PROFILING)
@@ -342,7 +342,7 @@ void SpeculativeJIT::writeBarrier(JSCell* owner, GPRReg valueGPR, NodeIndex valu
#if ENABLE(GGC)
JITCompiler::Jump rhsNotCell;
bool hadCellCheck = false;
- if (!isKnownCell(valueIndex) && !isCellPrediction(m_jit.getPrediction(valueIndex))) {
+ if (!isKnownCell(valueUse.index()) && !isCellPrediction(m_jit.getPrediction(valueUse.index()))) {
hadCellCheck = true;
rhsNotCell = m_jit.branchIfNotCell(valueGPR);
}
@@ -383,7 +383,7 @@ bool SpeculativeJIT::nonSpeculativeCompare(Node& node, MacroAssembler::Relationa
bool SpeculativeJIT::nonSpeculativeStrictEq(Node& node, bool invert)
{
- if (!invert && (isKnownNumeric(node.child1()) || isKnownNumeric(node.child2())))
+ if (!invert && (isKnownNumeric(node.child1().index()) || isKnownNumeric(node.child2().index())))
return nonSpeculativeCompare(node, MacroAssembler::Equal, operationCompareStrictEq);
NodeIndex branchNodeIndex = detectPeepHoleBranch();
@@ -831,9 +831,9 @@ void SpeculativeJIT::compilePeepHoleObjectEquality(Node& node, NodeIndex branchN
GPRReg op2GPR = op2.gpr();
if (!predictionCheck(m_state.forNode(node.child1()).m_type))
- speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1GPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(classInfo)));
+ speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), node.child1().index(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1GPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(classInfo)));
if (!predictionCheck(m_state.forNode(node.child2()).m_type))
- speculationCheck(BadType, JSValueSource::unboxedCell(op2GPR), node.child2(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op2GPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(classInfo)));
+ speculationCheck(BadType, JSValueSource::unboxedCell(op2GPR), node.child2().index(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op2GPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(classInfo)));
addBranch(m_jit.branchPtr(condition, op1GPR, op2GPR), taken);
if (notTaken != (m_block + 1))
@@ -855,13 +855,13 @@ void SpeculativeJIT::compilePeepHoleIntegerBranch(Node& node, NodeIndex branchNo
notTaken = tmp;
}
- if (isInt32Constant(node.child1())) {
- int32_t imm = valueOfInt32Constant(node.child1());
+ if (isInt32Constant(node.child1().index())) {
+ int32_t imm = valueOfInt32Constant(node.child1().index());
SpeculateIntegerOperand op2(this, node.child2());
addBranch(m_jit.branch32(condition, JITCompiler::Imm32(imm), op2.gpr()), taken);
- } else if (isInt32Constant(node.child2())) {
+ } else if (isInt32Constant(node.child2().index())) {
SpeculateIntegerOperand op1(this, node.child1());
- int32_t imm = valueOfInt32Constant(node.child2());
+ int32_t imm = valueOfInt32Constant(node.child2().index());
addBranch(m_jit.branch32(condition, op1.gpr(), JITCompiler::Imm32(imm)), taken);
} else {
SpeculateIntegerOperand op1(this, node.child1());
@@ -913,7 +913,7 @@ void SpeculativeJIT::compileMovHint(Node& node)
{
ASSERT(node.op == SetLocal);
- setNodeIndexForOperand(node.child1(), node.local());
+ setNodeIndexForOperand(node.child1().index(), node.local());
m_lastSetOperand = node.local();
}
@@ -1268,15 +1268,8 @@ ValueRecovery SpeculativeJIT::computeValueRecoveryFor(const ValueSource& valueSo
// Try to see if there is an alternate node that would contain the value we want.
// There are four possibilities:
//
- // ValueToNumber: If the only live version of the value is a ValueToNumber node
- // then it means that all remaining uses of the value would have performed a
- // ValueToNumber conversion anyway. Thus, we can substitute ValueToNumber.
- //
- // ValueToInt32: Likewise, if the only remaining live version of the value is
- // ValueToInt32, then we can use it. But if there is both a ValueToInt32
- // and a ValueToNumber, then we better go with ValueToNumber because it
- // means that some remaining uses would have converted to number while
- // others would have converted to Int32.
+ // ValueToInt32: If the only remaining live version of the value is
+ // ValueToInt32, then we can use it.
//
// UInt32ToNumber: If the only live version of the value is a UInt32ToNumber
// then the only remaining uses are ones that want a properly formed number
@@ -1289,7 +1282,7 @@ ValueRecovery SpeculativeJIT::computeValueRecoveryFor(const ValueSource& valueSo
bool found = false;
if (nodePtr->op == UInt32ToNumber) {
- NodeIndex nodeIndex = nodePtr->child1();
+ NodeIndex nodeIndex = nodePtr->child1().index();
nodePtr = &at(nodeIndex);
infoPtr = &m_generationInfo[nodePtr->virtualRegister()];
if (infoPtr->alive() && infoPtr->nodeIndex() == nodeIndex)
@@ -1297,7 +1290,6 @@ ValueRecovery SpeculativeJIT::computeValueRecoveryFor(const ValueSource& valueSo
}
if (!found) {
- NodeIndex valueToNumberIndex = NoNode;
NodeIndex valueToInt32Index = NoNode;
NodeIndex uint32ToNumberIndex = NoNode;
@@ -1311,10 +1303,6 @@ ValueRecovery SpeculativeJIT::computeValueRecoveryFor(const ValueSource& valueSo
if (node.child1Unchecked() != valueSource.nodeIndex())
continue;
switch (node.op) {
- case ValueToNumber:
- case ValueToDouble:
- valueToNumberIndex = info.nodeIndex();
- break;
case ValueToInt32:
valueToInt32Index = info.nodeIndex();
break;
@@ -1327,9 +1315,7 @@ ValueRecovery SpeculativeJIT::computeValueRecoveryFor(const ValueSource& valueSo
}
NodeIndex nodeIndexToUse;
- if (valueToNumberIndex != NoNode)
- nodeIndexToUse = valueToNumberIndex;
- else if (valueToInt32Index != NoNode)
+ if (valueToInt32Index != NoNode)
nodeIndexToUse = valueToInt32Index;
else if (uint32ToNumberIndex != NoNode)
nodeIndexToUse = uint32ToNumberIndex;
@@ -1594,16 +1580,16 @@ static void compileClampDoubleToByte(JITCompiler& jit, GPRReg result, FPRReg sou
void SpeculativeJIT::compilePutByValForByteArray(GPRReg base, GPRReg property, Node& node)
{
- NodeIndex baseIndex = node.child1();
- NodeIndex valueIndex = node.child3();
+ NodeUse baseUse = node.child1();
+ NodeUse valueUse = node.child3();
- if (!isByteArrayPrediction(m_state.forNode(baseIndex).m_type))
- speculationCheck(BadType, JSValueSource::unboxedCell(base), baseIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(base, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSByteArray::s_info)));
+ if (!isByteArrayPrediction(m_state.forNode(baseUse).m_type))
+ speculationCheck(BadType, JSValueSource::unboxedCell(base), baseUse.index(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(base, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSByteArray::s_info)));
GPRTemporary value;
GPRReg valueGPR;
- if (at(valueIndex).isConstant()) {
- JSValue jsValue = valueOfJSConstant(valueIndex);
+ if (at(valueUse).isConstant()) {
+ JSValue jsValue = valueOfJSConstant(valueUse.index());
if (!jsValue.isNumber()) {
terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
noResult(m_compileIndex);
@@ -1615,8 +1601,8 @@ void SpeculativeJIT::compilePutByValForByteArray(GPRReg base, GPRReg property, N
m_jit.move(Imm32(clampedValue), scratchReg);
value.adopt(scratch);
valueGPR = scratchReg;
- } else if (!at(valueIndex).shouldNotSpeculateInteger()) {
- SpeculateIntegerOperand valueOp(this, valueIndex);
+ } else if (!at(valueUse).shouldNotSpeculateInteger()) {
+ SpeculateIntegerOperand valueOp(this, valueUse);
GPRTemporary scratch(this);
GPRReg scratchReg = scratch.gpr();
m_jit.move(valueOp.gpr(), scratchReg);
@@ -1624,7 +1610,7 @@ void SpeculativeJIT::compilePutByValForByteArray(GPRReg base, GPRReg property, N
value.adopt(scratch);
valueGPR = scratchReg;
} else {
- SpeculateDoubleOperand valueOp(this, valueIndex);
+ SpeculateDoubleOperand valueOp(this, valueUse);
GPRTemporary result(this);
FPRTemporary floatScratch(this);
FPRReg fpr = valueOp.fpr();
@@ -1745,16 +1731,16 @@ void SpeculativeJIT::compileGetByValOnIntTypedArray(const TypedArrayDescriptor&
void SpeculativeJIT::compilePutByValForIntTypedArray(const TypedArrayDescriptor& descriptor, GPRReg base, GPRReg property, Node& node, size_t elementSize, TypedArraySpeculationRequirements speculationRequirements, TypedArraySignedness signedness, TypedArrayRounding rounding)
{
- NodeIndex baseIndex = node.child1();
- NodeIndex valueIndex = node.child3();
+ NodeUse baseUse = node.child1();
+ NodeUse valueUse = node.child3();
if (speculationRequirements != NoTypedArrayTypeSpecCheck)
- speculationCheck(BadType, JSValueSource::unboxedCell(base), baseIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(base, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
+ speculationCheck(BadType, JSValueSource::unboxedCell(base), baseUse, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(base, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
GPRTemporary value;
GPRReg valueGPR;
- if (at(valueIndex).isConstant()) {
- JSValue jsValue = valueOfJSConstant(valueIndex);
+ if (at(valueUse).isConstant()) {
+ JSValue jsValue = valueOfJSConstant(valueUse.index());
if (!jsValue.isNumber()) {
terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
noResult(m_compileIndex);
@@ -1770,8 +1756,8 @@ void SpeculativeJIT::compilePutByValForIntTypedArray(const TypedArrayDescriptor&
m_jit.move(Imm32(static_cast<int>(d)), scratchReg);
value.adopt(scratch);
valueGPR = scratchReg;
- } else if (!at(valueIndex).shouldNotSpeculateInteger()) {
- SpeculateIntegerOperand valueOp(this, valueIndex);
+ } else if (!at(valueUse).shouldNotSpeculateInteger()) {
+ SpeculateIntegerOperand valueOp(this, valueUse);
GPRTemporary scratch(this);
GPRReg scratchReg = scratch.gpr();
m_jit.move(valueOp.gpr(), scratchReg);
@@ -1783,7 +1769,7 @@ void SpeculativeJIT::compilePutByValForIntTypedArray(const TypedArrayDescriptor&
valueGPR = scratchReg;
} else if (rounding == ClampRounding) {
ASSERT(elementSize == 1);
- SpeculateDoubleOperand valueOp(this, valueIndex);
+ SpeculateDoubleOperand valueOp(this, valueUse);
GPRTemporary result(this);
FPRTemporary floatScratch(this);
FPRReg fpr = valueOp.fpr();
@@ -1792,7 +1778,7 @@ void SpeculativeJIT::compilePutByValForIntTypedArray(const TypedArrayDescriptor&
value.adopt(result);
valueGPR = gpr;
} else {
- SpeculateDoubleOperand valueOp(this, valueIndex);
+ SpeculateDoubleOperand valueOp(this, valueUse);
GPRTemporary result(this);
FPRReg fpr = valueOp.fpr();
GPRReg gpr = result.gpr();
@@ -1891,13 +1877,13 @@ void SpeculativeJIT::compileGetByValOnFloatTypedArray(const TypedArrayDescriptor
void SpeculativeJIT::compilePutByValForFloatTypedArray(const TypedArrayDescriptor& descriptor, GPRReg base, GPRReg property, Node& node, size_t elementSize, TypedArraySpeculationRequirements speculationRequirements)
{
- NodeIndex baseIndex = node.child1();
- NodeIndex valueIndex = node.child3();
+ NodeUse baseUse = node.child1();
+ NodeUse valueUse = node.child3();
- SpeculateDoubleOperand valueOp(this, valueIndex);
+ SpeculateDoubleOperand valueOp(this, valueUse);
if (speculationRequirements != NoTypedArrayTypeSpecCheck)
- speculationCheck(BadType, JSValueSource::unboxedCell(base), baseIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(base, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
+ speculationCheck(BadType, JSValueSource::unboxedCell(base), baseUse.index(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(base, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
GPRTemporary result(this);
@@ -2042,8 +2028,8 @@ void SpeculativeJIT::compileSoftModulo(Node& node)
SpeculateStrictInt32Operand op1(this, node.child1());
GPRReg op1Gpr = op1.gpr();
- if (isInt32Constant(node.child2())) {
- int32_t divisor = valueOfInt32Constant(node.child2());
+ if (isInt32Constant(node.child2().index())) {
+ int32_t divisor = valueOfInt32Constant(node.child2().index());
if (divisor < 0)
divisor = -divisor;
@@ -2199,8 +2185,8 @@ void SpeculativeJIT::compileSoftModulo(Node& node)
void SpeculativeJIT::compileAdd(Node& node)
{
if (m_jit.graph().addShouldSpeculateInteger(node, m_jit.codeBlock())) {
- if (isNumberConstant(node.child1())) {
- int32_t imm1 = valueOfNumberConstantAsInt32(node.child1());
+ if (isNumberConstant(node.child1().index())) {
+ int32_t imm1 = valueOfNumberConstantAsInt32(node.child1().index());
SpeculateIntegerOperand op2(this, node.child2());
GPRTemporary result(this);
@@ -2214,9 +2200,9 @@ void SpeculativeJIT::compileAdd(Node& node)
return;
}
- if (isNumberConstant(node.child2())) {
+ if (isNumberConstant(node.child2().index())) {
SpeculateIntegerOperand op1(this, node.child1());
- int32_t imm2 = valueOfNumberConstantAsInt32(node.child2());
+ int32_t imm2 = valueOfNumberConstantAsInt32(node.child2().index());
GPRTemporary result(this);
if (nodeCanTruncateInteger(node.arithNodeFlags())) {
@@ -2279,9 +2265,9 @@ void SpeculativeJIT::compileAdd(Node& node)
void SpeculativeJIT::compileArithSub(Node& node)
{
if (m_jit.graph().addShouldSpeculateInteger(node, m_jit.codeBlock())) {
- if (isNumberConstant(node.child2())) {
+ if (isNumberConstant(node.child2().index())) {
SpeculateIntegerOperand op1(this, node.child1());
- int32_t imm2 = valueOfNumberConstantAsInt32(node.child2());
+ int32_t imm2 = valueOfNumberConstantAsInt32(node.child2().index());
GPRTemporary result(this);
if (nodeCanTruncateInteger(node.arithNodeFlags())) {
@@ -2294,8 +2280,8 @@ void SpeculativeJIT::compileArithSub(Node& node)
return;
}
- if (isNumberConstant(node.child1())) {
- int32_t imm1 = valueOfNumberConstantAsInt32(node.child1());
+ if (isNumberConstant(node.child1().index())) {
+ int32_t imm1 = valueOfNumberConstantAsInt32(node.child1().index());
SpeculateIntegerOperand op2(this, node.child2());
GPRTemporary result(this);
@@ -2421,7 +2407,7 @@ bool SpeculativeJIT::compare(Node& node, MacroAssembler::RelationalCondition con
return false;
}
-bool SpeculativeJIT::compileStrictEqForConstant(Node& node, NodeIndex value, JSValue constant)
+bool SpeculativeJIT::compileStrictEqForConstant(Node& node, NodeUse value, JSValue constant)
{
JSValueOperand op1(this, value);
@@ -2498,14 +2484,14 @@ bool SpeculativeJIT::compileStrictEq(Node& node)
// 1) If either operand is a constant and that constant is not a double, integer,
// or string, then do a JSValue comparison.
- if (isJSConstant(node.child1())) {
- JSValue value = valueOfJSConstant(node.child1());
+ if (isJSConstant(node.child1().index())) {
+ JSValue value = valueOfJSConstant(node.child1().index());
if (!value.isNumber() && !value.isString())
return compileStrictEqForConstant(node, node.child2(), value);
}
- if (isJSConstant(node.child2())) {
- JSValue value = valueOfJSConstant(node.child2());
+ if (isJSConstant(node.child2().index())) {
+ JSValue value = valueOfJSConstant(node.child2().index());
if (!value.isNumber() && !value.isString())
return compileStrictEqForConstant(node, node.child1(), value);
}
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
index 0098da3a1..cfb2189cf 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
@@ -33,6 +33,7 @@
#include "DFGJITCompiler.h"
#include "DFGOSRExit.h"
#include "DFGOperations.h"
+#include "MarkedAllocator.h"
#include "ValueRecovery.h"
namespace JSC { namespace DFG {
@@ -181,6 +182,10 @@ public:
{
return m_jit.graph()[nodeIndex];
}
+ Node& at(NodeUse nodeUse)
+ {
+ return at(nodeUse.index());
+ }
GPRReg fillInteger(NodeIndex, DataFormat& returnFormat);
FPRReg fillDouble(NodeIndex);
@@ -217,6 +222,10 @@ public:
GenerationInfo& info = m_generationInfo[virtualRegister];
return info.canReuse();
}
+ bool canReuse(NodeUse nodeUse)
+ {
+ return canReuse(nodeUse.index());
+ }
GPRReg reuse(GPRReg reg)
{
m_gprs.lock(reg);
@@ -317,13 +326,17 @@ public:
m_gprs.release(info.gpr());
#endif
}
+ void use(NodeUse nodeUse)
+ {
+ use(nodeUse.index());
+ }
static void markCellCard(MacroAssembler&, GPRReg ownerGPR, GPRReg scratchGPR1, GPRReg scratchGPR2);
static void writeBarrier(MacroAssembler&, GPRReg ownerGPR, GPRReg scratchGPR1, GPRReg scratchGPR2, WriteBarrierUseKind);
- void writeBarrier(GPRReg ownerGPR, GPRReg valueGPR, NodeIndex valueIndex, WriteBarrierUseKind, GPRReg scratchGPR1 = InvalidGPRReg, GPRReg scratchGPR2 = InvalidGPRReg);
+ void writeBarrier(GPRReg ownerGPR, GPRReg valueGPR, NodeUse valueUse, WriteBarrierUseKind, GPRReg scratchGPR1 = InvalidGPRReg, GPRReg scratchGPR2 = InvalidGPRReg);
void writeBarrier(GPRReg ownerGPR, JSCell* value, WriteBarrierUseKind, GPRReg scratchGPR1 = InvalidGPRReg, GPRReg scratchGPR2 = InvalidGPRReg);
- void writeBarrier(JSCell* owner, GPRReg valueGPR, NodeIndex valueIndex, WriteBarrierUseKind, GPRReg scratchGPR1 = InvalidGPRReg);
+ void writeBarrier(JSCell* owner, GPRReg valueGPR, NodeUse valueUse, WriteBarrierUseKind, GPRReg scratchGPR1 = InvalidGPRReg);
static GPRReg selectScratchGPR(GPRReg preserve1 = InvalidGPRReg, GPRReg preserve2 = InvalidGPRReg, GPRReg preserve3 = InvalidGPRReg, GPRReg preserve4 = InvalidGPRReg)
{
@@ -874,7 +887,7 @@ private:
// Check if the lastNode is a branch on this node.
Node& lastNode = at(lastNodeIndex);
- return lastNode.op == Branch && lastNode.child1() == m_compileIndex ? lastNodeIndex : NoNode;
+ return lastNode.op == Branch && lastNode.child1().index() == m_compileIndex ? lastNodeIndex : NoNode;
}
void nonSpeculativeValueToNumber(Node&);
@@ -884,15 +897,15 @@ private:
enum SpillRegistersMode { NeedToSpill, DontSpill };
#if USE(JSVALUE64)
JITCompiler::Call cachedGetById(CodeOrigin, GPRReg baseGPR, GPRReg resultGPR, GPRReg scratchGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill);
- void cachedPutById(CodeOrigin, GPRReg base, GPRReg value, NodeIndex valueIndex, GPRReg scratchGPR, unsigned identifierNumber, PutKind, JITCompiler::Jump slowPathTarget = JITCompiler::Jump());
+ void cachedPutById(CodeOrigin, GPRReg base, GPRReg value, NodeUse valueUse, GPRReg scratchGPR, unsigned identifierNumber, PutKind, JITCompiler::Jump slowPathTarget = JITCompiler::Jump());
#elif USE(JSVALUE32_64)
JITCompiler::Call cachedGetById(CodeOrigin, GPRReg baseTagGPROrNone, GPRReg basePayloadGPR, GPRReg resultTagGPR, GPRReg resultPayloadGPR, GPRReg scratchGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill);
- void cachedPutById(CodeOrigin, GPRReg basePayloadGPR, GPRReg valueTagGPR, GPRReg valuePayloadGPR, NodeIndex valueIndex, GPRReg scratchGPR, unsigned identifierNumber, PutKind, JITCompiler::Jump slowPathTarget = JITCompiler::Jump());
+ void cachedPutById(CodeOrigin, GPRReg basePayloadGPR, GPRReg valueTagGPR, GPRReg valuePayloadGPR, NodeUse valueUse, GPRReg scratchGPR, unsigned identifierNumber, PutKind, JITCompiler::Jump slowPathTarget = JITCompiler::Jump());
#endif
- void nonSpeculativeNonPeepholeCompareNull(NodeIndex operand, bool invert = false);
- void nonSpeculativePeepholeBranchNull(NodeIndex operand, NodeIndex branchNodeIndex, bool invert = false);
- bool nonSpeculativeCompareNull(Node&, NodeIndex operand, bool invert = false);
+ void nonSpeculativeNonPeepholeCompareNull(NodeUse operand, bool invert = false);
+ void nonSpeculativePeepholeBranchNull(NodeUse operand, NodeIndex branchNodeIndex, bool invert = false);
+ bool nonSpeculativeCompareNull(Node&, NodeUse operand, bool invert = false);
void nonSpeculativePeepholeBranch(Node&, NodeIndex branchNodeIndex, MacroAssembler::RelationalCondition, S_DFGOperation_EJJ helperFunction);
void nonSpeculativeNonPeepholeCompare(Node&, MacroAssembler::RelationalCondition, S_DFGOperation_EJJ helperFunction);
@@ -1504,15 +1517,15 @@ private:
void compilePeepHoleObjectEquality(Node&, NodeIndex branchNodeIndex, const ClassInfo*, PredictionChecker);
void compileObjectEquality(Node&, const ClassInfo*, PredictionChecker);
void compileValueAdd(Node&);
- void compileObjectOrOtherLogicalNot(NodeIndex value, const ClassInfo*, bool needSpeculationCheck);
+ void compileObjectOrOtherLogicalNot(NodeUse value, const ClassInfo*, bool needSpeculationCheck);
void compileLogicalNot(Node&);
- void emitObjectOrOtherBranch(NodeIndex value, BlockIndex taken, BlockIndex notTaken, const ClassInfo*, bool needSpeculationCheck);
+ void emitObjectOrOtherBranch(NodeUse value, BlockIndex taken, BlockIndex notTaken, const ClassInfo*, bool needSpeculationCheck);
void emitBranch(Node&);
void compileIntegerCompare(Node&, MacroAssembler::RelationalCondition);
void compileDoubleCompare(Node&, MacroAssembler::DoubleCondition);
- bool compileStrictEqForConstant(Node&, NodeIndex value, JSValue constant);
+ bool compileStrictEqForConstant(Node&, NodeUse value, JSValue constant);
bool compileStrictEq(Node&);
@@ -1552,9 +1565,9 @@ private:
template<typename T>
void emitAllocateJSFinalObject(T structure, GPRReg resultGPR, GPRReg scratchGPR, MacroAssembler::JumpList& slowPath)
{
- MarkedSpace::SizeClass* sizeClass = &m_jit.globalData()->heap.sizeClassForObject(sizeof(JSFinalObject));
+ MarkedAllocator* allocator = &m_jit.globalData()->heap.allocatorForObject(sizeof(JSFinalObject));
- m_jit.loadPtr(&sizeClass->firstFreeCell, resultGPR);
+ m_jit.loadPtr(&allocator->m_firstFreeCell, resultGPR);
slowPath.append(m_jit.branchTestPtr(MacroAssembler::Zero, resultGPR));
// The object is half-allocated: we have what we know is a fresh object, but
@@ -1566,7 +1579,7 @@ private:
// Now that we have scratchGPR back, remove the object from the free list
m_jit.loadPtr(MacroAssembler::Address(resultGPR), scratchGPR);
- m_jit.storePtr(scratchGPR, &sizeClass->firstFreeCell);
+ m_jit.storePtr(scratchGPR, &allocator->m_firstFreeCell);
// Initialize the object's classInfo pointer
m_jit.storePtr(MacroAssembler::TrustedImmPtr(&JSFinalObject::s_info), MacroAssembler::Address(resultGPR, JSCell::classInfoOffset()));
@@ -1592,6 +1605,10 @@ private:
return;
m_jit.codeBlock()->appendOSRExit(OSRExit(kind, jsValueSource, m_jit.valueProfileFor(nodeIndex), jumpToFail, this));
}
+ void speculationCheck(ExitKind kind, JSValueSource jsValueSource, NodeUse nodeUse, MacroAssembler::Jump jumpToFail)
+ {
+ speculationCheck(kind, jsValueSource, nodeUse.index(), jumpToFail);
+ }
// Add a set of speculation checks without additional recovery.
void speculationCheck(ExitKind kind, JSValueSource jsValueSource, NodeIndex nodeIndex, MacroAssembler::JumpList& jumpsToFail)
{
@@ -1599,6 +1616,10 @@ private:
for (unsigned i = 0; i < JumpVector.size(); ++i)
speculationCheck(kind, jsValueSource, nodeIndex, JumpVector[i]);
}
+ void speculationCheck(ExitKind kind, JSValueSource jsValueSource, NodeUse nodeUse, MacroAssembler::JumpList& jumpsToFail)
+ {
+ speculationCheck(kind, jsValueSource, nodeUse.index(), jumpsToFail);
+ }
// Add a speculation check with additional recovery.
void speculationCheck(ExitKind kind, JSValueSource jsValueSource, NodeIndex nodeIndex, MacroAssembler::Jump jumpToFail, const SpeculationRecovery& recovery)
{
@@ -1607,6 +1628,10 @@ private:
m_jit.codeBlock()->appendSpeculationRecovery(recovery);
m_jit.codeBlock()->appendOSRExit(OSRExit(kind, jsValueSource, m_jit.valueProfileFor(nodeIndex), jumpToFail, this, m_jit.codeBlock()->numberOfSpeculationRecoveries()));
}
+ void speculationCheck(ExitKind kind, JSValueSource jsValueSource, NodeUse nodeUse, MacroAssembler::Jump jumpToFail, const SpeculationRecovery& recovery)
+ {
+ speculationCheck(kind, jsValueSource, nodeUse.index(), jumpToFail, recovery);
+ }
// Called when we statically determine that a speculation will fail.
void terminateSpeculativeExecution(ExitKind kind, JSValueRegs jsValueRegs, NodeIndex nodeIndex)
@@ -1619,6 +1644,10 @@ private:
speculationCheck(kind, jsValueRegs, nodeIndex, m_jit.jump());
m_compileOkay = false;
}
+ void terminateSpeculativeExecution(ExitKind kind, JSValueRegs jsValueRegs, NodeUse nodeUse)
+ {
+ terminateSpeculativeExecution(kind, jsValueRegs, nodeUse.index());
+ }
template<bool strict>
GPRReg fillSpeculateIntInternal(NodeIndex, DataFormat& returnFormat);
@@ -1711,16 +1740,16 @@ private:
class IntegerOperand {
public:
- explicit IntegerOperand(SpeculativeJIT* jit, NodeIndex index)
+ explicit IntegerOperand(SpeculativeJIT* jit, NodeUse use)
: m_jit(jit)
- , m_index(index)
+ , m_index(use.index())
, m_gprOrInvalid(InvalidGPRReg)
#ifndef NDEBUG
, m_format(DataFormatNone)
#endif
{
ASSERT(m_jit);
- if (jit->isFilled(index))
+ if (jit->isFilled(m_index))
gpr();
}
@@ -1763,13 +1792,13 @@ private:
class DoubleOperand {
public:
- explicit DoubleOperand(SpeculativeJIT* jit, NodeIndex index)
+ explicit DoubleOperand(SpeculativeJIT* jit, NodeUse use)
: m_jit(jit)
- , m_index(index)
+ , m_index(use.index())
, m_fprOrInvalid(InvalidFPRReg)
{
ASSERT(m_jit);
- if (jit->isFilledDouble(index))
+ if (jit->isFilledDouble(m_index))
fpr();
}
@@ -1804,9 +1833,9 @@ private:
class JSValueOperand {
public:
- explicit JSValueOperand(SpeculativeJIT* jit, NodeIndex index)
+ explicit JSValueOperand(SpeculativeJIT* jit, NodeUse use)
: m_jit(jit)
- , m_index(index)
+ , m_index(use.index())
#if USE(JSVALUE64)
, m_gprOrInvalid(InvalidGPRReg)
#elif USE(JSVALUE32_64)
@@ -1815,12 +1844,12 @@ public:
{
ASSERT(m_jit);
#if USE(JSVALUE64)
- if (jit->isFilled(index))
+ if (jit->isFilled(m_index))
gpr();
#elif USE(JSVALUE32_64)
m_register.pair.tagGPR = InvalidGPRReg;
m_register.pair.payloadGPR = InvalidGPRReg;
- if (jit->isFilled(index))
+ if (jit->isFilled(m_index))
fill();
#endif
}
@@ -1918,13 +1947,13 @@ private:
class StorageOperand {
public:
- explicit StorageOperand(SpeculativeJIT* jit, NodeIndex index)
+ explicit StorageOperand(SpeculativeJIT* jit, NodeUse use)
: m_jit(jit)
- , m_index(index)
+ , m_index(use.index())
, m_gprOrInvalid(InvalidGPRReg)
{
ASSERT(m_jit);
- if (jit->isFilled(index))
+ if (jit->isFilled(m_index))
gpr();
}
@@ -2087,16 +2116,16 @@ private:
class SpeculateIntegerOperand {
public:
- explicit SpeculateIntegerOperand(SpeculativeJIT* jit, NodeIndex index)
+ explicit SpeculateIntegerOperand(SpeculativeJIT* jit, NodeUse use)
: m_jit(jit)
- , m_index(index)
+ , m_index(use.index())
, m_gprOrInvalid(InvalidGPRReg)
#ifndef NDEBUG
, m_format(DataFormatNone)
#endif
{
ASSERT(m_jit);
- if (jit->isFilled(index))
+ if (jit->isFilled(m_index))
gpr();
}
@@ -2134,13 +2163,13 @@ private:
class SpeculateStrictInt32Operand {
public:
- explicit SpeculateStrictInt32Operand(SpeculativeJIT* jit, NodeIndex index)
+ explicit SpeculateStrictInt32Operand(SpeculativeJIT* jit, NodeUse use)
: m_jit(jit)
- , m_index(index)
+ , m_index(use.index())
, m_gprOrInvalid(InvalidGPRReg)
{
ASSERT(m_jit);
- if (jit->isFilled(index))
+ if (jit->isFilled(m_index))
gpr();
}
@@ -2175,13 +2204,13 @@ private:
class SpeculateDoubleOperand {
public:
- explicit SpeculateDoubleOperand(SpeculativeJIT* jit, NodeIndex index)
+ explicit SpeculateDoubleOperand(SpeculativeJIT* jit, NodeUse use)
: m_jit(jit)
- , m_index(index)
+ , m_index(use.index())
, m_fprOrInvalid(InvalidFPRReg)
{
ASSERT(m_jit);
- if (jit->isFilled(index))
+ if (jit->isFilled(m_index))
fpr();
}
@@ -2211,13 +2240,13 @@ private:
class SpeculateCellOperand {
public:
- explicit SpeculateCellOperand(SpeculativeJIT* jit, NodeIndex index)
+ explicit SpeculateCellOperand(SpeculativeJIT* jit, NodeUse use)
: m_jit(jit)
- , m_index(index)
+ , m_index(use.index())
, m_gprOrInvalid(InvalidGPRReg)
{
ASSERT(m_jit);
- if (jit->isFilled(index))
+ if (jit->isFilled(m_index))
gpr();
}
@@ -2252,13 +2281,13 @@ private:
class SpeculateBooleanOperand {
public:
- explicit SpeculateBooleanOperand(SpeculativeJIT* jit, NodeIndex index)
+ explicit SpeculateBooleanOperand(SpeculativeJIT* jit, NodeUse use)
: m_jit(jit)
- , m_index(index)
+ , m_index(use.index())
, m_gprOrInvalid(InvalidGPRReg)
{
ASSERT(m_jit);
- if (jit->isFilled(index))
+ if (jit->isFilled(m_index))
gpr();
}
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
index e1f92ba9e..a2cdec086 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
@@ -360,7 +360,7 @@ bool SpeculativeJIT::fillJSValue(NodeIndex nodeIndex, GPRReg& tagGPR, GPRReg& pa
void SpeculativeJIT::nonSpeculativeValueToNumber(Node& node)
{
- if (isKnownNumeric(node.child1())) {
+ if (isKnownNumeric(node.child1().index())) {
JSValueOperand op1(this, node.child1());
op1.fill();
if (op1.isDouble()) {
@@ -381,8 +381,8 @@ void SpeculativeJIT::nonSpeculativeValueToNumber(Node& node)
GPRTemporary resultTag(this, op1);
GPRTemporary resultPayload(this, op1, false);
- ASSERT(!isInt32Constant(node.child1()));
- ASSERT(!isNumberConstant(node.child1()));
+ ASSERT(!isInt32Constant(node.child1().index()));
+ ASSERT(!isNumberConstant(node.child1().index()));
GPRReg tagGPR = op1.tagGPR();
GPRReg payloadGPR = op1.payloadGPR();
@@ -415,9 +415,9 @@ void SpeculativeJIT::nonSpeculativeValueToNumber(Node& node)
void SpeculativeJIT::nonSpeculativeValueToInt32(Node& node)
{
- ASSERT(!isInt32Constant(node.child1()));
+ ASSERT(!isInt32Constant(node.child1().index()));
- if (isKnownInteger(node.child1())) {
+ if (isKnownInteger(node.child1().index())) {
IntegerOperand op1(this, node.child1());
GPRTemporary result(this, op1);
m_jit.move(op1.gpr(), result.gpr());
@@ -532,14 +532,14 @@ JITCompiler::Call SpeculativeJIT::cachedGetById(CodeOrigin codeOrigin, GPRReg ba
return functionCall;
}
-void SpeculativeJIT::cachedPutById(CodeOrigin codeOrigin, GPRReg basePayloadGPR, GPRReg valueTagGPR, GPRReg valuePayloadGPR, NodeIndex valueIndex, GPRReg scratchGPR, unsigned identifierNumber, PutKind putKind, JITCompiler::Jump slowPathTarget)
+void SpeculativeJIT::cachedPutById(CodeOrigin codeOrigin, GPRReg basePayloadGPR, GPRReg valueTagGPR, GPRReg valuePayloadGPR, NodeUse valueUse, GPRReg scratchGPR, unsigned identifierNumber, PutKind putKind, JITCompiler::Jump slowPathTarget)
{
m_jit.beginUninterruptedSequence();
JITCompiler::DataLabelPtr structureToCompare;
JITCompiler::Jump structureCheck = m_jit.branchPtrWithPatch(JITCompiler::NotEqual, JITCompiler::Address(basePayloadGPR, JSCell::structureOffset()), structureToCompare, JITCompiler::TrustedImmPtr(reinterpret_cast<void*>(-1)));
m_jit.endUninterruptedSequence();
- writeBarrier(basePayloadGPR, valueTagGPR, valueIndex, WriteBarrierForPropertyAccess, scratchGPR);
+ writeBarrier(basePayloadGPR, valueTagGPR, valueUse, WriteBarrierForPropertyAccess, scratchGPR);
m_jit.loadPtr(JITCompiler::Address(basePayloadGPR, JSObject::offsetOfPropertyStorage()), scratchGPR);
JITCompiler::DataLabel32 tagStoreWithPatch = m_jit.store32WithAddressOffsetPatch(valueTagGPR, JITCompiler::Address(scratchGPR, OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
@@ -576,7 +576,7 @@ void SpeculativeJIT::cachedPutById(CodeOrigin codeOrigin, GPRReg basePayloadGPR,
m_jit.addPropertyAccess(PropertyAccessRecord(codeOrigin, structureToCompare, functionCall, structureCheck, JITCompiler::DataLabelCompact(tagStoreWithPatch.label()), JITCompiler::DataLabelCompact(payloadStoreWithPatch.label()), slowCase, doneLabel, safeCast<int8_t>(basePayloadGPR), safeCast<int8_t>(valueTagGPR), safeCast<int8_t>(valuePayloadGPR), safeCast<int8_t>(scratchGPR)));
}
-void SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull(NodeIndex operand, bool invert)
+void SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull(NodeUse operand, bool invert)
{
JSValueOperand arg(this, operand);
GPRReg argTagGPR = arg.tagGPR();
@@ -586,13 +586,13 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull(NodeIndex operand, boo
GPRReg resultPayloadGPR = resultPayload.gpr();
JITCompiler::Jump notCell;
- if (!isKnownCell(operand))
+ if (!isKnownCell(operand.index()))
notCell = m_jit.branch32(MacroAssembler::NotEqual, argTagGPR, TrustedImm32(JSValue::CellTag));
m_jit.loadPtr(JITCompiler::Address(argPayloadGPR, JSCell::structureOffset()), resultPayloadGPR);
m_jit.test8(invert ? JITCompiler::Zero : JITCompiler::NonZero, JITCompiler::Address(resultPayloadGPR, Structure::typeInfoFlagsOffset()), JITCompiler::TrustedImm32(MasqueradesAsUndefined), resultPayloadGPR);
- if (!isKnownCell(operand)) {
+ if (!isKnownCell(operand.index())) {
JITCompiler::Jump done = m_jit.jump();
notCell.link(&m_jit);
@@ -608,7 +608,7 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull(NodeIndex operand, boo
booleanResult(resultPayloadGPR, m_compileIndex);
}
-void SpeculativeJIT::nonSpeculativePeepholeBranchNull(NodeIndex operand, NodeIndex branchNodeIndex, bool invert)
+void SpeculativeJIT::nonSpeculativePeepholeBranchNull(NodeUse operand, NodeIndex branchNodeIndex, bool invert)
{
Node& branchNode = at(branchNodeIndex);
BlockIndex taken = branchNode.takenBlockIndex();
@@ -630,13 +630,13 @@ void SpeculativeJIT::nonSpeculativePeepholeBranchNull(NodeIndex operand, NodeInd
JITCompiler::Jump notCell;
- if (!isKnownCell(operand))
+ if (!isKnownCell(operand.index()))
notCell = m_jit.branch32(MacroAssembler::NotEqual, argTagGPR, TrustedImm32(JSValue::CellTag));
m_jit.loadPtr(JITCompiler::Address(argPayloadGPR, JSCell::structureOffset()), resultGPR);
addBranch(m_jit.branchTest8(invert ? JITCompiler::Zero : JITCompiler::NonZero, JITCompiler::Address(resultGPR, Structure::typeInfoFlagsOffset()), JITCompiler::TrustedImm32(MasqueradesAsUndefined)), taken);
- if (!isKnownCell(operand)) {
+ if (!isKnownCell(operand.index())) {
addBranch(m_jit.jump(), notTaken);
notCell.link(&m_jit);
@@ -651,7 +651,7 @@ void SpeculativeJIT::nonSpeculativePeepholeBranchNull(NodeIndex operand, NodeInd
addBranch(m_jit.jump(), notTaken);
}
-bool SpeculativeJIT::nonSpeculativeCompareNull(Node& node, NodeIndex operand, bool invert)
+bool SpeculativeJIT::nonSpeculativeCompareNull(Node& node, NodeUse operand, bool invert)
{
NodeIndex branchNodeIndex = detectPeepHoleBranch();
if (branchNodeIndex != NoNode) {
@@ -698,7 +698,7 @@ void SpeculativeJIT::nonSpeculativePeepholeBranch(Node& node, NodeIndex branchNo
JITCompiler::JumpList slowPath;
- if (isKnownNotInteger(node.child1()) || isKnownNotInteger(node.child2())) {
+ if (isKnownNotInteger(node.child1().index()) || isKnownNotInteger(node.child2().index())) {
GPRResult result(this);
GPRReg resultGPR = result.gpr();
@@ -716,14 +716,14 @@ void SpeculativeJIT::nonSpeculativePeepholeBranch(Node& node, NodeIndex branchNo
arg1.use();
arg2.use();
- if (!isKnownInteger(node.child1()))
+ if (!isKnownInteger(node.child1().index()))
slowPath.append(m_jit.branch32(MacroAssembler::NotEqual, arg1TagGPR, JITCompiler::TrustedImm32(JSValue::Int32Tag)));
- if (!isKnownInteger(node.child2()))
+ if (!isKnownInteger(node.child2().index()))
slowPath.append(m_jit.branch32(MacroAssembler::NotEqual, arg2TagGPR, JITCompiler::TrustedImm32(JSValue::Int32Tag)));
addBranch(m_jit.branch32(cond, arg1PayloadGPR, arg2PayloadGPR), taken);
- if (!isKnownInteger(node.child1()) || !isKnownInteger(node.child2())) {
+ if (!isKnownInteger(node.child1().index()) || !isKnownInteger(node.child2().index())) {
addBranch(m_jit.jump(), notTaken);
slowPath.link(&m_jit);
@@ -751,7 +751,7 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompare(Node& node, MacroAssembler
JITCompiler::JumpList slowPath;
- if (isKnownNotInteger(node.child1()) || isKnownNotInteger(node.child2())) {
+ if (isKnownNotInteger(node.child1().index()) || isKnownNotInteger(node.child2().index())) {
GPRResult result(this);
GPRReg resultPayloadGPR = result.gpr();
@@ -769,14 +769,14 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompare(Node& node, MacroAssembler
arg1.use();
arg2.use();
- if (!isKnownInteger(node.child1()))
+ if (!isKnownInteger(node.child1().index()))
slowPath.append(m_jit.branch32(MacroAssembler::NotEqual, arg1TagGPR, JITCompiler::TrustedImm32(JSValue::Int32Tag)));
- if (!isKnownInteger(node.child2()))
+ if (!isKnownInteger(node.child2().index()))
slowPath.append(m_jit.branch32(MacroAssembler::NotEqual, arg2TagGPR, JITCompiler::TrustedImm32(JSValue::Int32Tag)));
m_jit.compare32(cond, arg1PayloadGPR, arg2PayloadGPR, resultPayloadGPR);
- if (!isKnownInteger(node.child1()) || !isKnownInteger(node.child2())) {
+ if (!isKnownInteger(node.child1().index()) || !isKnownInteger(node.child2().index())) {
JITCompiler::Jump haveResult = m_jit.jump();
slowPath.link(&m_jit);
@@ -822,7 +822,7 @@ void SpeculativeJIT::nonSpeculativePeepholeStrictEq(Node& node, NodeIndex branch
arg1.use();
arg2.use();
- if (isKnownCell(node.child1()) && isKnownCell(node.child2())) {
+ if (isKnownCell(node.child1().index()) && isKnownCell(node.child2().index())) {
// see if we get lucky: if the arguments are cells and they reference the same
// cell, then they must be strictly equal.
addBranch(m_jit.branchPtr(JITCompiler::Equal, arg1PayloadGPR, arg2PayloadGPR), invert ? notTaken : taken);
@@ -861,7 +861,7 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeStrictEq(Node& node, bool invert)
arg1.use();
arg2.use();
- if (isKnownCell(node.child1()) && isKnownCell(node.child2())) {
+ if (isKnownCell(node.child1().index()) && isKnownCell(node.child2().index())) {
// see if we get lucky: if the arguments are cells and they reference the same
// cell, then they must be strictly equal.
JITCompiler::Jump notEqualCase = m_jit.branchPtr(JITCompiler::NotEqual, arg1PayloadGPR, arg2PayloadGPR);
@@ -908,11 +908,11 @@ void SpeculativeJIT::emitCall(Node& node)
CallLinkInfo::CallType callType = node.op == Call ? CallLinkInfo::Call : CallLinkInfo::Construct;
- NodeIndex calleeNodeIndex = m_jit.graph().m_varArgChildren[node.firstChild()];
- JSValueOperand callee(this, calleeNodeIndex);
+ NodeUse calleeNodeUse = m_jit.graph().m_varArgChildren[node.firstChild()];
+ JSValueOperand callee(this, calleeNodeUse);
GPRReg calleeTagGPR = callee.tagGPR();
GPRReg calleePayloadGPR = callee.payloadGPR();
- use(calleeNodeIndex);
+ use(calleeNodeUse);
// The call instruction's first child is either the function (normal call) or the
// receiver (method call). subsequent children are the arguments.
@@ -924,11 +924,11 @@ void SpeculativeJIT::emitCall(Node& node)
m_jit.store32(calleeTagGPR, callFrameTagSlot(RegisterFile::Callee));
for (int i = 0; i < numPassedArgs; i++) {
- NodeIndex argNodeIndex = m_jit.graph().m_varArgChildren[node.firstChild() + 1 + i];
- JSValueOperand arg(this, argNodeIndex);
+ NodeUse argNodeUse = m_jit.graph().m_varArgChildren[node.firstChild() + 1 + i];
+ JSValueOperand arg(this, argNodeUse);
GPRReg argTagGPR = arg.tagGPR();
GPRReg argPayloadGPR = arg.payloadGPR();
- use(argNodeIndex);
+ use(argNodeUse);
m_jit.store32(argTagGPR, argumentTagSlot(i + dummyThisArgument));
m_jit.store32(argPayloadGPR, argumentPayloadSlot(i + dummyThisArgument));
@@ -1439,7 +1439,7 @@ void SpeculativeJIT::compileValueAdd(Node& node)
GPRResult2 resultTag(this);
GPRResult resultPayload(this);
- if (isKnownNotNumber(node.child1()) || isKnownNotNumber(node.child2()))
+ if (isKnownNotNumber(node.child1().index()) || isKnownNotNumber(node.child2().index()))
callOperation(operationValueAddNotNumber, resultTag.gpr(), resultPayload.gpr(), op1TagGPR, op1PayloadGPR, op2TagGPR, op2PayloadGPR);
else
callOperation(operationValueAdd, resultTag.gpr(), resultPayload.gpr(), op1TagGPR, op1PayloadGPR, op2TagGPR, op2PayloadGPR);
@@ -1447,9 +1447,9 @@ void SpeculativeJIT::compileValueAdd(Node& node)
jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex);
}
-void SpeculativeJIT::compileObjectOrOtherLogicalNot(NodeIndex nodeIndex, const ClassInfo* classInfo, bool needSpeculationCheck)
+void SpeculativeJIT::compileObjectOrOtherLogicalNot(NodeUse nodeUse, const ClassInfo* classInfo, bool needSpeculationCheck)
{
- JSValueOperand value(this, nodeIndex);
+ JSValueOperand value(this, nodeUse);
GPRTemporary resultPayload(this);
GPRReg valueTagGPR = value.tagGPR();
GPRReg valuePayloadGPR = value.payloadGPR();
@@ -1457,7 +1457,7 @@ void SpeculativeJIT::compileObjectOrOtherLogicalNot(NodeIndex nodeIndex, const C
MacroAssembler::Jump notCell = m_jit.branch32(MacroAssembler::NotEqual, valueTagGPR, TrustedImm32(JSValue::CellTag));
if (needSpeculationCheck)
- speculationCheck(BadType, JSValueRegs(valueTagGPR, valuePayloadGPR), nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(valuePayloadGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(classInfo)));
+ speculationCheck(BadType, JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(valuePayloadGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(classInfo)));
m_jit.move(TrustedImm32(0), resultPayloadGPR);
MacroAssembler::Jump done = m_jit.jump();
@@ -1467,7 +1467,7 @@ void SpeculativeJIT::compileObjectOrOtherLogicalNot(NodeIndex nodeIndex, const C
if (needSpeculationCheck) {
m_jit.move(valueTagGPR, resultPayloadGPR);
m_jit.or32(TrustedImm32(1), resultPayloadGPR);
- speculationCheck(BadType, JSValueRegs(valueTagGPR, valuePayloadGPR), nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, resultPayloadGPR, TrustedImm32(JSValue::NullTag)));
+ speculationCheck(BadType, JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, m_jit.branch32(MacroAssembler::NotEqual, resultPayloadGPR, TrustedImm32(JSValue::NullTag)));
}
m_jit.move(TrustedImm32(1), resultPayloadGPR);
@@ -1478,7 +1478,7 @@ void SpeculativeJIT::compileObjectOrOtherLogicalNot(NodeIndex nodeIndex, const C
void SpeculativeJIT::compileLogicalNot(Node& node)
{
- if (isKnownBoolean(node.child1()) || isBooleanPrediction(m_jit.getPrediction(node.child1()))) {
+ if (isKnownBoolean(node.child1().index()) || isBooleanPrediction(m_jit.getPrediction(node.child1().index()))) {
SpeculateBooleanOperand value(this, node.child1());
GPRTemporary result(this, value);
m_jit.xor32(TrustedImm32(1), value.gpr(), result.gpr());
@@ -1535,9 +1535,9 @@ void SpeculativeJIT::compileLogicalNot(Node& node)
booleanResult(resultPayloadGPR, m_compileIndex, UseChildrenCalledExplicitly);
}
-void SpeculativeJIT::emitObjectOrOtherBranch(NodeIndex nodeIndex, BlockIndex taken, BlockIndex notTaken, const ClassInfo* classInfo, bool needSpeculationCheck)
+void SpeculativeJIT::emitObjectOrOtherBranch(NodeUse nodeUse, BlockIndex taken, BlockIndex notTaken, const ClassInfo* classInfo, bool needSpeculationCheck)
{
- JSValueOperand value(this, nodeIndex);
+ JSValueOperand value(this, nodeUse);
GPRTemporary scratch(this);
GPRReg valueTagGPR = value.tagGPR();
GPRReg valuePayloadGPR = value.payloadGPR();
@@ -1545,7 +1545,7 @@ void SpeculativeJIT::emitObjectOrOtherBranch(NodeIndex nodeIndex, BlockIndex tak
MacroAssembler::Jump notCell = m_jit.branch32(MacroAssembler::NotEqual, valueTagGPR, TrustedImm32(JSValue::CellTag));
if (needSpeculationCheck)
- speculationCheck(BadType, JSValueRegs(valueTagGPR, valuePayloadGPR), nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(valuePayloadGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(classInfo)));
+ speculationCheck(BadType, JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(valuePayloadGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(classInfo)));
addBranch(m_jit.jump(), taken);
notCell.link(&m_jit);
@@ -1554,7 +1554,7 @@ void SpeculativeJIT::emitObjectOrOtherBranch(NodeIndex nodeIndex, BlockIndex tak
if (needSpeculationCheck) {
m_jit.move(valueTagGPR, scratchGPR);
m_jit.or32(TrustedImm32(1), scratchGPR);
- speculationCheck(BadType, JSValueRegs(valueTagGPR, valuePayloadGPR), nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, scratchGPR, TrustedImm32(JSValue::NullTag)));
+ speculationCheck(BadType, JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, m_jit.branch32(MacroAssembler::NotEqual, scratchGPR, TrustedImm32(JSValue::NullTag)));
}
if (notTaken != (m_block + 1))
@@ -1568,7 +1568,7 @@ void SpeculativeJIT::emitBranch(Node& node)
BlockIndex taken = node.takenBlockIndex();
BlockIndex notTaken = node.notTakenBlockIndex();
- if (isKnownBoolean(node.child1())) {
+ if (isKnownBoolean(node.child1().index())) {
SpeculateBooleanOperand value(this, node.child1());
MacroAssembler::ResultCondition condition = MacroAssembler::NonZero;
@@ -1800,18 +1800,18 @@ void SpeculativeJIT::compile(Node& node)
case BitAnd:
case BitOr:
case BitXor:
- if (isInt32Constant(node.child1())) {
+ if (isInt32Constant(node.child1().index())) {
SpeculateIntegerOperand op2(this, node.child2());
GPRTemporary result(this, op2);
- bitOp(op, valueOfInt32Constant(node.child1()), op2.gpr(), result.gpr());
+ bitOp(op, valueOfInt32Constant(node.child1().index()), op2.gpr(), result.gpr());
integerResult(result.gpr(), m_compileIndex);
- } else if (isInt32Constant(node.child2())) {
+ } else if (isInt32Constant(node.child2().index())) {
SpeculateIntegerOperand op1(this, node.child1());
GPRTemporary result(this, op1);
- bitOp(op, valueOfInt32Constant(node.child2()), op1.gpr(), result.gpr());
+ bitOp(op, valueOfInt32Constant(node.child2().index()), op1.gpr(), result.gpr());
integerResult(result.gpr(), m_compileIndex);
} else {
@@ -1830,11 +1830,11 @@ void SpeculativeJIT::compile(Node& node)
case BitRShift:
case BitLShift:
case BitURShift:
- if (isInt32Constant(node.child2())) {
+ if (isInt32Constant(node.child2().index())) {
SpeculateIntegerOperand op1(this, node.child1());
GPRTemporary result(this, op1);
- shiftOp(op, op1.gpr(), valueOfInt32Constant(node.child2()) & 0x1f, result.gpr());
+ shiftOp(op, op1.gpr(), valueOfInt32Constant(node.child2().index()) & 0x1f, result.gpr());
integerResult(result.gpr(), m_compileIndex);
} else {
@@ -1861,30 +1861,6 @@ void SpeculativeJIT::compile(Node& node)
break;
}
- case ValueToNumber: {
- if (at(node.child1()).shouldNotSpeculateInteger()) {
- SpeculateDoubleOperand op1(this, node.child1());
- FPRTemporary result(this, op1);
- m_jit.moveDouble(op1.fpr(), result.fpr());
- doubleResult(result.fpr(), m_compileIndex);
- break;
- }
-
- SpeculateIntegerOperand op1(this, node.child1());
- GPRTemporary result(this, op1);
- m_jit.move(op1.gpr(), result.gpr());
- integerResult(result.gpr(), m_compileIndex, op1.format());
- break;
- }
-
- case ValueToDouble: {
- SpeculateDoubleOperand op1(this, node.child1());
- FPRTemporary result(this, op1);
- m_jit.moveDouble(op1.fpr(), result.fpr());
- doubleResult(result.fpr(), m_compileIndex);
- break;
- }
-
case ValueAdd:
case ArithAdd:
compileAdd(node);
@@ -2091,12 +2067,12 @@ void SpeculativeJIT::compile(Node& node)
break;
case CompareEq:
- if (isNullConstant(node.child1())) {
+ if (isNullConstant(node.child1().index())) {
if (nonSpeculativeCompareNull(node, node.child2()))
return;
break;
}
- if (isNullConstant(node.child2())) {
+ if (isNullConstant(node.child2().index())) {
if (nonSpeculativeCompareNull(node, node.child1()))
return;
break;
@@ -2631,7 +2607,7 @@ void SpeculativeJIT::compile(Node& node)
}
case Branch:
- if (isStrictInt32(node.child1()) || at(node.child1()).shouldSpeculateInteger()) {
+ if (isStrictInt32(node.child1().index()) || at(node.child1()).shouldSpeculateInteger()) {
SpeculateIntegerOperand op(this, node.child1());
BlockIndex taken = node.takenBlockIndex();
@@ -2720,7 +2696,7 @@ void SpeculativeJIT::compile(Node& node)
// FIXME: Add string speculation here.
- bool wasPrimitive = isKnownNumeric(node.child1()) || isKnownBoolean(node.child1());
+ bool wasPrimitive = isKnownNumeric(node.child1().index()) || isKnownBoolean(node.child1().index());
JSValueOperand op1(this, node.child1());
GPRTemporary resultTag(this, op1);
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
index 139dedded..0dc207f75 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
@@ -360,7 +360,7 @@ GPRReg SpeculativeJIT::fillJSValue(NodeIndex nodeIndex)
void SpeculativeJIT::nonSpeculativeValueToNumber(Node& node)
{
- if (isKnownNumeric(node.child1())) {
+ if (isKnownNumeric(node.child1().index())) {
JSValueOperand op1(this, node.child1());
GPRTemporary result(this, op1);
m_jit.move(op1.gpr(), result.gpr());
@@ -371,8 +371,8 @@ void SpeculativeJIT::nonSpeculativeValueToNumber(Node& node)
JSValueOperand op1(this, node.child1());
GPRTemporary result(this);
- ASSERT(!isInt32Constant(node.child1()));
- ASSERT(!isNumberConstant(node.child1()));
+ ASSERT(!isInt32Constant(node.child1().index()));
+ ASSERT(!isNumberConstant(node.child1().index()));
GPRReg jsValueGpr = op1.gpr();
GPRReg gpr = result.gpr();
@@ -404,9 +404,9 @@ void SpeculativeJIT::nonSpeculativeValueToNumber(Node& node)
void SpeculativeJIT::nonSpeculativeValueToInt32(Node& node)
{
- ASSERT(!isInt32Constant(node.child1()));
+ ASSERT(!isInt32Constant(node.child1().index()));
- if (isKnownInteger(node.child1())) {
+ if (isKnownInteger(node.child1().index())) {
IntegerOperand op1(this, node.child1());
GPRTemporary result(this, op1);
m_jit.move(op1.gpr(), result.gpr());
@@ -512,13 +512,13 @@ JITCompiler::Call SpeculativeJIT::cachedGetById(CodeOrigin codeOrigin, GPRReg ba
return functionCall;
}
-void SpeculativeJIT::cachedPutById(CodeOrigin codeOrigin, GPRReg baseGPR, GPRReg valueGPR, NodeIndex valueIndex, GPRReg scratchGPR, unsigned identifierNumber, PutKind putKind, JITCompiler::Jump slowPathTarget)
+void SpeculativeJIT::cachedPutById(CodeOrigin codeOrigin, GPRReg baseGPR, GPRReg valueGPR, NodeUse valueUse, GPRReg scratchGPR, unsigned identifierNumber, PutKind putKind, JITCompiler::Jump slowPathTarget)
{
JITCompiler::DataLabelPtr structureToCompare;
JITCompiler::Jump structureCheck = m_jit.branchPtrWithPatch(JITCompiler::NotEqual, JITCompiler::Address(baseGPR, JSCell::structureOffset()), structureToCompare, JITCompiler::TrustedImmPtr(reinterpret_cast<void*>(-1)));
- writeBarrier(baseGPR, valueGPR, valueIndex, WriteBarrierForPropertyAccess, scratchGPR);
+ writeBarrier(baseGPR, valueGPR, valueUse, WriteBarrierForPropertyAccess, scratchGPR);
m_jit.loadPtr(JITCompiler::Address(baseGPR, JSObject::offsetOfPropertyStorage()), scratchGPR);
JITCompiler::DataLabel32 storeWithPatch = m_jit.storePtrWithAddressOffsetPatch(valueGPR, JITCompiler::Address(scratchGPR, 0));
@@ -554,7 +554,7 @@ void SpeculativeJIT::cachedPutById(CodeOrigin codeOrigin, GPRReg baseGPR, GPRReg
m_jit.addPropertyAccess(PropertyAccessRecord(codeOrigin, structureToCompare, functionCall, structureCheck, JITCompiler::DataLabelCompact(storeWithPatch.label()), slowCase, doneLabel, safeCast<int8_t>(baseGPR), safeCast<int8_t>(valueGPR), safeCast<int8_t>(scratchGPR)));
}
-void SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull(NodeIndex operand, bool invert)
+void SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull(NodeUse operand, bool invert)
{
JSValueOperand arg(this, operand);
GPRReg argGPR = arg.gpr();
@@ -564,13 +564,13 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull(NodeIndex operand, boo
JITCompiler::Jump notCell;
- if (!isKnownCell(operand))
+ if (!isKnownCell(operand.index()))
notCell = m_jit.branchTestPtr(MacroAssembler::NonZero, argGPR, GPRInfo::tagMaskRegister);
m_jit.loadPtr(JITCompiler::Address(argGPR, JSCell::structureOffset()), resultGPR);
m_jit.test8(invert ? JITCompiler::Zero : JITCompiler::NonZero, JITCompiler::Address(resultGPR, Structure::typeInfoFlagsOffset()), JITCompiler::TrustedImm32(MasqueradesAsUndefined), resultGPR);
- if (!isKnownCell(operand)) {
+ if (!isKnownCell(operand.index())) {
JITCompiler::Jump done = m_jit.jump();
notCell.link(&m_jit);
@@ -586,7 +586,7 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull(NodeIndex operand, boo
jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean);
}
-void SpeculativeJIT::nonSpeculativePeepholeBranchNull(NodeIndex operand, NodeIndex branchNodeIndex, bool invert)
+void SpeculativeJIT::nonSpeculativePeepholeBranchNull(NodeUse operand, NodeIndex branchNodeIndex, bool invert)
{
Node& branchNode = at(branchNodeIndex);
BlockIndex taken = branchNode.takenBlockIndex();
@@ -607,13 +607,13 @@ void SpeculativeJIT::nonSpeculativePeepholeBranchNull(NodeIndex operand, NodeInd
JITCompiler::Jump notCell;
- if (!isKnownCell(operand))
+ if (!isKnownCell(operand.index()))
notCell = m_jit.branchTestPtr(MacroAssembler::NonZero, argGPR, GPRInfo::tagMaskRegister);
m_jit.loadPtr(JITCompiler::Address(argGPR, JSCell::structureOffset()), resultGPR);
addBranch(m_jit.branchTest8(invert ? JITCompiler::Zero : JITCompiler::NonZero, JITCompiler::Address(resultGPR, Structure::typeInfoFlagsOffset()), JITCompiler::TrustedImm32(MasqueradesAsUndefined)), taken);
- if (!isKnownCell(operand)) {
+ if (!isKnownCell(operand.index())) {
addBranch(m_jit.jump(), notTaken);
notCell.link(&m_jit);
@@ -627,7 +627,7 @@ void SpeculativeJIT::nonSpeculativePeepholeBranchNull(NodeIndex operand, NodeInd
addBranch(m_jit.jump(), notTaken);
}
-bool SpeculativeJIT::nonSpeculativeCompareNull(Node& node, NodeIndex operand, bool invert)
+bool SpeculativeJIT::nonSpeculativeCompareNull(Node& node, NodeUse operand, bool invert)
{
NodeIndex branchNodeIndex = detectPeepHoleBranch();
if (branchNodeIndex != NoNode) {
@@ -672,7 +672,7 @@ void SpeculativeJIT::nonSpeculativePeepholeBranch(Node& node, NodeIndex branchNo
JITCompiler::JumpList slowPath;
- if (isKnownNotInteger(node.child1()) || isKnownNotInteger(node.child2())) {
+ if (isKnownNotInteger(node.child1().index()) || isKnownNotInteger(node.child2().index())) {
GPRResult result(this);
GPRReg resultGPR = result.gpr();
@@ -690,14 +690,14 @@ void SpeculativeJIT::nonSpeculativePeepholeBranch(Node& node, NodeIndex branchNo
arg1.use();
arg2.use();
- if (!isKnownInteger(node.child1()))
+ if (!isKnownInteger(node.child1().index()))
slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg1GPR, GPRInfo::tagTypeNumberRegister));
- if (!isKnownInteger(node.child2()))
+ if (!isKnownInteger(node.child2().index()))
slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg2GPR, GPRInfo::tagTypeNumberRegister));
addBranch(m_jit.branch32(cond, arg1GPR, arg2GPR), taken);
- if (!isKnownInteger(node.child1()) || !isKnownInteger(node.child2())) {
+ if (!isKnownInteger(node.child1().index()) || !isKnownInteger(node.child2().index())) {
addBranch(m_jit.jump(), notTaken);
slowPath.link(&m_jit);
@@ -723,7 +723,7 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompare(Node& node, MacroAssembler
JITCompiler::JumpList slowPath;
- if (isKnownNotInteger(node.child1()) || isKnownNotInteger(node.child2())) {
+ if (isKnownNotInteger(node.child1().index()) || isKnownNotInteger(node.child2().index())) {
GPRResult result(this);
GPRReg resultGPR = result.gpr();
@@ -742,14 +742,14 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompare(Node& node, MacroAssembler
arg1.use();
arg2.use();
- if (!isKnownInteger(node.child1()))
+ if (!isKnownInteger(node.child1().index()))
slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg1GPR, GPRInfo::tagTypeNumberRegister));
- if (!isKnownInteger(node.child2()))
+ if (!isKnownInteger(node.child2().index()))
slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg2GPR, GPRInfo::tagTypeNumberRegister));
m_jit.compare32(cond, arg1GPR, arg2GPR, resultGPR);
- if (!isKnownInteger(node.child1()) || !isKnownInteger(node.child2())) {
+ if (!isKnownInteger(node.child1().index()) || !isKnownInteger(node.child2().index())) {
JITCompiler::Jump haveResult = m_jit.jump();
slowPath.link(&m_jit);
@@ -795,7 +795,7 @@ void SpeculativeJIT::nonSpeculativePeepholeStrictEq(Node& node, NodeIndex branch
arg1.use();
arg2.use();
- if (isKnownCell(node.child1()) && isKnownCell(node.child2())) {
+ if (isKnownCell(node.child1().index()) && isKnownCell(node.child2().index())) {
// see if we get lucky: if the arguments are cells and they reference the same
// cell, then they must be strictly equal.
addBranch(m_jit.branchPtr(JITCompiler::Equal, arg1GPR, arg2GPR), invert ? notTaken : taken);
@@ -844,7 +844,7 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeStrictEq(Node& node, bool invert)
arg1.use();
arg2.use();
- if (isKnownCell(node.child1()) && isKnownCell(node.child2())) {
+ if (isKnownCell(node.child1().index()) && isKnownCell(node.child2().index())) {
// see if we get lucky: if the arguments are cells and they reference the same
// cell, then they must be strictly equal.
JITCompiler::Jump notEqualCase = m_jit.branchPtr(JITCompiler::NotEqual, arg1GPR, arg2GPR);
@@ -917,10 +917,10 @@ void SpeculativeJIT::emitCall(Node& node)
CallLinkInfo::CallType callType = node.op == Call ? CallLinkInfo::Call : CallLinkInfo::Construct;
- NodeIndex calleeNodeIndex = m_jit.graph().m_varArgChildren[node.firstChild()];
- JSValueOperand callee(this, calleeNodeIndex);
+ NodeUse calleeNodeUse = m_jit.graph().m_varArgChildren[node.firstChild()];
+ JSValueOperand callee(this, calleeNodeUse);
GPRReg calleeGPR = callee.gpr();
- use(calleeNodeIndex);
+ use(calleeNodeUse);
// The call instruction's first child is either the function (normal call) or the
// receiver (method call). subsequent children are the arguments.
@@ -931,10 +931,10 @@ void SpeculativeJIT::emitCall(Node& node)
m_jit.storePtr(calleeGPR, callFrameSlot(RegisterFile::Callee));
for (int i = 0; i < numPassedArgs; i++) {
- NodeIndex argNodeIndex = m_jit.graph().m_varArgChildren[node.firstChild() + 1 + i];
- JSValueOperand arg(this, argNodeIndex);
+ NodeUse argNodeUse = m_jit.graph().m_varArgChildren[node.firstChild() + 1 + i];
+ JSValueOperand arg(this, argNodeUse);
GPRReg argGPR = arg.gpr();
- use(argNodeIndex);
+ use(argNodeUse);
m_jit.storePtr(argGPR, argumentSlot(i + dummyThisArgument));
}
@@ -1459,9 +1459,9 @@ void SpeculativeJIT::compileObjectEquality(Node& node, const ClassInfo* classInf
GPRReg resultGPR = result.gpr();
if (!predictionCheck(m_state.forNode(node.child1()).m_type))
- speculationCheck(BadType, JSValueRegs(op1GPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1GPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(classInfo)));
+ speculationCheck(BadType, JSValueRegs(op1GPR), node.child1().index(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1GPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(classInfo)));
if (!predictionCheck(m_state.forNode(node.child2()).m_type))
- speculationCheck(BadType, JSValueRegs(op2GPR), node.child2(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op2GPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(classInfo)));
+ speculationCheck(BadType, JSValueRegs(op2GPR), node.child2().index(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op2GPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(classInfo)));
MacroAssembler::Jump falseCase = m_jit.branchPtr(MacroAssembler::NotEqual, op1GPR, op2GPR);
m_jit.move(Imm32(ValueTrue), resultGPR);
@@ -1511,7 +1511,7 @@ void SpeculativeJIT::compileValueAdd(Node& node)
flushRegisters();
GPRResult result(this);
- if (isKnownNotNumber(node.child1()) || isKnownNotNumber(node.child2()))
+ if (isKnownNotNumber(node.child1().index()) || isKnownNotNumber(node.child2().index()))
callOperation(operationValueAddNotNumber, result.gpr(), op1GPR, op2GPR);
else
callOperation(operationValueAdd, result.gpr(), op1GPR, op2GPR);
@@ -1519,16 +1519,16 @@ void SpeculativeJIT::compileValueAdd(Node& node)
jsValueResult(result.gpr(), m_compileIndex);
}
-void SpeculativeJIT::compileObjectOrOtherLogicalNot(NodeIndex nodeIndex, const ClassInfo* classInfo, bool needSpeculationCheck)
+void SpeculativeJIT::compileObjectOrOtherLogicalNot(NodeUse nodeUse, const ClassInfo* classInfo, bool needSpeculationCheck)
{
- JSValueOperand value(this, nodeIndex);
+ JSValueOperand value(this, nodeUse);
GPRTemporary result(this);
GPRReg valueGPR = value.gpr();
GPRReg resultGPR = result.gpr();
MacroAssembler::Jump notCell = m_jit.branchTestPtr(MacroAssembler::NonZero, valueGPR, GPRInfo::tagMaskRegister);
if (needSpeculationCheck)
- speculationCheck(BadType, JSValueRegs(valueGPR), nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(valueGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(classInfo)));
+ speculationCheck(BadType, JSValueRegs(valueGPR), nodeUse, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(valueGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(classInfo)));
m_jit.move(TrustedImm32(static_cast<int32_t>(ValueFalse)), resultGPR);
MacroAssembler::Jump done = m_jit.jump();
@@ -1537,7 +1537,7 @@ void SpeculativeJIT::compileObjectOrOtherLogicalNot(NodeIndex nodeIndex, const C
if (needSpeculationCheck) {
m_jit.move(valueGPR, resultGPR);
m_jit.andPtr(MacroAssembler::TrustedImm32(~TagBitUndefined), resultGPR);
- speculationCheck(BadType, JSValueRegs(valueGPR), nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, resultGPR, MacroAssembler::TrustedImmPtr(reinterpret_cast<void*>(ValueNull))));
+ speculationCheck(BadType, JSValueRegs(valueGPR), nodeUse, m_jit.branchPtr(MacroAssembler::NotEqual, resultGPR, MacroAssembler::TrustedImmPtr(reinterpret_cast<void*>(ValueNull))));
}
m_jit.move(TrustedImm32(static_cast<int32_t>(ValueTrue)), resultGPR);
@@ -1548,7 +1548,7 @@ void SpeculativeJIT::compileObjectOrOtherLogicalNot(NodeIndex nodeIndex, const C
void SpeculativeJIT::compileLogicalNot(Node& node)
{
- if (isKnownBoolean(node.child1())) {
+ if (isKnownBoolean(node.child1().index())) {
SpeculateBooleanOperand value(this, node.child1());
GPRTemporary result(this, value);
@@ -1623,16 +1623,16 @@ void SpeculativeJIT::compileLogicalNot(Node& node)
jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean, UseChildrenCalledExplicitly);
}
-void SpeculativeJIT::emitObjectOrOtherBranch(NodeIndex nodeIndex, BlockIndex taken, BlockIndex notTaken, const ClassInfo* classInfo, bool needSpeculationCheck)
+void SpeculativeJIT::emitObjectOrOtherBranch(NodeUse nodeUse, BlockIndex taken, BlockIndex notTaken, const ClassInfo* classInfo, bool needSpeculationCheck)
{
- JSValueOperand value(this, nodeIndex);
+ JSValueOperand value(this, nodeUse);
GPRTemporary scratch(this);
GPRReg valueGPR = value.gpr();
GPRReg scratchGPR = scratch.gpr();
MacroAssembler::Jump notCell = m_jit.branchTestPtr(MacroAssembler::NonZero, valueGPR, GPRInfo::tagMaskRegister);
if (needSpeculationCheck)
- speculationCheck(BadType, JSValueRegs(valueGPR), nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(valueGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(classInfo)));
+ speculationCheck(BadType, JSValueRegs(valueGPR), nodeUse.index(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(valueGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(classInfo)));
addBranch(m_jit.jump(), taken);
notCell.link(&m_jit);
@@ -1640,7 +1640,7 @@ void SpeculativeJIT::emitObjectOrOtherBranch(NodeIndex nodeIndex, BlockIndex tak
if (needSpeculationCheck) {
m_jit.move(valueGPR, scratchGPR);
m_jit.andPtr(MacroAssembler::TrustedImm32(~TagBitUndefined), scratchGPR);
- speculationCheck(BadType, JSValueRegs(valueGPR), nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, scratchGPR, MacroAssembler::TrustedImmPtr(reinterpret_cast<void*>(ValueNull))));
+ speculationCheck(BadType, JSValueRegs(valueGPR), nodeUse.index(), m_jit.branchPtr(MacroAssembler::NotEqual, scratchGPR, MacroAssembler::TrustedImmPtr(reinterpret_cast<void*>(ValueNull))));
}
if (notTaken != (m_block + 1))
addBranch(m_jit.jump(), notTaken);
@@ -1656,7 +1656,7 @@ void SpeculativeJIT::emitBranch(Node& node)
BlockIndex taken = node.takenBlockIndex();
BlockIndex notTaken = node.notTakenBlockIndex();
- if (isKnownBoolean(node.child1())) {
+ if (isKnownBoolean(node.child1().index())) {
MacroAssembler::ResultCondition condition = MacroAssembler::NonZero;
if (taken == (m_block + 1)) {
@@ -1879,18 +1879,18 @@ void SpeculativeJIT::compile(Node& node)
case BitAnd:
case BitOr:
case BitXor:
- if (isInt32Constant(node.child1())) {
+ if (isInt32Constant(node.child1().index())) {
SpeculateIntegerOperand op2(this, node.child2());
GPRTemporary result(this, op2);
- bitOp(op, valueOfInt32Constant(node.child1()), op2.gpr(), result.gpr());
+ bitOp(op, valueOfInt32Constant(node.child1().index()), op2.gpr(), result.gpr());
integerResult(result.gpr(), m_compileIndex);
- } else if (isInt32Constant(node.child2())) {
+ } else if (isInt32Constant(node.child2().index())) {
SpeculateIntegerOperand op1(this, node.child1());
GPRTemporary result(this, op1);
- bitOp(op, valueOfInt32Constant(node.child2()), op1.gpr(), result.gpr());
+ bitOp(op, valueOfInt32Constant(node.child2().index()), op1.gpr(), result.gpr());
integerResult(result.gpr(), m_compileIndex);
} else {
@@ -1909,11 +1909,11 @@ void SpeculativeJIT::compile(Node& node)
case BitRShift:
case BitLShift:
case BitURShift:
- if (isInt32Constant(node.child2())) {
+ if (isInt32Constant(node.child2().index())) {
SpeculateIntegerOperand op1(this, node.child1());
GPRTemporary result(this, op1);
- shiftOp(op, op1.gpr(), valueOfInt32Constant(node.child2()) & 0x1f, result.gpr());
+ shiftOp(op, op1.gpr(), valueOfInt32Constant(node.child2().index()) & 0x1f, result.gpr());
integerResult(result.gpr(), m_compileIndex);
} else {
@@ -1940,30 +1940,6 @@ void SpeculativeJIT::compile(Node& node)
break;
}
- case ValueToNumber: {
- if (at(node.child1()).shouldNotSpeculateInteger()) {
- SpeculateDoubleOperand op1(this, node.child1());
- FPRTemporary result(this, op1);
- m_jit.moveDouble(op1.fpr(), result.fpr());
- doubleResult(result.fpr(), m_compileIndex);
- break;
- }
-
- SpeculateIntegerOperand op1(this, node.child1());
- GPRTemporary result(this, op1);
- m_jit.move(op1.gpr(), result.gpr());
- integerResult(result.gpr(), m_compileIndex, op1.format());
- break;
- }
-
- case ValueToDouble: {
- SpeculateDoubleOperand op1(this, node.child1());
- FPRTemporary result(this, op1);
- m_jit.moveDouble(op1.fpr(), result.fpr());
- doubleResult(result.fpr(), m_compileIndex);
- break;
- }
-
case ValueAdd:
case ArithAdd:
compileAdd(node);
@@ -2147,12 +2123,12 @@ void SpeculativeJIT::compile(Node& node)
break;
case CompareEq:
- if (isNullConstant(node.child1())) {
+ if (isNullConstant(node.child1().index())) {
if (nonSpeculativeCompareNull(node, node.child2()))
return;
break;
}
- if (isNullConstant(node.child2())) {
+ if (isNullConstant(node.child2().index())) {
if (nonSpeculativeCompareNull(node, node.child1()))
return;
break;
@@ -2661,7 +2637,7 @@ void SpeculativeJIT::compile(Node& node)
}
case Branch:
- if (isStrictInt32(node.child1()) || at(node.child1()).shouldSpeculateInteger()) {
+ if (isStrictInt32(node.child1().index()) || at(node.child1()).shouldSpeculateInteger()) {
SpeculateIntegerOperand op(this, node.child1());
BlockIndex taken = node.takenBlockIndex();
@@ -2738,7 +2714,7 @@ void SpeculativeJIT::compile(Node& node)
// FIXME: Add string speculation here.
- bool wasPrimitive = isKnownNumeric(node.child1()) || isKnownBoolean(node.child1());
+ bool wasPrimitive = isKnownNumeric(node.child1().index()) || isKnownBoolean(node.child1().index());
JSValueOperand op1(this, node.child1());
GPRTemporary result(this, op1);