Author: kohsuke Date: Wed Dec 28 11:54:05 2005 New Revision: 359611 URL: http://svn.apache.org/viewcvs?rev=359611&view=rev Log: simplified the traversal code.
still trying to fix the JSR/RET issue, but I think I'm getting to the core. 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=359611&r1=359610&r2=359611&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 11:54:05 2005 @@ -15,12 +15,6 @@ */ package org.apache.commons.javaflow.bytecode.transformation.bcel.analyser; -import java.awt.Color; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Hashtable; -import java.util.Iterator; - import org.apache.bcel.generic.ASTORE; import org.apache.bcel.generic.ATHROW; import org.apache.bcel.generic.BranchInstruction; @@ -38,6 +32,12 @@ import org.apache.bcel.verifier.exc.AssertionViolatedException; import org.apache.bcel.verifier.exc.StructuralCodeConstraintException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Set; + /** * Instances of this class contain information about the subroutines * found in a code array of a method. @@ -85,7 +85,7 @@ private int localVariable = UNSET; /** The instructions that belong to this subroutine. */ - private HashSet instructions = new HashSet(); // Elements: InstructionHandle + private Set instructions; /* * Refer to the Subroutine interface for documentation. @@ -212,18 +212,6 @@ return (InstructionHandle[]) instructions.toArray(ret); } - /* - * Adds an instruction to this subroutine. - * All instructions must have been added before invoking setLeavingRET(). - * @see #setLeavingRET - */ - void addInstruction(InstructionHandle ih){ - if (theRET != null){ - throw new AssertionViolatedException("All instructions must have been added before invoking setLeavingRET()."); - } - instructions.add(ih); - } - /* Satisfies Subroutine.getRecursivelyAccessedLocalsIndices(). */ public int[] getRecursivelyAccessedLocalsIndices(){ HashSet s = new HashSet(); @@ -338,7 +326,10 @@ public SubroutineImpl(){ } - }// end Inner Class SubrouteImpl + void setInstructions(Set _instructions) { + this.instructions = _instructions; + } + }// end Inner Class SubrouteImpl /** * The Hashtable containing the subroutines found. @@ -406,56 +397,46 @@ // Now do a BFS from every subroutine leader to find all the // instructions that belong to a subroutine. HashSet instructions_assigned = new HashSet(); // we don't want to assign an instruction to two or more Subroutine objects. - - Hashtable colors = new Hashtable(); //Graph colouring. Key: InstructionHandle, Value: java.awt.Color . - - iter = sub_leaders.iterator(); + + iter = sub_leaders.iterator(); while (iter.hasNext()){ - // Do some BFS with "actual" as the root of the graph. - InstructionHandle actual = (InstructionHandle) (iter.next()); - // Init colors - for (int i=0; i<all.length; i++){ - colors.put(all[i], Color.white); - } - colors.put(actual, Color.gray); + // 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 ArrayList Q = new ArrayList(); Q.add(actual); // add(Obj) adds to the end, remove(0) removes from the start. - - /* BFS 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.]*/ + + /* BFS 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++){ - colors.put(handlers[j].getHandlerPC(), Color.gray); Q.add(handlers[j].getHandlerPC()); } } /* CONTINUE NORMAL BFS ALGORITHM */ - // Loop until Queue is empty - while (Q.size() != 0){ + while (!Q.isEmpty()){ InstructionHandle u = (InstructionHandle) Q.remove(0); - InstructionHandle[] successors = getSuccessors(u); - for (int i=0; i<successors.length; i++){ - if (((Color) colors.get(successors[i])) == Color.white){ - colors.put(successors[i], Color.gray); - Q.add(successors[i]); - } - } - colors.put(u, Color.black); - } + if(closure.add(u)) { + InstructionHandle[] successors = getSuccessors(u); + for (int i=0; i<successors.length; i++){ + Q.add(successors[i]); + } + } + } // BFS ended above. - for (int i=0; i<all.length; i++){ - if (colors.get(all[i]) == Color.black){ - ((SubroutineImpl) (actual==all[0]?getTopLevel():getSubroutine(actual))).addInstruction(all[i]); - if (instructions_assigned.contains(all[i])){ - //throw new StructuralCodeConstraintException("Instruction '"+all[i]+"' is part of more than one subroutine (or of the top level and a subroutine)."); - } - else{ - instructions_assigned.add(all[i]); - } - } - } - if (actual != all[0]){// If we don't deal with the top-level 'subroutine' + ((SubroutineImpl) (actual==all[0]?getTopLevel():getSubroutine(actual))).setInstructions(closure); + + for (Iterator itr = closure.iterator(); itr.hasNext();) { + InstructionHandle h = (InstructionHandle) itr.next(); + if(!instructions_assigned.add(h)) { + throw new StructuralCodeConstraintException("Instruction '"+h+"' is part of more than one subroutine (or of the top level and a subroutine)."); + } + } + + if (actual != all[0]){// If we don't deal with the top-level 'subroutine' ((SubroutineImpl) getSubroutine(actual)).setLeavingRET(); } } --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]