fixed a bug in SynchronizedBlock.

better handling of subroutine and exitblock


git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@1108 379699f6-c40d-0410-875b-85095c16579e
branch_1_1
jochen 25 years ago
parent 8e6f442ee5
commit ad5a9f0194
  1. 94
      jode/jode/flow/TransformExceptionHandlers.java.in

@ -246,7 +246,6 @@ public class TransformExceptionHandlers {
public void checkAndRemoveJSR(FlowBlock tryFlow, FlowBlock subRoutine, public void checkAndRemoveJSR(FlowBlock tryFlow, FlowBlock subRoutine,
int startOutExit, int endOutExit) { int startOutExit, int endOutExit) {
boolean foundSub = false; boolean foundSub = false;
FlowBlock exitBlock = null;
Iterator iter = tryFlow.getSuccessors().iterator(); Iterator iter = tryFlow.getSuccessors().iterator();
dest_loop: dest_loop:
while (iter.hasNext()) { while (iter.hasNext()) {
@ -306,8 +305,7 @@ public class TransformExceptionHandlers {
* directly to a correct jsr instruction, which * directly to a correct jsr instruction, which
* lies outside the try/catch block. * lies outside the try/catch block.
*/ */
if (exitBlock == null if (jumps.destination.predecessors.size() == 1
&& jumps.destination.predecessors.size() == 1
&& jumps.destination.getAddr() >= startOutExit && jumps.destination.getAddr() >= startOutExit
&& jumps.destination.getNextAddr() <= endOutExit) { && jumps.destination.getNextAddr() <= endOutExit) {
jumps.destination.analyze(startOutExit, endOutExit); jumps.destination.analyze(startOutExit, endOutExit);
@ -320,7 +318,6 @@ public class TransformExceptionHandlers {
&& (sb.getSubBlocks()[0].jump.destination && (sb.getSubBlocks()[0].jump.destination
== subRoutine)) { == subRoutine)) {
StructuredBlock jsrInner = sb.getSubBlocks()[0]; StructuredBlock jsrInner = sb.getSubBlocks()[0];
exitBlock = jumps.destination;
jumps.destination.removeSuccessor(jsrInner.jump); jumps.destination.removeSuccessor(jsrInner.jump);
jsrInner.removeJump(); jsrInner.removeJump();
sb.removeBlock(); sb.removeBlock();
@ -355,16 +352,30 @@ public class TransformExceptionHandlers {
return false; return false;
} }
boolean isMonitorExitSubRoutine(FlowBlock subRoutine, LocalInfo local) {
if (transformSubRoutine(subRoutine.block)) {
if (subRoutine.block instanceof InstructionBlock) {
Expression instr =
((InstructionBlock)subRoutine.block)
.getInstruction();
if (isMonitorExit(instr, local)) {
return true;
}
}
}
return false;
}
public void checkAndRemoveMonitorExit(FlowBlock tryFlow, LocalInfo local, public void checkAndRemoveMonitorExit(FlowBlock tryFlow, LocalInfo local,
int startOutExit, int endOutExit, int startOutExit, int endOutExit,
int startMonExit, int endMonExit) { int startMonExit, int endMonExit) {
FlowBlock subRoutine = null; FlowBlock subRoutine = null;
FlowBlock exitBlock = null;
Iterator succs = tryFlow.getSuccessors().iterator(); Iterator succs = tryFlow.getSuccessors().iterator();
dest_loop: dest_loop:
while (succs.hasNext()) { while (succs.hasNext()) {
boolean isFirstJump = true; boolean isFirstJump = true;
for (Jump jumps = tryFlow.getJumps((FlowBlock) succs.next()); FlowBlock successor = (FlowBlock) succs.next();
for (Jump jumps = tryFlow.getJumps(successor);
jumps != null; jumps = jumps.next, isFirstJump = false) { jumps != null; jumps = jumps.next, isFirstJump = false) {
StructuredBlock prev = jumps.prev; StructuredBlock prev = jumps.prev;
@ -435,44 +446,56 @@ public class TransformExceptionHandlers {
* another jsr. This must be the monitorexit * another jsr. This must be the monitorexit
* subroutine. * subroutine.
*/ */
if (prev instanceof JsrBlock && subRoutine == null) { if (prev instanceof JsrBlock) {
if (subRoutine == null
subRoutine = jumps.destination; && successor.getAddr() >= startMonExit
subRoutine.analyze(startMonExit, endMonExit); && successor.getNextAddr() <= endMonExit) {
transformSubRoutine(subRoutine.block); successor.analyze(startMonExit, endMonExit);
if (subRoutine.block instanceof InstructionBlock) { if (isMonitorExitSubRoutine(successor, local))
Expression instr = subRoutine = successor;
((InstructionBlock)subRoutine.block)
.getInstruction();
if (isMonitorExit(instr, local)) {
tryFlow.mergeAddr(subRoutine);
continue dest_loop;
}
} }
if (subRoutine == successor)
continue dest_loop;
} }
/* Now we have a jump that is not preceded by a /* Now we have a jump that is not preceded by a
* monitorexit. There's a last chance: the jump * monitorexit. There's a last chance: the jump
* jumps directly to the correct monitorexit * jumps directly to the correct monitorexit
* instruction, which lies outside the try/catch * instruction, which lies outside the try/catch
* block. * block.
*/ */
if (exitBlock == null if (successor.predecessors.size() == 1
&& jumps.destination.predecessors.size() != 1 && successor.getAddr() >= startOutExit
&& jumps.destination.getAddr() >= startOutExit && successor.getNextAddr() <= endOutExit) {
&& jumps.destination.getNextAddr() <= endOutExit) { successor.analyze(startOutExit, endOutExit);
jumps.destination.analyze(startOutExit, endOutExit);
StructuredBlock sb = jumps.destination.block; StructuredBlock sb = successor.block;
if (sb instanceof SequentialBlock) if (sb instanceof SequentialBlock)
sb = sb.getSubBlocks()[0]; sb = sb.getSubBlocks()[0];
if (sb instanceof JsrBlock
&& sb.getSubBlocks()[0] instanceof EmptyBlock) {
StructuredBlock jsrInner = sb.getSubBlocks()[0];
FlowBlock dest = jsrInner.jump.destination;
if (subRoutine == null
&& dest.getAddr() >= startMonExit
&& dest.getNextAddr() <= endMonExit) {
dest.analyze(startMonExit, endMonExit);
if (isMonitorExitSubRoutine(dest, local))
subRoutine = dest;
}
if (subRoutine == dest) {
sb.removeBlock();
continue dest_loop;
}
}
if (sb instanceof InstructionBlock) { if (sb instanceof InstructionBlock) {
Expression instr = ((InstructionBlock)sb) Expression instr = ((InstructionBlock)sb)
.getInstruction(); .getInstruction();
if (isMonitorExit(instr, local)) { if (isMonitorExit(instr, local)) {
sb.removeBlock(); sb.removeBlock();
exitBlock = jumps.destination;
continue dest_loop; continue dest_loop;
} }
} }
@ -488,8 +511,10 @@ public class TransformExceptionHandlers {
} }
} }
if (subRoutine != null) if (subRoutine != null) {
removeJSR(tryFlow, subRoutine); removeJSR(tryFlow, subRoutine);
tryFlow.mergeAddr(subRoutine);
}
} }
private boolean analyzeSynchronized(FlowBlock tryFlow, private boolean analyzeSynchronized(FlowBlock tryFlow,
@ -545,6 +570,13 @@ public class TransformExceptionHandlers {
((LocalLoadOperator)monexit.getSubExpressions()[0]) ((LocalLoadOperator)monexit.getSubExpressions()[0])
.getLocalInfo(); .getLocalInfo();
if ((GlobalOptions.debuggingFlags
& GlobalOptions.DEBUG_ANALYZE) != 0)
GlobalOptions.err.println
("analyzeSynchronized(" + tryFlow.getAddr()
+ "," + tryFlow.getNextAddr() + "," + catchFlow.getAddr()
+ "," + catchFlow.getNextAddr() + "," + endHandler + ")");
checkAndRemoveMonitorExit checkAndRemoveMonitorExit
(tryFlow, local, (tryFlow, local,
tryFlow.getNextAddr(), catchFlow.getAddr(), tryFlow.getNextAddr(), catchFlow.getAddr(),
@ -942,7 +974,7 @@ public class TransformExceptionHandlers {
if ((GlobalOptions.debuggingFlags if ((GlobalOptions.debuggingFlags
& GlobalOptions.DEBUG_ANALYZE) != 0) & GlobalOptions.DEBUG_ANALYZE) != 0)
GlobalOptions.err.println GlobalOptions.err.println
("analyzeCatch(" + tryFlow.getAddr() + ", " ("analyzeTryCatch(" + tryFlow.getAddr() + ", "
+ tryFlow.getNextAddr() + ") done."); + tryFlow.getNextAddr() + ") done.");
} }
} }

Loading…
Cancel
Save