void visitSubroutine ( final Label JSR , final long id , final int nbSubroutines ) { if ( JSR != null ) { if ( ( status & VISITED ) != 0 ) { return ; } status |= VISITED ; // adds JSR to the successors of this block, if it is a RET block if ( ( status & RET ) != 0 ) { if ( ! inSameSubroutine ( JSR ) ) { Edge e = new Edge ( ) ; e . info = inputStackTop ; e . successor = JSR . successors . successor ; e . next = successors ; successors = e ; } } } else { // if this block already belongs to subroutine 'id', returns if ( inSubroutine ( id ) ) { return ; } // marks this block as belonging to subroutine 'id' addToSubroutine ( id , nbSubroutines ) ; } // calls this method recursively on each successor, except JSR targets Edge e = successors ; while ( e != null ) { // if this block is a JSR block, then 'successors.next' leads // to the JSR target (see {@link #visitJumpInsn}) and must therefore // not be followed if ( ( status & Label . JSR ) == 0 || e != successors . next ) { e . successor . visitSubroutine ( JSR , id , nbSubroutines ) ; } e = e . next ; } }
Finds the basic blocks that belong to a given subroutine and marks these blocks as belonging to this subroutine . This recursive method follows the control flow graph to find all the blocks that are reachable from the current block WITHOUT following any JSR target .