summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-03-12 14:11:15 +0100
committerSimon Hausmann <simon.hausmann@nokia.com>2012-03-12 14:11:15 +0100
commitdd91e772430dc294e3bf478c119ef8d43c0a3358 (patch)
tree6f33ce4d5872a5691e0291eb45bf6ab373a5f567 /Source/JavaScriptCore/dfg/DFGAbstractState.cpp
parentad0d549d4cc13433f77c1ac8f0ab379c83d93f28 (diff)
downloadqtwebkit-dd91e772430dc294e3bf478c119ef8d43c0a3358.tar.gz
Imported WebKit commit 3db4eb1820ac8fb03065d7ea73a4d9db1e8fea1a (http://svn.webkit.org/repository/webkit/trunk@110422)
This includes build fixes for the latest qtbase/qtdeclarative as well as the final QML2 API.
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGAbstractState.cpp')
-rw-r--r--Source/JavaScriptCore/dfg/DFGAbstractState.cpp170
1 files changed, 122 insertions, 48 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
index ee0cc9ab7..7ab05f329 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
+++ b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
@@ -54,13 +54,7 @@ AbstractState::AbstractState(Graph& graph)
, m_variables(m_codeBlock->numParameters(), graph.m_localVars)
, m_block(0)
{
- size_t maxBlockSize = 0;
- for (size_t i = 0; i < graph.m_blocks.size(); ++i) {
- BasicBlock* block = graph.m_blocks[i].get();
- if (block->end - block->begin > maxBlockSize)
- maxBlockSize = block->end - block->begin;
- }
- m_nodes.resize(maxBlockSize);
+ m_nodes.resize(graph.size());
}
AbstractState::~AbstractState() { }
@@ -75,8 +69,9 @@ void AbstractState::beginBasicBlock(BasicBlock* basicBlock)
ASSERT(basicBlock->variablesAtTail.numberOfLocals() == basicBlock->valuesAtTail.numberOfLocals());
ASSERT(basicBlock->variablesAtHead.numberOfLocals() == basicBlock->variablesAtTail.numberOfLocals());
- for (size_t i = 0; i < basicBlock->end - basicBlock->begin; ++i)
- m_nodes[i].clear();
+ for (size_t i = 0; i < basicBlock->size(); i++)
+ m_nodes[basicBlock->at(i)].clear();
+
m_variables = basicBlock->valuesAtHead;
m_haveStructures = false;
for (size_t i = 0; i < m_variables.numberOfArguments(); ++i) {
@@ -113,6 +108,11 @@ void AbstractState::initialize(Graph& graph)
continue;
}
+ if (graph.argumentIsCaptured(i)) {
+ root->valuesAtHead.argument(i).makeTop();
+ continue;
+ }
+
PredictedType prediction = node.variableAccessData()->prediction();
if (isInt32Prediction(prediction))
root->valuesAtHead.argument(i).set(PredictInt32);
@@ -143,6 +143,11 @@ void AbstractState::initialize(Graph& graph)
else
root->valuesAtHead.argument(i).makeTop();
}
+ for (size_t i = 0; i < root->valuesAtHead.numberOfLocals(); ++i) {
+ if (!graph.localIsCaptured(i))
+ continue;
+ root->valuesAtHead.local(i).makeTop();
+ }
}
bool AbstractState::endBasicBlock(MergeMode mergeMode)
@@ -164,14 +169,28 @@ bool AbstractState::endBasicBlock(MergeMode mergeMode)
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLog(" Merging state for argument %zu.\n", argument);
#endif
- changed |= mergeStateAtTail(block->valuesAtTail.argument(argument), m_variables.argument(argument), block->variablesAtTail.argument(argument));
+ AbstractValue& destination = block->valuesAtTail.argument(argument);
+ if (m_graph.argumentIsCaptured(argument)) {
+ if (!destination.isTop()) {
+ destination.makeTop();
+ changed = true;
+ }
+ } else
+ changed |= mergeStateAtTail(destination, m_variables.argument(argument), block->variablesAtTail.argument(argument));
}
for (size_t local = 0; local < block->variablesAtTail.numberOfLocals(); ++local) {
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLog(" Merging state for local %zu.\n", local);
#endif
- changed |= mergeStateAtTail(block->valuesAtTail.local(local), m_variables.local(local), block->variablesAtTail.local(local));
+ AbstractValue& destination = block->valuesAtTail.local(local);
+ if (m_graph.localIsCaptured(local)) {
+ if (!destination.isTop()) {
+ destination.makeTop();
+ changed = true;
+ }
+ } else
+ changed |= mergeStateAtTail(destination, m_variables.local(local), block->variablesAtTail.local(local));
}
}
@@ -191,12 +210,13 @@ void AbstractState::reset()
m_isValid = false;
}
-bool AbstractState::execute(NodeIndex nodeIndex)
+bool AbstractState::execute(unsigned indexInBlock)
{
PROFILE(FLAG_FOR_EXECUTION);
ASSERT(m_block);
ASSERT(m_isValid);
+ NodeIndex nodeIndex = m_block->at(indexInBlock);
Node& node = m_graph[nodeIndex];
if (!node.shouldGenerate())
@@ -216,11 +236,17 @@ bool AbstractState::execute(NodeIndex nodeIndex)
}
case GetLocal: {
- forNode(nodeIndex) = m_variables.operand(node.local());
+ if (m_graph.isCaptured(node.local()))
+ forNode(nodeIndex).makeTop();
+ else
+ forNode(nodeIndex) = m_variables.operand(node.local());
break;
}
case SetLocal: {
+ if (m_graph.isCaptured(node.local()))
+ break;
+
if (node.variableAccessData()->shouldUseDoubleFormat()) {
forNode(node.child1()).filter(PredictNumber);
m_variables.operand(node.local()).set(PredictDouble);
@@ -265,12 +291,12 @@ bool AbstractState::execute(NodeIndex nodeIndex)
break;
case ValueToInt32:
- if (!m_graph[node.child1()].shouldNotSpeculateInteger()) {
+ if (m_graph[node.child1()].shouldNotSpeculateInteger()) {
if (m_graph[node.child1()].shouldSpeculateDouble())
forNode(node.child1()).filter(PredictNumber);
- else
- forNode(node.child1()).filter(PredictInt32);
- }
+ } else
+ forNode(node.child1()).filter(PredictInt32);
+
forNode(nodeIndex).set(PredictInt32);
break;
@@ -289,7 +315,7 @@ bool AbstractState::execute(NodeIndex nodeIndex)
break;
}
if (node.op == ValueAdd) {
- clobberStructures(nodeIndex);
+ clobberStructures(indexInBlock);
forNode(nodeIndex).set(PredictString | PredictInt32 | PredictNumber);
break;
}
@@ -311,6 +337,17 @@ bool AbstractState::execute(NodeIndex nodeIndex)
break;
}
+ case ArithNegate: {
+ if (m_graph.negateShouldSpeculateInteger(node)) {
+ forNode(node.child1()).filter(PredictInt32);
+ forNode(nodeIndex).set(PredictInt32);
+ break;
+ }
+ forNode(node.child1()).filter(PredictNumber);
+ forNode(nodeIndex).set(PredictDouble);
+ break;
+ }
+
case ArithMul:
case ArithDiv:
case ArithMin:
@@ -368,7 +405,7 @@ bool AbstractState::execute(NodeIndex nodeIndex)
else if (child.shouldSpeculateNumber())
forNode(node.child1()).filter(PredictNumber);
else
- clobberStructures(nodeIndex);
+ clobberStructures(indexInBlock);
forNode(nodeIndex).set(PredictBoolean);
break;
}
@@ -391,7 +428,7 @@ bool AbstractState::execute(NodeIndex nodeIndex)
filter = PredictArray;
else {
filter = PredictTop;
- clobberStructures(nodeIndex);
+ clobberStructures(indexInBlock);
}
forNode(node.child1()).filter(filter);
forNode(node.child2()).filter(filter);
@@ -421,7 +458,7 @@ bool AbstractState::execute(NodeIndex nodeIndex)
break;
}
if (!isActionableArrayPrediction(m_graph[node.child1()].prediction()) || !m_graph[node.child2()].shouldSpeculateInteger()) {
- clobberStructures(nodeIndex);
+ clobberStructures(indexInBlock);
forNode(nodeIndex).makeTop();
break;
}
@@ -507,7 +544,7 @@ bool AbstractState::execute(NodeIndex nodeIndex)
}
if (!m_graph[node.child2()].shouldSpeculateInteger() || !isActionableMutableArrayPrediction(m_graph[node.child1()].prediction())) {
ASSERT(node.op == PutByVal);
- clobberStructures(nodeIndex);
+ clobberStructures(indexInBlock);
forNode(nodeIndex).makeTop();
break;
}
@@ -693,10 +730,25 @@ bool AbstractState::execute(NodeIndex nodeIndex)
}
case NewObject:
- forNode(nodeIndex).set(m_codeBlock->globalObject()->emptyObjectStructure());
+ forNode(nodeIndex).set(m_codeBlock->globalObjectFor(node.codeOrigin)->emptyObjectStructure());
m_haveStructures = true;
break;
-
+
+ case CreateActivation:
+ forNode(nodeIndex).set(m_graph.m_globalData.activationStructure.get());
+ m_haveStructures = true;
+ break;
+
+ case TearOffActivation:
+ // Does nothing that is user-visible.
+ break;
+
+ case NewFunction:
+ case NewFunctionExpression:
+ case NewFunctionNoCheck:
+ forNode(nodeIndex).set(m_codeBlock->globalObjectFor(node.codeOrigin)->functionStructure());
+ break;
+
case GetCallee:
forNode(nodeIndex).set(PredictFunction);
break;
@@ -710,7 +762,7 @@ bool AbstractState::execute(NodeIndex nodeIndex)
break;
case PutScopedVar:
- clobberStructures(nodeIndex);
+ clobberStructures(indexInBlock);
break;
case GetById:
@@ -721,7 +773,7 @@ bool AbstractState::execute(NodeIndex nodeIndex)
}
if (isCellPrediction(m_graph[node.child1()].prediction()))
forNode(node.child1()).filter(PredictCell);
- clobberStructures(nodeIndex);
+ clobberStructures(indexInBlock);
forNode(nodeIndex).makeTop();
break;
@@ -783,7 +835,7 @@ bool AbstractState::execute(NodeIndex nodeIndex)
break;
case PutStructure:
- clobberStructures(nodeIndex);
+ clobberStructures(indexInBlock);
forNode(node.child1()).set(node.structureTransitionData().newStructure);
m_haveStructures = true;
break;
@@ -874,7 +926,7 @@ bool AbstractState::execute(NodeIndex nodeIndex)
case PutById:
case PutByIdDirect:
forNode(node.child1()).filter(PredictCell);
- clobberStructures(nodeIndex);
+ clobberStructures(indexInBlock);
break;
case GetGlobalVar:
@@ -910,7 +962,7 @@ bool AbstractState::execute(NodeIndex nodeIndex)
case ResolveBase:
case ResolveBaseStrictPut:
case ResolveGlobal:
- clobberStructures(nodeIndex);
+ clobberStructures(indexInBlock);
forNode(nodeIndex).makeTop();
break;
@@ -927,13 +979,13 @@ bool AbstractState::execute(NodeIndex nodeIndex)
return m_isValid;
}
-inline void AbstractState::clobberStructures(NodeIndex nodeIndex)
+inline void AbstractState::clobberStructures(unsigned indexInBlock)
{
PROFILE(FLAG_FOR_STRUCTURE_CLOBBERING);
if (!m_haveStructures)
return;
- for (size_t i = nodeIndex - m_block->begin + 1; i-- > 0;)
- m_nodes[i].clobberStructures();
+ for (size_t i = indexInBlock + 1; i--;)
+ forNode(m_block->at(i)).clobberStructures();
for (size_t i = 0; i < m_variables.numberOfArguments(); ++i)
m_variables.argument(i).clobberStructures();
for (size_t i = 0; i < m_variables.numberOfLocals(); ++i)
@@ -946,7 +998,7 @@ inline bool AbstractState::mergeStateAtTail(AbstractValue& destination, Abstract
if (nodeIndex == NoNode)
return false;
- AbstractValue* source;
+ AbstractValue source;
Node& node = m_graph[nodeIndex];
if (!node.refCount())
@@ -961,7 +1013,7 @@ inline bool AbstractState::mergeStateAtTail(AbstractValue& destination, Abstract
case SetArgument:
case Flush:
// The block transfers the value from head to tail.
- source = &inVariable;
+ source = inVariable;
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLog(" Transfering from head to tail.\n");
#endif
@@ -969,7 +1021,7 @@ inline bool AbstractState::mergeStateAtTail(AbstractValue& destination, Abstract
case GetLocal:
// The block refines the value with additional speculations.
- source = &forNode(nodeIndex);
+ source = forNode(nodeIndex);
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLog(" Refining.\n");
#endif
@@ -978,7 +1030,10 @@ inline bool AbstractState::mergeStateAtTail(AbstractValue& destination, Abstract
case SetLocal:
// The block sets the variable, and potentially refines it, both
// before and after setting it.
- source = &forNode(node.child1());
+ if (node.variableAccessData()->shouldUseDoubleFormat())
+ source.set(PredictDouble);
+ else
+ source = forNode(node.child1());
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLog(" Setting.\n");
#endif
@@ -986,11 +1041,10 @@ inline bool AbstractState::mergeStateAtTail(AbstractValue& destination, Abstract
default:
ASSERT_NOT_REACHED();
- source = 0;
break;
}
- if (destination == *source) {
+ if (destination == source) {
// Abstract execution did not change the output value of the variable, for this
// basic block, on this iteration.
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
@@ -1002,7 +1056,7 @@ inline bool AbstractState::mergeStateAtTail(AbstractValue& destination, Abstract
// Abstract execution reached a new conclusion about the speculations reached about
// this variable after execution of this basic block. Update the state, and return
// true to indicate that the fixpoint must go on!
- destination = *source;
+ destination = source;
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLog(" Changed!\n");
#endif
@@ -1016,11 +1070,29 @@ inline bool AbstractState::merge(BasicBlock* from, BasicBlock* to)
bool changed = false;
- for (size_t argument = 0; argument < from->variablesAtTail.numberOfArguments(); ++argument)
- changed |= mergeVariableBetweenBlocks(to->valuesAtHead.argument(argument), from->valuesAtTail.argument(argument), to->variablesAtHead.argument(argument), from->variablesAtTail.argument(argument));
+ for (size_t argument = 0; argument < from->variablesAtTail.numberOfArguments(); ++argument) {
+ AbstractValue& destination = to->valuesAtHead.argument(argument);
+ if (m_graph.argumentIsCaptured(argument)) {
+ if (destination.isTop())
+ continue;
+ destination.makeTop();
+ changed = true;
+ continue;
+ }
+ changed |= mergeVariableBetweenBlocks(destination, from->valuesAtTail.argument(argument), to->variablesAtHead.argument(argument), from->variablesAtTail.argument(argument));
+ }
- for (size_t local = 0; local < from->variablesAtTail.numberOfLocals(); ++local)
- changed |= mergeVariableBetweenBlocks(to->valuesAtHead.local(local), from->valuesAtTail.local(local), to->variablesAtHead.local(local), from->variablesAtTail.local(local));
+ for (size_t local = 0; local < from->variablesAtTail.numberOfLocals(); ++local) {
+ AbstractValue& destination = to->valuesAtHead.local(local);
+ if (m_graph.localIsCaptured(local)) {
+ if (destination.isTop())
+ continue;
+ destination.makeTop();
+ changed = true;
+ continue;
+ }
+ changed |= mergeVariableBetweenBlocks(destination, from->valuesAtTail.local(local), to->variablesAtHead.local(local), from->variablesAtTail.local(local));
+ }
if (!to->cfaHasVisited)
changed = true;
@@ -1034,7 +1106,7 @@ inline bool AbstractState::mergeToSuccessors(Graph& graph, BasicBlock* basicBloc
{
PROFILE(FLAG_FOR_MERGE_TO_SUCCESSORS);
- Node& terminal = graph[basicBlock->end - 1];
+ Node& terminal = graph[basicBlock->last()];
ASSERT(terminal.isTerminal());
@@ -1073,15 +1145,17 @@ inline bool AbstractState::mergeVariableBetweenBlocks(AbstractValue& destination
void AbstractState::dump(FILE* out)
{
bool first = true;
- for (size_t i = 0; i < m_nodes.size(); ++i) {
- if (m_nodes[i].isClear())
+ for (size_t i = 0; i < m_block->size(); ++i) {
+ NodeIndex index = m_block->at(i);
+ AbstractValue& value = m_nodes[index];
+ if (value.isClear())
continue;
if (first)
first = false;
else
fprintf(out, " ");
- fprintf(out, "@%lu:", static_cast<unsigned long>(i + m_block->begin));
- m_nodes[i].dump(out);
+ fprintf(out, "@%lu:", static_cast<unsigned long>(index));
+ value.dump(out);
}
}
#endif