Index: vm/jitrino/src/codegenerator/ia32/Ia32CodeSelector.cpp =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32CodeSelector.cpp (revision 483044) +++ vm/jitrino/src/codegenerator/ia32/Ia32CodeSelector.cpp (working copy) @@ -441,6 +441,21 @@ assert(target!=NULL); fg->addEdge(node, target, 1.0); } + // fixup empty catch blocks otherwise respective catchEdges will be lost + // There is no [catchBlock]-->[catchHandler] edge. Catch block will be removed + // as an empty one and exception handling will be incorrect + if (node->isCatchBlock() && node->isEmpty()) { + assert(node->getInDegree()==1); + Edge* catchEdge = node->getInEdges().front(); + assert(catchEdge->getSourceNode()->isDispatchNode()); + assert(node->getOutDegree()==1); + Node* succ = node->getUnconditionalEdgeTarget(); + while( succ->isEmpty() && (succ->getOutDegree() == 1) ) { + succ = succ->getUnconditionalEdgeTarget(); + } + assert(succ && ((Inst*)succ->getFirstInst())->hasKind(Inst::Kind_CatchPseudoInst)); + fg->replaceEdgeTarget(catchEdge,succ,true/*keepOldBody*/); + } } } } Index: vm/jitrino/src/shared/ControlFlowGraph.h =================================================================== --- vm/jitrino/src/shared/ControlFlowGraph.h (revision 481228) +++ vm/jitrino/src/shared/ControlFlowGraph.h (working copy) @@ -1287,17 +1287,17 @@ * Removes the edge, creates a new one and connects it to * the newTarget node. * - * @param[in] edge - the edge to change the target - * @param[in] newTarget - a new Target node + * @param[in] edge - the edge to change the target + * @param[in] newTarget - a new Target node + * @param[in] keepOldBody - modify old or create a new edge * * @return The edge connecting the Source node of the * edge and the newTarget node. * - * @note The removal of the old edge is obsolete and should be refactored. - * The only place to take care is retargeting edges + * @note The removal of the old edge is needed * while inlining CFG: edge IDs must be renewed. */ - Edge* replaceEdgeTarget(Edge* edge, Node *newTarget); + Edge* replaceEdgeTarget(Edge* edge, Node *newTarget, bool keepOldBody = false); /** * Checks if CFG is annotated with the edge profile information. Index: vm/jitrino/src/shared/ControlFlowGraph.cpp =================================================================== --- vm/jitrino/src/shared/ControlFlowGraph.cpp (revision 481228) +++ vm/jitrino/src/shared/ControlFlowGraph.cpp (working copy) @@ -302,13 +302,19 @@ lastEdgeRemovalTraversalNumber = traversalNumber; } -Edge* ControlFlowGraph::replaceEdgeTarget(Edge* edge, Node* newTarget) { +Edge* ControlFlowGraph::replaceEdgeTarget(Edge* edge, Node* newTarget, bool keepOldBody) { Node* source = edge->getSourceNode(); Node* oldTarget = edge->getTargetNode(); CFGInst* lastInst = source->getLastInst(); - - removeEdge(edge); - Edge* newEdge = addEdge(source, newTarget); + + Edge* newEdge = NULL; + if (keepOldBody) { + edge->target = newTarget; + newEdge = edge; + } else { + removeEdge(edge); + newEdge = addEdge(source, newTarget); + } if (lastInst!=NULL) { lastInst->updateControlTransferInst(oldTarget, newTarget); }