summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/dfg/DFGGraph.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGGraph.h')
-rw-r--r--Source/JavaScriptCore/dfg/DFGGraph.h83
1 files changed, 82 insertions, 1 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGGraph.h b/Source/JavaScriptCore/dfg/DFGGraph.h
index fdb78cf9b..8d164a299 100644
--- a/Source/JavaScriptCore/dfg/DFGGraph.h
+++ b/Source/JavaScriptCore/dfg/DFGGraph.h
@@ -76,11 +76,13 @@ struct ResolveGlobalData {
// Nodes that are 'dead' remain in the vector with refCount 0.
class Graph : public Vector<Node, 64> {
public:
- Graph(JSGlobalData& globalData, CodeBlock* codeBlock)
+ Graph(JSGlobalData& globalData, CodeBlock* codeBlock, unsigned osrEntryBytecodeIndex, const Operands<JSValue>& mustHandleValues)
: m_globalData(globalData)
, m_codeBlock(codeBlock)
, m_profiledBlock(codeBlock->alternative())
, m_hasArguments(false)
+ , m_osrEntryBytecodeIndex(osrEntryBytecodeIndex)
+ , m_mustHandleValues(mustHandleValues)
{
ASSERT(m_profiledBlock);
}
@@ -137,6 +139,20 @@ public:
edge = newEdge;
}
+ void compareAndSwap(Edge& edge, NodeIndex oldIndex, NodeIndex newIndex, bool changeRef)
+ {
+ if (edge.index() != oldIndex)
+ return;
+ changeIndex(edge, newIndex, changeRef);
+ }
+
+ void compareAndSwap(Edge& edge, Edge oldEdge, Edge newEdge, bool changeRef)
+ {
+ if (edge != oldEdge)
+ return;
+ changeEdge(edge, newEdge, changeRef);
+ }
+
void clearAndDerefChild1(Node& node)
{
if (!node.child1())
@@ -614,6 +630,69 @@ public:
vote(node.child3(), ballot);
}
+ template<typename T> // T = NodeIndex or Edge
+ void substitute(BasicBlock& block, unsigned startIndexInBlock, T oldThing, T newThing)
+ {
+ for (unsigned indexInBlock = startIndexInBlock; indexInBlock < block.size(); ++indexInBlock) {
+ NodeIndex nodeIndex = block[indexInBlock];
+ Node& node = at(nodeIndex);
+ if (node.flags() & NodeHasVarArgs) {
+ for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); ++childIdx)
+ compareAndSwap(m_varArgChildren[childIdx], oldThing, newThing, node.shouldGenerate());
+ continue;
+ }
+ if (!node.child1())
+ continue;
+ compareAndSwap(node.children.child1(), oldThing, newThing, node.shouldGenerate());
+ if (!node.child2())
+ continue;
+ compareAndSwap(node.children.child2(), oldThing, newThing, node.shouldGenerate());
+ if (!node.child3())
+ continue;
+ compareAndSwap(node.children.child3(), oldThing, newThing, node.shouldGenerate());
+ }
+ }
+
+ // Use this if you introduce a new GetLocal and you know that you introduced it *before*
+ // any GetLocals in the basic block.
+ // FIXME: it may be appropriate, in the future, to generalize this to handle GetLocals
+ // introduced anywhere in the basic block.
+ void substituteGetLocal(BasicBlock& block, unsigned startIndexInBlock, VariableAccessData* variableAccessData, NodeIndex newGetLocal)
+ {
+ if (variableAccessData->isCaptured()) {
+ // Let CSE worry about this one.
+ return;
+ }
+ for (unsigned indexInBlock = startIndexInBlock; indexInBlock < block.size(); ++indexInBlock) {
+ NodeIndex nodeIndex = block[indexInBlock];
+ Node& node = at(nodeIndex);
+ bool shouldContinue = true;
+ switch (node.op()) {
+ case SetLocal: {
+ if (node.local() == variableAccessData->local())
+ shouldContinue = false;
+ break;
+ }
+
+ case GetLocal: {
+ if (node.variableAccessData() != variableAccessData)
+ continue;
+ substitute(block, indexInBlock, nodeIndex, newGetLocal);
+ NodeIndex oldTailIndex = block.variablesAtTail.operand(variableAccessData->local());
+ if (oldTailIndex == nodeIndex)
+ block.variablesAtTail.operand(variableAccessData->local()) = newGetLocal;
+ shouldContinue = false;
+ break;
+ }
+
+ default:
+ break;
+ }
+ if (!shouldContinue)
+ break;
+ }
+ }
+
JSGlobalData& m_globalData;
CodeBlock* m_codeBlock;
CodeBlock* m_profiledBlock;
@@ -633,6 +712,8 @@ public:
Dominators m_dominators;
unsigned m_localVars;
unsigned m_parameterSlots;
+ unsigned m_osrEntryBytecodeIndex;
+ Operands<JSValue> m_mustHandleValues;
private:
void handleSuccessor(Vector<BlockIndex, 16>& worklist, BlockIndex blockIndex, BlockIndex successorIndex);