finally and synchronized improvements, clean up and speed up

git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@70 379699f6-c40d-0410-875b-85095c16579e
stable
jochen 26 years ago
parent b596c66503
commit a891c3b82c
  1. 3
      jode/jode/flow/CatchBlock.java
  2. 30
      jode/jode/flow/CatchFinallyBlock.java
  3. 1
      jode/jode/flow/CombineIfGotoExpressions.java
  4. 26
      jode/jode/flow/CompleteSynchronized.java
  5. 2
      jode/jode/flow/CreateExpression.java
  6. 25
      jode/jode/flow/CreateForInitializer.java
  7. 54
      jode/jode/flow/CreateIfThenElseOperator.java
  8. 1584
      jode/jode/flow/FlowBlock.java
  9. 8
      jode/jode/flow/LoopBlock.java
  10. 5
      jode/jode/flow/RemoveEmpty.java
  11. 7
      jode/jode/flow/SequentialBlock.java
  12. 46
      jode/jode/flow/StructuredBlock.java
  13. 7
      jode/jode/flow/SynchronizedBlock.java

@ -88,7 +88,8 @@ public class CatchBlock extends StructuredBlock {
? new EmptyBlock() ? new EmptyBlock()
: catchBlock.getSubBlocks()[1]); : catchBlock.getSubBlocks()[1]);
newCatchBlock.moveJump(catchBlock.jump); if (catchBlock.jump != null)
newCatchBlock.moveJump(catchBlock.jump);
catchBlock = newCatchBlock; catchBlock = newCatchBlock;
} }
} }

