Put Jumps in linked list

git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@83 379699f6-c40d-0410-875b-85095c16579e
stable
jochen 26 years ago
parent e1aca5c144
commit c7aeb9a301
  1. 236
      jode/jode/flow/FlowBlock.java
  2. 6
      jode/jode/flow/Jump.java
  3. 11
      jode/jode/flow/StructuredBlock.java
  4. 83
      jode/jode/flow/TransformExceptionHandlers.java

@ -86,7 +86,8 @@ public class FlowBlock {
/** /**
* This contains a map of all successing flow blocks and there * This contains a map of all successing flow blocks and there
* jumps. The key of this dictionary are the flow blocks, while * jumps. The key of this dictionary are the flow blocks, while
* the elements are Stacks of jumps. * the elements is the first jump to that dictionary. The other
* jumps are accessible via the jump.next field.
*/ */
Dictionary successors = new Hashtable(); Dictionary successors = new Hashtable();
@ -121,28 +122,28 @@ public class FlowBlock {
/** /**
* This method optimizes the jumps to successor. * This method optimizes the jumps to successor.
* @param jumps The jumps that jump to successor. All jumps that * @param jumps The list of jumps with that successor.
* can be optimized are removed from this stack. * @return The remaining jumps, that couldn't be optimized.
*/ */
public void optimizeJumps(Stack jumps, FlowBlock succ) { public Jump optimizeJumps(Jump jumps, FlowBlock succ) {
Stack remainingJumps = new Stack(); Jump remainingJumps = null;
if (lastModified.jump == null) { if (lastModified.jump == null) {
Jump jump = new Jump(succ); Jump lastJump = new Jump(succ);
lastModified.setJump(jump); lastModified.setJump(lastJump);
remainingJumps.push(jump); remainingJumps = lastJump;
} }
next_jump: next_jump:
while (!jumps.isEmpty()) { while (jumps != null) {
Jump jump = (Jump) jumps.pop(); Jump jump = jumps;
jumps = jumps.next;
FlowBlock successor = jump.destination;
/* if the jump is the jump of the lastModified, skip it. /* if the jump is the jump of the lastModified, skip it.
*/ */
if (jump.prev == lastModified) { if (jump.prev == lastModified) {
remainingJumps.push(jump); jump.next = remainingJumps;
remainingJumps = jump;
continue; continue;
} }
@ -188,7 +189,7 @@ public class FlowBlock {
/* Consider this jump again /* Consider this jump again
*/ */
jumps.push(jump); jumps = jump;
continue; continue;
} }
@ -213,11 +214,12 @@ public class FlowBlock {
if (loopBlock.getCondition() == LoopBlock.TRUE && if (loopBlock.getCondition() == LoopBlock.TRUE &&
loopBlock.getType() != LoopBlock.DOWHILE && loopBlock.getType() != LoopBlock.DOWHILE &&
(loopBlock.jumpMayBeChanged() (loopBlock.jumpMayBeChanged()
|| loopBlock.getNextFlowBlock() == successor)) { || loopBlock.getNextFlowBlock() == succ)) {
if (loopBlock.jump == null) { if (loopBlock.jump == null) {
/* consider this jump again */
loopBlock.moveJump(jump); loopBlock.moveJump(jump);
jumps.push(jump); jumps = jump;
} else } else
jump.prev.removeJump(); jump.prev.removeJump();
@ -247,11 +249,12 @@ public class FlowBlock {
if (loopBlock.getCondition() == LoopBlock.TRUE && if (loopBlock.getCondition() == LoopBlock.TRUE &&
loopBlock.getType() == LoopBlock.WHILE && loopBlock.getType() == LoopBlock.WHILE &&
(loopBlock.jumpMayBeChanged() (loopBlock.jumpMayBeChanged()
|| loopBlock.getNextFlowBlock() == successor)) { || loopBlock.getNextFlowBlock() == succ)) {
if (loopBlock.jump == null) { if (loopBlock.jump == null) {
/* consider this jump again */
loopBlock.moveJump(jump); loopBlock.moveJump(jump);
jumps.push(jump); jumps = jump;
} else } else
jump.prev.removeJump(); jump.prev.removeJump();
@ -270,7 +273,7 @@ public class FlowBlock {
*/ */
if (cb.outer instanceof SequentialBlock && if (cb.outer instanceof SequentialBlock &&
cb.outer.getSubBlocks()[0] == cb && cb.outer.getSubBlocks()[0] == cb &&
(cb.outer.getNextFlowBlock() == successor || (cb.outer.getNextFlowBlock() == succ ||
cb.outer.jumpMayBeChanged())) { cb.outer.jumpMayBeChanged())) {
SequentialBlock sequBlock = (SequentialBlock) cb.outer; SequentialBlock sequBlock = (SequentialBlock) cb.outer;
@ -284,7 +287,7 @@ public class FlowBlock {
newIfBlock.setThenBlock(thenBlock); newIfBlock.setThenBlock(thenBlock);
if (thenBlock.contains(lastModified)) { if (thenBlock.contains(lastModified)) {
if (lastModified.jump.destination == successor) { if (lastModified.jump.destination == succ) {
newIfBlock.moveJump(lastModified.jump); newIfBlock.moveJump(lastModified.jump);
lastModified = newIfBlock; lastModified = newIfBlock;
jump.prev.removeJump(); jump.prev.removeJump();
@ -295,7 +298,7 @@ public class FlowBlock {
newIfBlock.moveJump(jump); newIfBlock.moveJump(jump);
/* consider this jump again */ /* consider this jump again */
jumps.push(jump); jumps = jump;
continue; continue;
} }
} else { } else {
@ -329,14 +332,14 @@ public class FlowBlock {
StructuredBlock elseBlock = sequBlock.subBlocks[1]; StructuredBlock elseBlock = sequBlock.subBlocks[1];
if (ifBlock.elseBlock == null if (ifBlock.elseBlock == null
&& (elseBlock.getNextFlowBlock() == successor && (elseBlock.getNextFlowBlock() == succ
|| elseBlock.jumpMayBeChanged())) { || elseBlock.jumpMayBeChanged())) {
ifBlock.replace(sequBlock); ifBlock.replace(sequBlock);
ifBlock.setElseBlock(elseBlock); ifBlock.setElseBlock(elseBlock);
if (elseBlock.contains(lastModified)) { if (elseBlock.contains(lastModified)) {
if (lastModified.jump.destination == successor) { if (lastModified.jump.destination == succ) {
ifBlock.moveJump(lastModified.jump); ifBlock.moveJump(lastModified.jump);
lastModified = ifBlock; lastModified = ifBlock;
jump.prev.removeJump(); jump.prev.removeJump();
@ -347,7 +350,7 @@ public class FlowBlock {
/* consider this jump again */ /* consider this jump again */
ifBlock.moveJump(jump); ifBlock.moveJump(jump);
jumps.push(jump); jumps = jump;
continue; continue;
} }
} }
@ -363,34 +366,34 @@ public class FlowBlock {
for (StructuredBlock surrounder = jump.prev.outer; for (StructuredBlock surrounder = jump.prev.outer;
surrounder != null; surrounder = surrounder.outer) { surrounder != null; surrounder = surrounder.outer) {
if (surrounder instanceof BreakableBlock) { if (surrounder instanceof BreakableBlock) {
if (surrounder.getNextFlowBlock() != successor if (surrounder.getNextFlowBlock() != succ
&& surrounder.jumpMayBeChanged()) { && surrounder.jumpMayBeChanged()) {
surrounder.setJump(new Jump(successor)); surrounder.setJump(new Jump(succ));
jumps.push(surrounder.jump); surrounder.jump.next = jumps;
jumps = surrounder.jump;
break; break;
} }
} }
} }
remainingJumps.push(jump); jump.next = remainingJumps;
remainingJumps = jump;
} }
while(!remainingJumps.isEmpty()) return remainingJumps;
jumps.push(remainingJumps.pop());
} }
/** /**
* Resolve remaining jumps to the successor by generating break * Resolve remaining jumps to the successor by generating break
* instructions. As last resort generate a do while(false) block. * instructions. As last resort generate a do while(false) block.
* @param jumps The jumps that should be resolved. * @param jumps The jump list that need to be resolved.
*/ */
void resolveRemaining(Stack jumps) { void resolveRemaining(Jump jumps) {
LoopBlock doWhileFalse = null; LoopBlock doWhileFalse = null;
StructuredBlock outerMost = lastModified; StructuredBlock outerMost = lastModified;
boolean removeLast = false; boolean removeLast = false;
next_jump: next_jump:
while (!jumps.isEmpty()) { for (; jumps != null; jumps = jumps.next) {
Jump jump = (Jump) jumps.pop(); StructuredBlock prevBlock = jumps.prev;
StructuredBlock prevBlock = jump.prev;
if (prevBlock == lastModified) { if (prevBlock == lastModified) {
/* handled below */ /* handled below */
@ -404,7 +407,7 @@ public class FlowBlock {
surrounder != null; surrounder = surrounder.outer) { surrounder != null; surrounder = surrounder.outer) {
if (surrounder instanceof BreakableBlock) { if (surrounder instanceof BreakableBlock) {
breaklevel++; breaklevel++;
if (surrounder.getNextFlowBlock() == jump.destination) { if (surrounder.getNextFlowBlock() == jumps.destination) {
breakToBlock = (BreakableBlock) surrounder; breakToBlock = (BreakableBlock) surrounder;
break; break;
} }
@ -421,7 +424,6 @@ public class FlowBlock {
if (doWhileFalse == null) { if (doWhileFalse == null) {
doWhileFalse = new LoopBlock(LoopBlock.DOWHILE, doWhileFalse = new LoopBlock(LoopBlock.DOWHILE,
LoopBlock.FALSE); LoopBlock.FALSE);
doWhileFalse.setJump(new Jump(jump.destination));
} }
/* Adapt outermost, so that it contains the break. */ /* Adapt outermost, so that it contains the break. */
while (!outerMost.contains(prevBlock)) while (!outerMost.contains(prevBlock))
@ -439,7 +441,6 @@ public class FlowBlock {
if (doWhileFalse != null) { if (doWhileFalse != null) {
doWhileFalse.replace(outerMost); doWhileFalse.replace(outerMost);
doWhileFalse.setBody(outerMost); doWhileFalse.setBody(outerMost);
doWhileFalse.jump = null;
lastModified = doWhileFalse; lastModified = doWhileFalse;
} }
} }
@ -452,19 +453,20 @@ public class FlowBlock {
/* Merge the sucessors from the successing flow block /* Merge the sucessors from the successing flow block
*/ */
Enumeration keys = succ.successors.keys(); Enumeration keys = succ.successors.keys();
Enumeration stacks = succ.successors.elements(); Enumeration succs = succ.successors.elements();
while (keys.hasMoreElements()) { while (keys.hasMoreElements()) {
FlowBlock dest = (FlowBlock) keys.nextElement(); FlowBlock dest = (FlowBlock) keys.nextElement();
Stack hisJumps = (Stack) stacks.nextElement(); Jump hisJumps = (Jump) succs.nextElement();
Stack myJumps = (Stack) successors.get(dest); Jump myJumps = (Jump) successors.get(dest);
dest.predecessors.removeElement(succ); dest.predecessors.removeElement(succ);
if (myJumps == null) { if (myJumps == null) {
dest.predecessors.addElement(this); dest.predecessors.addElement(this);
successors.put(dest, hisJumps); successors.put(dest, hisJumps);
} else { } else {
while (!hisJumps.isEmpty()) while (myJumps.next != null)
myJumps.push(hisJumps.pop()); myJumps = myJumps.next;
myJumps.next = hisJumps;
} }
} }
} }
@ -474,25 +476,22 @@ public class FlowBlock {
* successing flow block simultanous to a T1 transformation. * successing flow block simultanous to a T1 transformation.
* @param successor The flow block which is unified with this flow * @param successor The flow block which is unified with this flow
* block. * block.
* @param jumps The list of jumps to successor in this block.
* @return The variables that must be defined in this block. * @return The variables that must be defined in this block.
*/ */
void updateInOut (FlowBlock successor, boolean t1Transformation, void updateInOut (FlowBlock successor, Jump jumps) {
Stack jumps) {
/* First get the out vectors of all jumps to successor and /* First get the out vectors of all jumps to successor and
* calculate the intersection. * calculate the intersection.
*/ */
VariableSet gens = new VariableSet(); VariableSet gens = new VariableSet();
VariableSet kills = null; VariableSet kills = null;
Enumeration enum = jumps.elements(); for (;jumps != null; jumps = jumps.next) {
while (enum.hasMoreElements()) { gens.unionExact(jumps.gen);
Jump jump = (Jump) enum.nextElement();
gens.unionExact(jump.gen);
if (kills == null) if (kills == null)
kills = jump.kill; kills = jumps.kill;
else else
kills = kills.intersect(jump.kill); kills = kills.intersect(jumps.kill);
} }
/* Merge the locals used in successing block with those written /* Merge the locals used in successing block with those written
@ -502,22 +501,19 @@ public class FlowBlock {
/* Now update in and out set of successing block */ /* Now update in and out set of successing block */
if (t1Transformation) if (successor != this)
successor.in.subtract(kills); successor.in.subtract(kills);
/* The gen/kill sets must be updated for every jump /* The gen/kill sets must be updated for every jump
* in the other block */ * in the other block */
Enumeration stacks = successor.successors.elements(); Enumeration succSuccs = successor.successors.elements();
while (stacks.hasMoreElements()) { while (succSuccs.hasMoreElements()) {
enum = ((Stack) stacks.nextElement()).elements(); Jump succJumps = (Jump) succSuccs.nextElement();
while (enum.hasMoreElements()) { for (; succJumps != null; succJumps = succJumps.next) {
Jump jump = (Jump) enum.nextElement(); succJumps.gen.mergeGenKill(gens, succJumps.kill);
if (jump != null) { if (successor != this)
jump.gen.mergeGenKill(gens, jump.kill); succJumps.kill.add(kills);
if (t1Transformation)
jump.kill.add(kills);
}
} }
} }
this.in.unionExact(successor.in); this.in.unionExact(successor.in);
@ -567,28 +563,27 @@ public class FlowBlock {
throw new AssertError("Inconsistency"); throw new AssertError("Inconsistency");
Enumeration keys = successors.keys(); Enumeration keys = successors.keys();
Enumeration stacks = successors.elements(); Enumeration succs = successors.elements();
while (keys.hasMoreElements()) { while (keys.hasMoreElements()) {
FlowBlock dest = (FlowBlock) keys.nextElement(); FlowBlock dest = (FlowBlock) keys.nextElement();
if (!dest.predecessors.contains(this)) if (!dest.predecessors.contains(this))
throw new AssertError("Inconsistency"); throw new AssertError("Inconsistency");
Enumeration enum = ((Stack)stacks.nextElement()).elements(); Jump jumps = (Jump)succs.nextElement();
if (!enum.hasMoreElements()) if (jumps == null)
throw new AssertError("Inconsistency"); throw new AssertError("Inconsistency");
while (enum.hasMoreElements()) { for (; jumps != null; jumps = jumps.next) {
Jump jump = (Jump) enum.nextElement();
if (jump.destination != dest) if (jumps.destination != dest)
throw new AssertError("Inconsistency"); throw new AssertError("Inconsistency");
if (jump.prev.flowBlock != this || if (jumps.prev.flowBlock != this ||
jump.prev.jump != jump) jumps.prev.jump != jumps)
throw new AssertError("Inconsistency"); throw new AssertError("Inconsistency");
prev_loop: prev_loop:
for (StructuredBlock prev = jump.prev; prev != block; for (StructuredBlock prev = jumps.prev; prev != block;
prev = prev.outer) { prev = prev.outer) {
if (prev.outer == null) if (prev.outer == null)
throw new RuntimeException("Inconsistency"); throw new RuntimeException("Inconsistency");
@ -620,14 +615,14 @@ public class FlowBlock {
checkConsistent(); checkConsistent();
succ.checkConsistent(); succ.checkConsistent();
Stack jumps = (Stack) successors.remove(succ); Jump jumps = (Jump) successors.remove(succ);
/* Update the in/out-Vectors now */ /* Update the in/out-Vectors now */
updateInOut(succ, true, jumps); updateInOut(succ, jumps);
/* Try to eliminate as many jumps as possible. /* Try to eliminate as many jumps as possible.
*/ */
optimizeJumps(jumps, succ); jumps = optimizeJumps(jumps, succ);
resolveRemaining(jumps); resolveRemaining(jumps);
/* Now unify the blocks. /* Now unify the blocks.
@ -668,10 +663,10 @@ public class FlowBlock {
checkConsistent(); checkConsistent();
Stack jumps = (Stack) successors.remove(this); Jump jumps = (Jump) successors.remove(this);
/* Update the in/out-Vectors now */ /* Update the in/out-Vectors now */
updateInOut(this, false, jumps); updateInOut(this, jumps);
StructuredBlock bodyBlock = block; StructuredBlock bodyBlock = block;
@ -685,8 +680,8 @@ public class FlowBlock {
boolean createdForBlock = false; boolean createdForBlock = false;
if (jumps.size() == 1 if (jumps.next == null
&& ((Jump)jumps.peek()).prev == lastModified && jumps.prev == lastModified
&& lastModified instanceof InstructionBlock) { && lastModified instanceof InstructionBlock) {
Expression instr = Expression instr =
@ -749,7 +744,7 @@ public class FlowBlock {
/* Try to eliminate as many jumps as possible. /* Try to eliminate as many jumps as possible.
*/ */
optimizeJumps(jumps, this); jumps = optimizeJumps(jumps, this);
LoopBlock whileBlock = LoopBlock whileBlock =
new LoopBlock(LoopBlock.WHILE, LoopBlock.TRUE); new LoopBlock(LoopBlock.WHILE, LoopBlock.TRUE);
@ -760,16 +755,17 @@ public class FlowBlock {
/* if there are further jumps to this, replace every jump with a /* if there are further jumps to this, replace every jump with a
* continue to while block and return true. * continue to while block and return true.
*/ */
while (!jumps.isEmpty()) { for (; jumps != null; jumps = jumps.next) {
Jump jump = (Jump) jumps.pop();
if (jump.prev == lastModified) if (jumps.prev == lastModified)
/* handled later */ /* handled later */
continue; continue;
StructuredBlock prevBlock = jumps.prev;
int breaklevel = 0, continuelevel = 0; int breaklevel = 0, continuelevel = 0;
BreakableBlock breakToBlock = null; BreakableBlock breakToBlock = null;
for (StructuredBlock surrounder = jump.prev.outer; for (StructuredBlock surrounder = prevBlock.outer;
surrounder != whileBlock; surrounder != whileBlock;
surrounder = surrounder.outer) { surrounder = surrounder.outer) {
if (surrounder instanceof BreakableBlock) { if (surrounder instanceof BreakableBlock) {
@ -782,7 +778,6 @@ public class FlowBlock {
} }
} }
} }
StructuredBlock prevBlock = jump.prev;
prevBlock.removeJump(); prevBlock.removeJump();
if (breakToBlock == null) if (breakToBlock == null)
prevBlock.appendBlock prevBlock.appendBlock
@ -816,34 +811,34 @@ public class FlowBlock {
public void mergeEndBlock() { public void mergeEndBlock() {
checkConsistent(); checkConsistent();
Stack allJumps = (Stack) successors.remove(END_OF_METHOD); Jump allJumps = (Jump) successors.remove(END_OF_METHOD);
if (allJumps == null) if (allJumps == null)
return; return;
/* First remove all implicit jumps to the END_OF_METHOD block. /* First remove all implicit jumps to the END_OF_METHOD block.
*/ */
Stack jumps = new Stack(); Jump jumps = null;
Enumeration enum = allJumps.elements(); for (; allJumps != null; ) {
while (enum.hasMoreElements()) { Jump jump = allJumps;
Jump jump = (Jump) enum.nextElement(); allJumps = allJumps.next;
if (jump.prev instanceof ReturnBlock) { if (jump.prev instanceof ReturnBlock) {
/* This jump is implicit */ /* This jump is implicit */
jump.prev.removeJump(); jump.prev.removeJump();
continue; continue;
} }
jumps.push(jump); jump.next = jumps;
jumps = jump;
} }
/* Try to eliminate as many jumps as possible. /* Try to eliminate as many jumps as possible.
*/ */
optimizeJumps(jumps, END_OF_METHOD); jumps = optimizeJumps(jumps, END_OF_METHOD);
next_jump: next_jump:
while (!jumps.isEmpty()) { for (; jumps != null; jumps = jumps.next) {
Jump jump = (Jump) jumps.pop();
StructuredBlock prevBlock = jump.prev; StructuredBlock prevBlock = jumps.prev;
if (lastModified == prevBlock) if (lastModified == prevBlock)
/* handled later */ /* handled later */
@ -1097,30 +1092,30 @@ public class FlowBlock {
|| (nextFlow.predecessors.size() > 1 || (nextFlow.predecessors.size() > 1
&& (lastFlow == null && (lastFlow == null
|| !nextFlow.predecessors.contains(lastFlow))) || !nextFlow.predecessors.contains(lastFlow)))
|| ((Stack)successors.get(nextFlow)).size() > 1) || ((Jump)successors.get(nextFlow)).next != null)
break; break;
checkConsistent(); checkConsistent();
Stack jumps = (Stack) successors.remove(nextFlow); Jump jumps = (Jump) successors.remove(nextFlow);
/* note that jumps.size() == 1 */ /* note that this is the single caseBlock jump */
if (nextFlow.predecessors.size() == 2) { if (nextFlow.predecessors.size() == 2) {
Stack lastJumps = Jump lastJumps =
(Stack) lastFlow.successors.remove(nextFlow); (Jump) lastFlow.successors.remove(nextFlow);
/* Do the in/out analysis with all jumps /* Do the in/out analysis with all jumps
* Note that this won't update lastFlow.in, but * Note that this won't update lastFlow.in, but
* this will not be used anymore. * this will not be used anymore.
*/ */
lastJumps.push(jumps.peek()); jumps.next = lastJumps;
updateInOut(nextFlow, true, lastJumps); updateInOut(nextFlow, jumps);
lastJumps.pop();
lastFlow.optimizeJumps(lastJumps, nextFlow); lastJumps =
lastFlow.optimizeJumps(lastJumps, nextFlow);
lastFlow.resolveRemaining(lastJumps); lastFlow.resolveRemaining(lastJumps);
} else } else
updateInOut(nextFlow, true, jumps); updateInOut(nextFlow, jumps);
if (lastFlow != null) { if (lastFlow != null) {
lastFlow.block.replace lastFlow.block.replace
@ -1180,21 +1175,30 @@ public class FlowBlock {
} }
public void removeSuccessor(Jump jump) { public void removeSuccessor(Jump jump) {
Stack destJumps = (Stack) successors.get(jump.destination); Jump destJumps = (Jump) successors.get(jump.destination);
if (!destJumps.removeElement(jump)) Jump prev = null;
while (destJumps != jump && destJumps != null) {
prev = destJumps;
destJumps = destJumps.next;
}
if (destJumps == null)
throw new AssertError("removing non existent jump"); throw new AssertError("removing non existent jump");
if (destJumps.isEmpty()) if (prev != null)
successors.remove(jump.destination); prev.next = destJumps.next;
else {
if (destJumps.next == null)
successors.remove(jump.destination);
else
successors.put(jump.destination, destJumps.next);
}
} }
public void addSuccessor(Jump jump) { public void addSuccessor(Jump jump) {
Stack destJumps = (Stack) successors.get(jump.destination); jump.next = (Jump) successors.get(jump.destination);
if (destJumps == null) { if (jump.next == null)
jump.destination.predecessors.addElement(this); jump.destination.predecessors.addElement(this);
destJumps = new Stack();
successors.put(jump.destination, destJumps); successors.put(jump.destination, jump);
}
destJumps.push(jump);
} }
public void makeDeclaration(VariableSet param) { public void makeDeclaration(VariableSet param) {

@ -35,6 +35,12 @@ public class Jump {
*/ */
int destAddr; int destAddr;
/**
* The jumps in a flow block, that have the same destination, are
* in a link list. This field points to the next jump in this link.
*/
Jump next;
/** /**
* The kill locals. This are the slots, which must be overwritten * The kill locals. This are the slots, which must be overwritten
* in this block on every path to this jump. That means, that all * in this block on every path to this jump. That means, that all

@ -371,10 +371,13 @@ public abstract class StructuredBlock {
} }
subs[i].checkConsistent(); subs[i].checkConsistent();
} }
if (jump != null if (jump != null) {
&& !((java.util.Stack) Jump jumps = (Jump) flowBlock.successors.get(jump.destination);
flowBlock.successors.get(jump.destination)).contains(jump)) for (; jumps != jump; jumps = jumps.next) {
throw new AssertError("Inconsistency"); if (jumps == null)
throw new AssertError("Inconsistency");
}
}
} }
/** /**

@ -28,7 +28,6 @@ import jode.LocalLoadOperator;
import jode.Expression; import jode.Expression;
import jode.PopOperator; import jode.PopOperator;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.Stack;
/** /**
* *
@ -135,15 +134,11 @@ public class TransformExceptionHandlers {
/* The gen/kill sets must be updated for every jump /* The gen/kill sets must be updated for every jump
* in the catch block */ * in the catch block */
Enumeration stacks = catchFlow.successors.elements(); Enumeration succs = catchFlow.successors.elements();
while (stacks.hasMoreElements()) { while (succs.hasMoreElements()) {
Enumeration enum = ((Stack) stacks.nextElement()).elements(); for (Jump succJumps = (Jump) succs.nextElement();
while (enum.hasMoreElements()) { succJumps != null; succJumps = succJumps.next) {
succJumps.gen.mergeGenKill(gens, succJumps.kill);
Jump jump = (Jump) enum.nextElement();
if (jump != null) {
jump.gen.mergeGenKill(gens, jump.kill);
}
} }
} }
tryFlow.in.unionExact(catchFlow.in); tryFlow.in.unionExact(catchFlow.in);
@ -243,14 +238,10 @@ public class TransformExceptionHandlers {
* @param subRoutine the FlowBlock of the sub routine. * @param subRoutine the FlowBlock of the sub routine.
*/ */
private void removeJSR(FlowBlock tryFlow, FlowBlock subRoutine) { private void removeJSR(FlowBlock tryFlow, FlowBlock subRoutine) {
Stack jumps = (Stack)tryFlow.successors.remove(subRoutine); for (Jump jumps = (Jump)tryFlow.successors.remove(subRoutine);
if (jumps == null) jumps != null; jumps = jumps.next) {
return;
Enumeration enum = jumps.elements(); StructuredBlock prev = jumps.prev;
while (enum.hasMoreElements()) {
Jump jump = (Jump)enum.nextElement();
StructuredBlock prev = jump.prev;
prev.removeJump(); prev.removeJump();
if (prev instanceof EmptyBlock if (prev instanceof EmptyBlock
&& prev.outer instanceof JsrBlock) { && prev.outer instanceof JsrBlock) {
@ -310,17 +301,15 @@ public class TransformExceptionHandlers {
public void checkAndRemoveJSR(FlowBlock tryFlow, FlowBlock subRoutine) { public void checkAndRemoveJSR(FlowBlock tryFlow, FlowBlock subRoutine) {
Enumeration keys = tryFlow.successors.keys(); Enumeration keys = tryFlow.successors.keys();
Enumeration stacks = tryFlow.successors.elements(); Enumeration succs = tryFlow.successors.elements();
while (keys.hasMoreElements()) { while (keys.hasMoreElements()) {
Stack jumps = (Stack) stacks.nextElement(); Jump jumps = (Jump) succs.nextElement();
if (keys.nextElement() == subRoutine) if (keys.nextElement() == subRoutine)
continue; continue;
Enumeration enum = jumps.elements(); for ( ; jumps != null; jumps = jumps.next) {
while (enum.hasMoreElements()) {
Jump jump = (Jump)enum.nextElement();
StructuredBlock prev = jump.prev; StructuredBlock prev = jumps.prev;
if (prev instanceof ThrowBlock) { if (prev instanceof ThrowBlock) {
/* The jump is a throw. We have a catch-all block /* The jump is a throw. We have a catch-all block
* that will do the finally. * that will do the finally.
@ -384,19 +373,18 @@ public class TransformExceptionHandlers {
public void checkAndRemoveMonitorExit(FlowBlock tryFlow, LocalInfo local, public void checkAndRemoveMonitorExit(FlowBlock tryFlow, LocalInfo local,
int startMonExit, int endMonExit) { int startMonExit, int endMonExit) {
FlowBlock subRoutine = null; FlowBlock subRoutine = null;
Enumeration stacks = tryFlow.successors.elements(); Enumeration succs = tryFlow.successors.elements();
dest_loop: dest_loop:
while (stacks.hasMoreElements()) { while (succs.hasMoreElements()) {
Enumeration enum = ((Stack) stacks.nextElement()).elements(); for (Jump jumps = (Jump) succs.nextElement();
while (enum.hasMoreElements()) { jumps != null; jumps = jumps.next) {
Jump jump = (Jump)enum.nextElement();
StructuredBlock prev = jump.prev; StructuredBlock prev = jumps.prev;
if (prev instanceof EmptyBlock if (prev instanceof EmptyBlock
&& prev.outer instanceof JsrBlock && prev.outer instanceof JsrBlock
&& subRoutine == null) { && subRoutine == null) {
subRoutine = jump.destination; subRoutine = jumps.destination;
subRoutine.analyze(startMonExit, endMonExit); subRoutine.analyze(startMonExit, endMonExit);
transformSubRoutine(subRoutine); transformSubRoutine(subRoutine);
@ -621,10 +609,8 @@ public class TransformExceptionHandlers {
subRoutine.analyze(catchFlow.addr+catchFlow.length, end); subRoutine.analyze(catchFlow.addr+catchFlow.length, end);
if (!transformSubRoutine(subRoutine)) if (!transformSubRoutine(subRoutine))
return false; return false;
Stack jumps = (Stack)tryFlow.successors.get(subRoutine);
if (jumps != null) updateInOutCatch(tryFlow, subRoutine);
/* jumps may be null, if tryFlow ends with a throw */
tryFlow.updateInOut(subRoutine, true, jumps);
tryFlow.length += catchFlow.length; tryFlow.length += catchFlow.length;
checkAndRemoveJSR(tryFlow, subRoutine); checkAndRemoveJSR(tryFlow, subRoutine);
@ -678,11 +664,9 @@ public class TransformExceptionHandlers {
/* There is another exit in the try block, bad */ /* There is another exit in the try block, bad */
return false; return false;
} }
Enumeration enum = for (Jump throwJumps = (Jump) tryFlow.successors.get(key);
((Stack)tryFlow.successors.get(key)).elements(); throwJumps != null; throwJumps = throwJumps.next) {
while (enum.hasMoreElements()) { if (!(throwJumps.prev instanceof ThrowBlock)) {
Jump throwJump= (Jump)enum.nextElement();
if (!(throwJump.prev instanceof ThrowBlock)) {
/* There is a return exit in the try block */ /* There is a return exit in the try block */
return false; return false;
} }
@ -691,19 +675,18 @@ public class TransformExceptionHandlers {
/* remove the pop now */ /* remove the pop now */
firstInstr.removeBlock(); firstInstr.removeBlock();
tryFlow.length += catchFlow.length;
updateInOutCatch(tryFlow, succ);
if (succ != null) { if (succ != null) {
Stack jumps = (Stack) tryFlow.successors.remove(succ); Jump jumps = (Jump) tryFlow.successors.remove(succ);
succ.predecessors.removeElement(tryFlow); succ.predecessors.removeElement(tryFlow);
/* Handle the jumps in the tryFlow. /* Handle the jumps in the tryFlow.
*/ */
tryFlow.updateInOut(succ, true, jumps); jumps = tryFlow.optimizeJumps(jumps, succ);
tryFlow.optimizeJumps(jumps, succ);
tryFlow.resolveRemaining(jumps); tryFlow.resolveRemaining(jumps);
} }
tryFlow.length += catchFlow.length;
TryBlock tryBlock = (TryBlock)tryFlow.block; TryBlock tryBlock = (TryBlock)tryFlow.block;
if (tryBlock.getSubBlocks()[0] instanceof TryBlock) { if (tryBlock.getSubBlocks()[0] instanceof TryBlock) {
/* remove the unnecessary tryBlock */ /* remove the unnecessary tryBlock */
@ -792,13 +775,13 @@ public class TransformExceptionHandlers {
throw new AssertError("Handler has a predecessors"); throw new AssertError("Handler has a predecessors");
updateInOutCatch(tryFlow, catchFlow); updateInOutCatch(tryFlow, catchFlow);
if (types[i] != null) { if (types[i] != null)
analyzeCatchBlock(types[i], tryFlow, catchFlow); analyzeCatchBlock(types[i], tryFlow, catchFlow);
} else if (!analyzeSynchronized(tryFlow, catchFlow, endHandler) else if (!analyzeSynchronized(tryFlow, catchFlow, endHandler)
&& ! analyzeFinally(tryFlow, catchFlow, endHandler) && ! analyzeFinally(tryFlow, catchFlow, endHandler)
&& ! analyzeSpecialFinally(tryFlow, catchFlow, && ! analyzeSpecialFinally(tryFlow, catchFlow,
endHandler)) endHandler))
analyzeCatchBlock(jode.Type.tObject, tryFlow, catchFlow); analyzeCatchBlock(jode.Type.tObject, tryFlow, catchFlow);

Loading…
Cancel
Save