Index: src/test/regression/H3225/PositiveJsrTest.j =================================================================== --- src/test/regression/H3225/PositiveJsrTest.j (revision 542211) +++ src/test/regression/H3225/PositiveJsrTest.j (working copy) @@ -39,6 +39,9 @@ aload_0 invokevirtual org/apache/harmony/drlvm/tests/regression/h3225/PositiveJsrTest/testBranches()V + aload_0 + invokevirtual org/apache/harmony/drlvm/tests/regression/h3225/PositiveJsrTest/testUnreachableNodes()V + return .end method @@ -202,3 +205,23 @@ .end method + +; +; Subroutine graph contains several unreachable nodes. +; +.method public testUnreachableNodes()V + .limit stack 1 + .limit locals 1 + + return +LabelBackward: + aconst_null + ifnull LabelForward + aconst_null + ifnull LabelBackward +LabelForward: + aconst_null + ifnull LabelBackward + jsr LabelBackward +.end method + Index: vm/vmcore/src/verifier/Graph.cpp =================================================================== --- vm/vmcore/src/verifier/Graph.cpp (revision 542211) +++ vm/vmcore/src/verifier/Graph.cpp (working copy) @@ -124,7 +124,8 @@ size_t len = strlen( class_name ) + strlen( m_ctx->m_name ) + strlen( m_ctx->m_descriptor ) + 6; char *fname = (char*)STD_ALLOCA( len ); - sprintf( fname, "%s_%s%s", class_name, m_ctx->m_name, m_ctx->m_descriptor ); + sprintf( fname, "%s_%s%s", class_name, m_ctx->m_name, + m_ctx->m_descriptor ); char *f_start; char *pointer; @@ -165,7 +166,8 @@ return; } // create name of graph - sprintf( fname, "%s.%s%s", class_name, m_ctx->m_name, m_ctx->m_descriptor ); + sprintf( fname, "%s.%s%s", class_name, m_ctx->m_name, + m_ctx->m_descriptor ); // print graph to file DumpDotHeader( f_start, fout ); @@ -640,6 +642,9 @@ for( ; node->m_type != VF_NODE_END_ENTRY; node++ ) { assert( VF_NODE_CODE_RANGE == node->m_type ); if( !node->m_mark ) { + VF_TRACE( "null", + "Cleaning unreachable node #" << ctx->m_graph-> + GetNodeNum( node ) ); unsigned char *instr = node->m_start->m_addr; const unsigned char *end = vf_get_instr_end( node->m_end, ctx ); while( instr < end ) { @@ -650,7 +655,14 @@ // so we rarely remove edges here is rare for( vf_EdgeHandle edge = node->m_outedge; edge; edge = edge->m_outnext ) { - vf_remove_inedge( edge ); + assert( edge->m_start == node ); + VF_TRACE( "null", "Cleaning unreachable edge #" + << ctx->m_graph->GetNodeNum( node ) << " -> #" + << ctx->m_graph->GetNodeNum( edge->m_end ) ); + if( edge->m_end->m_mark ) { + // remove edges to reachable nodes + vf_remove_inedge( edge ); + } } node->m_inedge = node->m_outedge = NULL; node->m_sub = NULL;