@ -36,22 +36,22 @@ public class CatchFinallyBlock extends CatchBlock {
fin.setFlowBlock(flowBlock); fin.setFlowBlock(flowBlock);
} }
/** // /**
* Returns the block where the control will normally flow to, when // * Returns the block where the control will normally flow to, when
* the given sub block is finished (<em>not</em> ignoring the jump // * the given sub block is finished (<em>not</em> ignoring the jump
* after this block). FinallyBlock have a special behaviour, since // * after this block). FinallyBlock have a special behaviour, since
* the try block has the finallyblock as successor and the // * the try block has the finallyblock as successor and the
* finallyblock has no default successor at all!! // * finallyblock has no default successor at all!!
* // *
* @return null, if the control flows to another FlowBlock. // * @return null, if the control flows to another FlowBlock.
*/ // */
public StructuredBlock getNextBlock(StructuredBlock subBlock) { // public StructuredBlock getNextBlock(StructuredBlock subBlock) {
return subBlock == tryBlock ? finallyBlock : null; // return subBlock == tryBlock ? finallyBlock : null;
} // }
public FlowBlock getNextFlowBlock(StructuredBlock subBlock) { // public FlowBlock getNextFlowBlock(StructuredBlock subBlock) {
return null; // return null;
} // }
/** /**
* Replaces the given sub block with a new block. * Replaces the given sub block with a new block.

@ -80,6 +80,7 @@ public class CombineIfGotoExpressions implements Transformation{
} catch (NullPointerException ex) { } catch (NullPointerException ex) {
return false; return false;
} }
flow.removeSuccessor(prevJump);
prevJump.prev.removeJump(); prevJump.prev.removeJump();
Expression cond = Expression cond =
new ComplexExpression new ComplexExpression

@ -33,32 +33,38 @@ public class CompleteSynchronized implements Transformation {
*/ */
public boolean transform(FlowBlock flow) { public boolean transform(FlowBlock flow) {
SynchronizedBlock synBlock; if (!(flow.lastModified instanceof SynchronizedBlock)
try { || flow.lastModified.outer == null)
synBlock = (SynchronizedBlock) flow.lastModified; return false;
SequentialBlock sequBlock = /* If the program is well formed, the following succeed */
(SequentialBlock) synBlock.outer;
SynchronizedBlock synBlock = (SynchronizedBlock) flow.lastModified;
try {
SequentialBlock sequBlock = (SequentialBlock) synBlock.outer;
ComplexExpression monenter = (ComplexExpression) ComplexExpression monenter = (ComplexExpression)
((InstructionBlock) sequBlock.subBlocks[0]).getInstruction(); ((InstructionBlock) sequBlock.subBlocks[0]).getInstruction();
if (!(monenter.getOperator() instanceof MonitorEnterOperator) if (!(monenter.getOperator() instanceof MonitorEnterOperator)
|| ((LocalLoadOperator) monenter.getSubExpressions()[0]). || ((LocalLoadOperator) monenter.getSubExpressions()[0]).
getLocalInfo() != synBlock.local.getLocalInfo()) getLocalInfo() != synBlock.local.getLocalInfo())
return false; return false;
} catch (ClassCastException ex) { } catch (ClassCastException ex) {
return false; return false;
} catch (NullPointerException ex) {
return false;
} }
if (jode.Decompiler.isVerbose) if (jode.Decompiler.isVerbose)
System.err.print("f"); System.err.print('s');
synBlock.isEntered = true; synBlock.isEntered = true;
synBlock.replace(synBlock.outer, synBlock); synBlock.replace(synBlock.outer, synBlock);
/* Is there another expression? */
if (synBlock.outer == null)
return false;
Expression object; Expression object;
try { try {
SequentialBlock sequBlock = SequentialBlock sequBlock =
@ -75,8 +81,6 @@ public class CompleteSynchronized implements Transformation {
} catch (ClassCastException ex) { } catch (ClassCastException ex) {
return true; return true;
} catch (NullPointerException ex) {
return true;
} }
synBlock.object = object; synBlock.object = object;

@ -106,7 +106,7 @@ public class CreateExpression implements Transformation {
return false; return false;
} }
if(jode.Decompiler.isVerbose) if(jode.Decompiler.isVerbose)
System.err.print("x"); System.err.print('x');
((InstructionContainer) flow.lastModified).setInstruction ((InstructionContainer) flow.lastModified).setInstruction
(new ComplexExpression(op, exprs)); (new ComplexExpression(op, exprs));

@ -30,32 +30,33 @@ public class CreateForInitializer implements Transformation {
*/ */
public boolean transform(FlowBlock flow) { public boolean transform(FlowBlock flow) {
LoopBlock forBlock; if (!(flow.lastModified instanceof LoopBlock)
|| flow.lastModified.outer == null)
return false;
LoopBlock forBlock = (LoopBlock) flow.lastModified;
if (forBlock.type != forBlock.FOR || forBlock.init != null)
return false;
/* The following succeed, with high probability */
Instruction initializer; Instruction initializer;
try { try {
forBlock = (LoopBlock) flow.lastModified;
if (forBlock.type != forBlock.FOR || forBlock.init != null)
return false;
SequentialBlock sequBlock = SequentialBlock sequBlock =
(SequentialBlock) forBlock.outer; (SequentialBlock) forBlock.outer;
initializer = initializer =
((InstructionBlock) sequBlock.subBlocks[0]).getInstruction(); ((InstructionBlock) sequBlock.subBlocks[0]).getInstruction();
if (!(initializer instanceof Expression) if (!( ((Expression)initializer).getOperator()
|| !( ((Expression)initializer).getOperator() instanceof StoreInstruction))
instanceof StoreInstruction))
return false; return false;
} catch (ClassCastException ex) { } catch (ClassCastException ex) {
return false; return false;
} catch (NullPointerException ex) {
return false;
} }
if (jode.Decompiler.isVerbose) if (jode.Decompiler.isVerbose)
System.err.print("f"); System.err.print('f');
forBlock.init = initializer; forBlock.init = initializer;
forBlock.replace(forBlock.outer, forBlock); forBlock.replace(forBlock.outer, forBlock);

@ -61,28 +61,31 @@ public class CreateIfThenElseOperator implements Transformation {
*/ */
public boolean createFunny(FlowBlock flow) { public boolean createFunny(FlowBlock flow) {
Expression[] e = new Expression[3]; if (!(flow.lastModified instanceof ConditionalBlock))
IfThenElseBlock ifBlock; return false;
try {
ConditionalBlock conditional =
(ConditionalBlock) flow.lastModified;
if (!(conditional.trueBlock instanceof EmptyBlock) ConditionalBlock conditional = (ConditionalBlock) flow.lastModified;
|| conditional.trueBlock.jump == null
|| conditional.jump == null)
return false;
CompareUnaryOperator compare = if (!(conditional.trueBlock instanceof EmptyBlock)
(CompareUnaryOperator) conditional.getInstruction(); || conditional.trueBlock.jump == null
|| conditional.jump == null
|| !(conditional.getInstruction() instanceof CompareUnaryOperator))
return false;
CompareUnaryOperator compare =
(CompareUnaryOperator) conditional.getInstruction();
FlowBlock trueDestination;
if (compare.getOperatorIndex() == compare.EQUALS_OP)
trueDestination = conditional.jump.destination;
else if (compare.getOperatorIndex() == compare.NOTEQUALS_OP)
trueDestination = conditional.trueBlock.jump.destination;
else
return false;
FlowBlock trueDestination; Expression[] e = new Expression[3];
if (compare.getOperatorIndex() == compare.EQUALS_OP) IfThenElseBlock ifBlock;
trueDestination = conditional.jump.destination; try {
else if (compare.getOperatorIndex() == compare.NOTEQUALS_OP)
trueDestination = conditional.trueBlock.jump.destination;
else
return false;
SequentialBlock sequBlock = SequentialBlock sequBlock =
(SequentialBlock) conditional.outer; (SequentialBlock) conditional.outer;
@ -129,9 +132,11 @@ public class CreateIfThenElseOperator implements Transformation {
return false; return false;
Expression cond = (Expression) condBlock.getInstruction(); Expression cond = (Expression) condBlock.getInstruction();
flow.removeSuccessor(condBlock.trueBlock.jump);
condBlock.trueBlock.removeJump(); condBlock.trueBlock.removeJump();
pushBlock.setInstruction(cond); pushBlock.setInstruction(cond);
pushBlock.replace(sequBlock, pushBlock); pushBlock.replace(sequBlock, pushBlock);
e[i+1] = cond; e[i+1] = cond;
} }
} catch (ClassCastException ex) { } catch (ClassCastException ex) {
@ -141,7 +146,7 @@ public class CreateIfThenElseOperator implements Transformation {
} }
if (jode.Decompiler.isVerbose) if (jode.Decompiler.isVerbose)
System.err.print("?"); System.err.print('?');
IfThenElseOperator iteo = new IfThenElseOperator IfThenElseOperator iteo = new IfThenElseOperator
(e[1].getType().intersection(e[2].getType())); (e[1].getType().intersection(e[2].getType()));
@ -170,6 +175,7 @@ public class CreateIfThenElseOperator implements Transformation {
*/ */
public boolean create(FlowBlock flow) { public boolean create(FlowBlock flow) {
Expression e[] = new Expression[3]; Expression e[] = new Expression[3];
InstructionBlock thenBlock;
try { try {
InstructionBlock elseBlock = (InstructionBlock) flow.lastModified; InstructionBlock elseBlock = (InstructionBlock) flow.lastModified;
@ -181,7 +187,7 @@ public class CreateIfThenElseOperator implements Transformation {
if (ifBlock.elseBlock != null) if (ifBlock.elseBlock != null)
return false; return false;
InstructionBlock thenBlock = (InstructionBlock) ifBlock.thenBlock; thenBlock = (InstructionBlock) ifBlock.thenBlock;
if (thenBlock.jump.destination != elseBlock.jump.destination) if (thenBlock.jump.destination != elseBlock.jump.destination)
return false; return false;
@ -194,7 +200,6 @@ public class CreateIfThenElseOperator implements Transformation {
return false; return false;
e[0] = (Expression) ifBlock.cond; e[0] = (Expression) ifBlock.cond;
thenBlock.removeJump();
} catch (ClassCastException ex) { } catch (ClassCastException ex) {
return false; return false;
} catch (NullPointerException ex) { } catch (NullPointerException ex) {
@ -202,7 +207,10 @@ public class CreateIfThenElseOperator implements Transformation {
} }
if (jode.Decompiler.isVerbose) if (jode.Decompiler.isVerbose)
System.err.print("?"); System.err.print('?');
flow.removeSuccessor(thenBlock.jump);
thenBlock.removeJump();
IfThenElseOperator iteo = new IfThenElseOperator IfThenElseOperator iteo = new IfThenElseOperator
(e[1].getType().intersection(e[2].getType())); (e[1].getType().intersection(e[2].getType()));

File diff suppressed because it is too large Load Diff

@ -185,7 +185,7 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
writer.untab(); writer.untab();
if (type == DOWHILE) if (type == DOWHILE)
writer.println((needBrace?"} ": "")+ writer.println((needBrace?"} ": "")+
"while ("+cond.simplify().toString()+")"); "while ("+cond.simplify().toString()+");");
else if (needBrace) else if (needBrace)
writer.println("}"); writer.println("}");
} }
@ -223,16 +223,16 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
/** /**
* Replace all breaks to this block with a continue to this block. * Replace all breaks to this block with a continue to this block.
*/ */
public void replaceBreakContinue() { public void replaceBreakContinue(BreakableBlock block) {
java.util.Stack todo = new java.util.Stack(); java.util.Stack todo = new java.util.Stack();
todo.push(this); todo.push(block);
while (!todo.isEmpty()) { while (!todo.isEmpty()) {
StructuredBlock[] subs = StructuredBlock[] subs =
((StructuredBlock)todo.pop()).getSubBlocks(); ((StructuredBlock)todo.pop()).getSubBlocks();
for (int i=0; i<subs.length; i++) { for (int i=0; i<subs.length; i++) {
if (subs[i] instanceof BreakBlock) { if (subs[i] instanceof BreakBlock) {
BreakBlock breakblk = (BreakBlock) subs[i]; BreakBlock breakblk = (BreakBlock) subs[i];
if (breakblk.breaksBlock == this) { if (breakblk.breaksBlock == block) {
new ContinueBlock(this, breakblk.label != null) new ContinueBlock(this, breakblk.label != null)
.replace(breakblk, null); .replace(breakblk, null);
} }

@ -69,11 +69,8 @@ public class RemoveEmpty implements Transformation {
StructuredBlock block = lastBlock.outer.getSubBlocks()[0]; StructuredBlock block = lastBlock.outer.getSubBlocks()[0];
block.replace(block.outer, block); block.replace(block.outer, block);
if (block.jump == null) if (lastBlock.jump != null)
/*XXX can this happen */
block.moveJump(lastBlock.jump); block.moveJump(lastBlock.jump);
else
lastBlock.removeJump();
flow.lastModified = block; flow.lastModified = block;
return true; return true;
} }

@ -44,6 +44,13 @@ public class SequentialBlock extends StructuredBlock {
sb.setFlowBlock(flowBlock); sb.setFlowBlock(flowBlock);
} }
public void checkConsistent() {
super.checkConsistent();
if (subBlocks[0].jump != null
|| (jump != null && subBlocks[1].jump != null))
throw new jode.AssertError("Inconsistency");
}
/** /**
* Returns the block where the control will normally flow to, when * Returns the block where the control will normally flow to, when
* the given sub block is finished (<em>not</em> ignoring the jump * the given sub block is finished (<em>not</em> ignoring the jump

@ -19,6 +19,7 @@
package jode.flow; package jode.flow;
import jode.TabbedPrintWriter; import jode.TabbedPrintWriter;
import jode.AssertError;
import jode.LocalInfo; import jode.LocalInfo;
/** /**
@ -181,12 +182,11 @@ public abstract class StructuredBlock {
} }
/** /**
* Removes the jump. This does also update the successors vector * Removes the jump. This does not update the successors vector
* of the flow block. */ * of the flow block, you have to do it yourself. */
public void removeJump() { public void removeJump() {
if (jump != null) { if (jump != null) {
jump.prev = null; jump.prev = null;
flowBlock.removeSuccessor(jump);
jump = null; jump = null;
} }
} }
@ -262,7 +262,8 @@ public abstract class StructuredBlock {
* @param jump The jump that should be moved, may be null. * @param jump The jump that should be moved, may be null.
*/ */
public void moveJump(Jump jump) { public void moveJump(Jump jump) {
removeJump(); if (this.jump != null)
throw new AssertError("overriding with moveJump()");
this.jump = jump; this.jump = jump;
if (jump != null) { if (jump != null) {
jump.prev.jump = null; jump.prev.jump = null;
@ -282,6 +283,31 @@ public abstract class StructuredBlock {
return sequBlock; return sequBlock;
} }
/**
* Removes this block, or replaces it with an EmptyBlock.
*/
public void removeBlock() {
if (outer instanceof SequentialBlock) {
if (outer.getSubBlocks()[1] == this) {
if (jump != null)
outer.getSubBlocks()[0].moveJump(jump);
outer.getSubBlocks()[0].replace(outer, null);
return;
} else if (outer.outer instanceof SequentialBlock) {
if (jump != null)
outer.outer.getSubBlocks()[0].moveJump(jump);
outer.getSubBlocks()[1].replace(outer, null);
return;
}
}
EmptyBlock eb = new EmptyBlock();
eb.moveJump(jump);
eb.replace(this, null);
}
/** /**
* Determines if there is a sub block, that flows through to the end * Determines if there is a sub block, that flows through to the end
* of this block. If this returns true, you know that jump is null. * of this block. If this returns true, you know that jump is null.
@ -340,16 +366,14 @@ public abstract class StructuredBlock {
for (int i=0; i<subs.length; i++) { for (int i=0; i<subs.length; i++) {
if (subs[i].outer != this || if (subs[i].outer != this ||
subs[i].flowBlock != flowBlock) { subs[i].flowBlock != flowBlock) {
throw new RuntimeException("Inconsistency"); throw new AssertError("Inconsistency");
} }
subs[i].checkConsistent(); subs[i].checkConsistent();
} }
if (jump != null && if (jump != null
(jump.prev != this || && !((java.util.Stack)
!flowBlock.successors.contains(jump) || flowBlock.successors.get(jump.destination)).contains(jump))
!jump.destination.predecessors.contains(flowBlock))) { throw new AssertError("Inconsistency");
throw new RuntimeException("Inconsistency");
}
} }
/** /**

@ -80,18 +80,15 @@ public class SynchronizedBlock extends StructuredBlock {
public void dumpInstruction(TabbedPrintWriter writer) public void dumpInstruction(TabbedPrintWriter writer)
throws java.io.IOException throws java.io.IOException
{ {
boolean needsBrace = bodyBlock.needsBraces();
if (!isEntered) if (!isEntered)
writer.print("/* missing monitorenter */"); writer.print("/* missing monitorenter */");
writer.println("synchronized (" writer.println("synchronized ("
+ (object != null + (object != null
? object.simplify().toString() ? object.simplify().toString()
: local.getName()) + ")" : local.getName()) + ") {");
+ (needsBrace ? " {" :""));
writer.tab(); writer.tab();
bodyBlock.dumpSource(writer); bodyBlock.dumpSource(writer);
writer.untab(); writer.untab();
if (needsBrace) writer.println("}");
writer.println("}");
} }
} }

Loading…
Cancel
Save