diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-05-25 15:09:11 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-05-25 15:09:11 +0200 |
commit | a89b2ebb8e192c5e8cea21079bda2ee2c0c7dddd (patch) | |
tree | b7abd9f49ae1d4d2e426a5883bfccd42b8e2ee12 /Source/JavaScriptCore/dfg/DFGGraph.cpp | |
parent | 8d473cf9743f1d30a16a27114e93bd5af5648d23 (diff) | |
download | qtwebkit-a89b2ebb8e192c5e8cea21079bda2ee2c0c7dddd.tar.gz |
Imported WebKit commit eb5c1b8fe4d4b1b90b5137433fc58a91da0e6878 (http://svn.webkit.org/repository/webkit/trunk@118516)
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGGraph.cpp')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGGraph.cpp | 151 |
1 files changed, 143 insertions, 8 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGGraph.cpp b/Source/JavaScriptCore/dfg/DFGGraph.cpp index 3c99e5d4e..4562e30ee 100644 --- a/Source/JavaScriptCore/dfg/DFGGraph.cpp +++ b/Source/JavaScriptCore/dfg/DFGGraph.cpp @@ -65,7 +65,7 @@ const char* Graph::nameOfVariableAccessData(VariableAccessData* variableAccessDa if (!index) return "A"; - static char buf[10]; + static char buf[100]; BoundsCheckedPointer<char> ptr(buf, sizeof(buf)); while (index) { @@ -73,6 +73,11 @@ const char* Graph::nameOfVariableAccessData(VariableAccessData* variableAccessDa index /= 26; } + if (variableAccessData->isCaptured()) + *ptr++ = '*'; + + ptr.strcat(predictionToAbbreviatedString(variableAccessData->prediction())); + *ptr++ = 0; return buf; @@ -126,10 +131,8 @@ void Graph::dump(NodeIndex nodeIndex) unsigned refCount = node.refCount(); bool skipped = !refCount; bool mustGenerate = node.mustGenerate(); - if (mustGenerate) { - ASSERT(refCount); + if (mustGenerate) --refCount; - } printWhiteSpace((node.codeOrigin.inlineDepth() - 1) * 2); @@ -166,7 +169,8 @@ void Graph::dump(NodeIndex nodeIndex) dataLog("%s@%u%s", useKindToString(m_varArgChildren[childIdx].useKind()), m_varArgChildren[childIdx].index(), - predictionToAbbreviatedString(at(childIdx).prediction())); + predictionToAbbreviatedString( + at(m_varArgChildren[childIdx]).prediction())); } } else { if (!!node.child1()) { @@ -278,12 +282,34 @@ void Graph::dump() NodeIndex lastNodeIndex = NoNode; for (size_t b = 0; b < m_blocks.size(); ++b) { BasicBlock* block = m_blocks[b].get(); + if (!block) + continue; dataLog("Block #%u (bc#%u): %s%s\n", (int)b, block->bytecodeBegin, block->isReachable ? "" : " (skipped)", block->isOSRTarget ? " (OSR target)" : ""); + dataLog(" Predecessors:"); + for (size_t i = 0; i < block->m_predecessors.size(); ++i) + dataLog(" #%u", block->m_predecessors[i]); + dataLog("\n"); + if (m_dominators.isValid()) { + dataLog(" Dominated by:"); + for (size_t i = 0; i < m_blocks.size(); ++i) { + if (!m_dominators.dominates(i, b)) + continue; + dataLog(" #%lu", static_cast<unsigned long>(i)); + } + dataLog("\n"); + dataLog(" Dominates:"); + for (size_t i = 0; i < m_blocks.size(); ++i) { + if (!m_dominators.dominates(b, i)) + continue; + dataLog(" #%lu", static_cast<unsigned long>(i)); + } + dataLog("\n"); + } dataLog(" Phi Nodes:\n"); for (size_t i = 0; i < block->phis.size(); ++i) { - // Dumping the dead Phi nodes is just annoying! - if (at(block->phis[i]).refCount()) - dump(block->phis[i]); + dumpCodeOrigin(lastNodeIndex, block->phis[i]); + dump(block->phis[i]); + lastNodeIndex = block->phis[i]; } dataLog(" vars before: "); if (block->cfaHasVisited) @@ -305,6 +331,9 @@ void Graph::dump() else dataLog("<empty>"); dataLog("\n"); + dataLog(" var links: "); + dumpOperands(block->variablesAtTail, WTF::dataFile()); + dataLog("\n"); } } @@ -362,6 +391,112 @@ void Graph::predictArgumentTypes() } } +void Graph::handleSuccessor(Vector<BlockIndex, 16>& worklist, BlockIndex blockIndex, BlockIndex successorIndex) +{ + BasicBlock* successor = m_blocks[successorIndex].get(); + if (!successor->isReachable) { + successor->isReachable = true; + worklist.append(successorIndex); + } + + successor->m_predecessors.append(blockIndex); +} + +void Graph::collectGarbage() +{ + // First reset the counts to 0 for all nodes. + for (unsigned i = size(); i--;) + at(i).setRefCount(0); + + // Now find the roots: the nodes that are must-generate. Set their ref counts to + // 1 and put them on the worklist. + Vector<NodeIndex, 128> worklist; + for (BlockIndex blockIndex = 0; blockIndex < m_blocks.size(); ++blockIndex) { + BasicBlock* block = m_blocks[blockIndex].get(); + if (!block) + continue; + for (unsigned indexInBlock = block->size(); indexInBlock--;) { + NodeIndex nodeIndex = block->at(indexInBlock); + Node& node = at(nodeIndex); + if (!(node.flags() & NodeMustGenerate)) + continue; + node.setRefCount(1); + worklist.append(nodeIndex); + } + } + + while (!worklist.isEmpty()) { + NodeIndex nodeIndex = worklist.last(); + worklist.removeLast(); + Node& node = at(nodeIndex); + ASSERT(node.shouldGenerate()); // It should not be on the worklist unless it's ref'ed. + if (node.flags() & NodeHasVarArgs) { + for (unsigned childIdx = node.firstChild(); + childIdx < node.firstChild() + node.numChildren(); + ++childIdx) { + NodeIndex childNodeIndex = m_varArgChildren[childIdx].index(); + if (!at(childNodeIndex).ref()) + continue; + worklist.append(childNodeIndex); + } + } else if (node.child1()) { + if (at(node.child1()).ref()) + worklist.append(node.child1().index()); + if (node.child2()) { + if (at(node.child2()).ref()) + worklist.append(node.child2().index()); + if (node.child3()) { + if (at(node.child3()).ref()) + worklist.append(node.child3().index()); + } + } + } + } +} + +void Graph::determineReachability() +{ + Vector<BlockIndex, 16> worklist; + worklist.append(0); + m_blocks[0]->isReachable = true; + while (!worklist.isEmpty()) { + BlockIndex index = worklist.last(); + worklist.removeLast(); + + BasicBlock* block = m_blocks[index].get(); + ASSERT(block->isLinked); + + Node& node = at(block->last()); + ASSERT(node.isTerminal()); + + if (node.isJump()) + handleSuccessor(worklist, index, node.takenBlockIndex()); + else if (node.isBranch()) { + handleSuccessor(worklist, index, node.takenBlockIndex()); + handleSuccessor(worklist, index, node.notTakenBlockIndex()); + } + } +} + +void Graph::resetReachability() +{ + for (BlockIndex blockIndex = m_blocks.size(); blockIndex--;) { + BasicBlock* block = m_blocks[blockIndex].get(); + if (!block) + continue; + block->isReachable = false; + block->m_predecessors.clear(); + } + + determineReachability(); +} + +void Graph::resetExitStates() +{ + for (unsigned i = size(); i--;) + at(i).setCanExit(true); +} + } } // namespace JSC::DFG #endif |