You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by ko...@apache.org on 2005/12/28 21:26:00 UTC
svn commit: r359623 -
/jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/Subroutines.java
Author: kohsuke
Date: Wed Dec 28 12:25:59 2005
New Revision: 359623
URL: http://svn.apache.org/viewcvs?rev=359623&view=rev
Log:
fixed an instrumentation bug where an exception handler is used inside a finally block.
Modified:
jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/Subroutines.java
Modified: jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/Subroutines.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/Subroutines.java?rev=359623&r1=359622&r2=359623&view=diff
==============================================================================
--- jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/Subroutines.java (original)
+++ jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/Subroutines.java Wed Dec 28 12:25:59 2005
@@ -52,11 +52,6 @@
* of a JSR of JSR_W instruction and ends at a corresponding RET
* instruction. Note also that the control flow of a subroutine
* may be complex and non-linear; and that subroutines may be nested.
- * JustIce also mandates subroutines not to be protected by exception
- * handling code (for the sake of control flow predictability).
- * To understand JustIce's notion of subroutines, please read
- *
- * TODO: refer to the paper.
*
* WARNING! These classes are a fork of the bcel verifier.
*
@@ -403,31 +398,42 @@
// set of InstructionHandles reachable from the top
Set closure = new HashSet();
- // Do a BFS with "actual" as the root of the graph.
- InstructionHandle actual = (InstructionHandle) (iter.next());
- // Init Queue
+ // Init Queue. Start with the entry point of closure.
+ InstructionHandle leader = (InstructionHandle) (iter.next());
ArrayList Q = new ArrayList();
- Q.add(actual);
-
- /* DFS ALGORITHM MODIFICATION: Start out with multiple "root" nodes, as exception handlers are starting points of top-level code, too. [why top-level? TODO: Refer to the special JustIce notion of subroutines.]*/
- if (actual == all[0]){
- for (int j=0; j<handlers.length; j++){
- Q.add(handlers[j].getHandlerPC());
- }
- }
- /* CONTINUE NORMAL BFS ALGORITHM */
+ Q.add(leader);
- while (!Q.isEmpty()){
- InstructionHandle u = (InstructionHandle) Q.remove(Q.size()-1);
- if(closure.add(u)) {
- InstructionHandle[] successors = getSuccessors(u);
- for (int i=0; i<successors.length; i++){
- Q.add(successors[i]);
+ while (!Q.isEmpty()){
+ while (!Q.isEmpty()){
+ InstructionHandle u = (InstructionHandle) Q.remove(Q.size()-1);
+ if(closure.add(u)) {
+ InstructionHandle[] successors = getSuccessors(u);
+ for (int i=0; i<successors.length; i++){
+ Q.add(successors[i]);
+ }
+ }
+ }
+ // check if exception handlers are reachable from the closure computed thus far.
+ // conceptually, an exception handler is a successor of each instruction inside
+ // the protected region, but the computation works faster if we don't implement it
+ // in a straight-forward way. Instead, we occasionally check if the first instruction
+ // of the protected region is in the closure, and if so, we know that the exception
+ // handler should also be in the closure.
+ //
+ // "one instruction must be always in at-most one subroutine" JVM requirement
+ // guarantees that the entire protected region always belongs to the same closure,
+ // so just checking the start instruction is suffice.
+ for( int i=0; i<handlers.length; i++ ) {
+ if(closure.contains(handlers[i].getStartPC())) {
+ InstructionHandle handlerPC = handlers[i].getHandlerPC();
+ if(!closure.contains(handlerPC)) {
+ Q.add(handlerPC);
+ }
}
}
}
- // DFS ended above.
- ((SubroutineImpl) (actual==all[0]?getTopLevel():getSubroutine(actual))).setInstructions(closure);
+ // DFS ended above.
+ ((SubroutineImpl) (leader==all[0]?getTopLevel():getSubroutine(leader))).setInstructions(closure);
for (Iterator itr = closure.iterator(); itr.hasNext();) {
InstructionHandle h = (InstructionHandle) itr.next();
@@ -436,29 +442,11 @@
}
}
- if (actual != all[0]){// If we don't deal with the top-level 'subroutine'
- ((SubroutineImpl) getSubroutine(actual)).setLeavingRET();
+ if (leader != all[0]){// If we don't deal with the top-level 'subroutine'
+ ((SubroutineImpl) getSubroutine(leader)).setLeavingRET();
}
}
- // Now make sure no instruction of a Subroutine is protected by exception handling code
- // as is mandated by JustIces notion of subroutines.
- /*for (int i=0; i<handlers.length; i++){
- InstructionHandle _protected = handlers[i].getStartPC();
- while (_protected != handlers[i].getEndPC().getNext()){// Note the inclusive/inclusive notation of "generic API" exception handlers!
- Enumeration subs = subroutines.elements();
- while (subs.hasMoreElements()){
- Subroutine sub = (Subroutine) subs.nextElement();
- if (sub != subroutines.get(all[0])){ // We don't want to forbid top-level exception handlers.
- if (sub.contains(_protected)){
- throw new StructuralCodeConstraintException("Subroutine instruction '"+_protected+"' is protected by an exception handler, '"+handlers[i]+"'. This is forbidden by the JustIce verifier due to its clear definition of subroutines.");
- }
- }
- }
- _protected = _protected.getNext();
- }
- }*/
-
// Now make sure no subroutine is calling a subroutine
// that uses the same local variable for the RET as themselves
// (recursively).
@@ -567,7 +555,7 @@
private static InstructionHandle[] getSuccessors(InstructionHandle instruction){
Instruction inst = instruction.getInstruction();
- if (inst instanceof RET){
+ if (inst instanceof RET){
return empty;
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org