Index: vm/jitrino/src/optimizer/syncopt.cpp =================================================================== --- vm/jitrino/src/optimizer/syncopt.cpp (revision 512248) +++ vm/jitrino/src/optimizer/syncopt.cpp (working copy) @@ -2111,18 +2111,24 @@ -DEFINE_SESSION_ACTION(SO2, so2, "SyncOpt2") +DEFINE_SESSION_ACTION(SO2, so2, "Nested synchronizations removal") - - void SO2::_run(IRManager& irm) { + MemoryManager tmpMM(1024, "SO2MM"); + ControlFlowGraph& fg = irm.getFlowGraph(); OptPass::computeDominators(irm); - ControlFlowGraph& fg = irm.getFlowGraph(); - MemoryManager tmpMM(1024, "SO2MM"); - StlVector monenters(tmpMM); DominatorTree* dom = fg.getDominatorTree(); - - const Nodes& nodes = fg.getNodesPostOrder(); + SyncOpt2 opt(tmpMM, fg, dom); + opt.runOpt(); +} + +SyncOpt2::SyncOpt2(MemoryManager& memManager, ControlFlowGraph& fg, DominatorTree* dt) +: mm(memManager), flowGraph(fg), domTree(dt) {} + +void SyncOpt2::runOpt() { + StlVector monenters(mm); + const Nodes& nodes = flowGraph.getNodesPostOrder(); + for (Nodes::const_iterator it = nodes.begin(), end = nodes.end(); it!=end; ++it) { Node* node = *it; for (Inst* inst = (Inst*)node->getFirstInst(); inst!=NULL; inst = inst->getNextInst()) { @@ -2133,23 +2139,16 @@ if (child->getNode()==NULL) { continue; } - if (child->getSrc(0) == inst->getSrc(0) && dom->dominates(inst->getNode(), child->getNode())) { - //clean child - int nExits=0; + Opnd* monObject = child->getSrc(0); + if ((monObject == inst->getSrc(0)) && domTree->dominates(inst->getNode(), child->getNode())) { + // Find a proper child to clean + int nExits = 0; Node* enterNode = child->getNode(); - Node* exitNode = NULL; - for (Nodes::const_iterator it2 = nodes.begin();exitNode!=enterNode; ++it2) { - exitNode = *it2; - Inst* exit = (Inst*)exitNode->getLastInst(); - if (exit->getOpcode() == Op_TauMonitorExit && exit->getSrc(0) == child->getSrc(0) && dom->dominates(enterNode, exitNode)) { -// printf("+++++++++++++++++++++++++++++++FOUND\n"); - Edge* exc = exitNode->getExceptionEdge(); - fg.removeEdge(exc); - exit->unlink(); - nExits++; - } - } - assert(nExits>0); + StlSet monexits(mm); + + findClosestMonExit(enterNode, monObject, nExits, monexits); + + assert(nExits > 0); child->unlink(); } } @@ -2158,5 +2157,29 @@ } } +void SyncOpt2::findClosestMonExit(Node* enterNode, Opnd* monObject, int& nExits, StlSet& monexits) { + const Edges& outEdges = enterNode->getOutEdges(); + Edges::const_iterator eit; + Node* exitNode; + for (eit = outEdges.begin(); eit != outEdges.end(); ++eit) { + exitNode = (*eit)->getTargetNode(); + assert(exitNode != flowGraph.getExitNode()); + if (monexits.has(exitNode)) { + continue; + } + Inst* exit = (Inst*)exitNode->getLastInst(); + if ((exit->getOpcode() == Op_TauMonitorExit) + && (exit->getSrc(0) == monObject) + && domTree->dominates(enterNode, exitNode)) { + Edge* excEdge = exitNode->getExceptionEdge(); + flowGraph.removeEdge(excEdge); + exit->unlink(); + nExits++; + monexits.insert(exitNode); + } else { + findClosestMonExit(exitNode, monObject, nExits, monexits); + } + } +} } //namespace Jitrino Index: vm/jitrino/src/optimizer/syncopt.h =================================================================== --- vm/jitrino/src/optimizer/syncopt.h (revision 512248) +++ vm/jitrino/src/optimizer/syncopt.h (working copy) @@ -131,6 +131,17 @@ Node *tmpRethrowNode); }; +class SyncOpt2 { +public: + SyncOpt2(MemoryManager& memManager, ControlFlowGraph& fg, DominatorTree* dt); + void runOpt(); + void findClosestMonExit(Node* enterNode, Opnd* monObject, int& nExits, StlSet& monexits); +private: + MemoryManager &mm; + ControlFlowGraph& flowGraph; + DominatorTree* domTree; +}; + } //namespace Jitrino #endif // _MEMORY_OPT_H