instructions collectionified

git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@1102 379699f6-c40d-0410-875b-85095c16579e
branch_1_1
jochen 25 years ago
parent 67e5bf4656
commit 02522b5cef
  1. 32
      jode/jode/decompiler/DeadCodeAnalysis.java.in
  2. 19
      jode/jode/decompiler/MethodAnalyzer.java.in
  3. 24
      jode/jode/decompiler/Opcodes.java

@ -22,21 +22,20 @@ import jode.bytecode.BytecodeInfo;
import jode.bytecode.Instruction; import jode.bytecode.Instruction;
import jode.bytecode.Handler; import jode.bytecode.Handler;
import @COLLECTIONS@.Iterator;
public class DeadCodeAnalysis { public class DeadCodeAnalysis {
private final static String REACHABLE = "R"; private final static String REACHABLE = "R";
private final static String REACHCHANGED = "C"; private final static String REACHCHANGED = "C";
private static void propagateReachability(Instruction firstInstr, private static void propagateReachability(BytecodeInfo code) {
Instruction reachInstr) {
if (reachInstr.getTmpInfo() != null)
return;
reachInstr.setTmpInfo(REACHCHANGED);
boolean changed; boolean changed;
do { do {
changed = false; changed = false;
for (Instruction instr = firstInstr; for (Iterator iter = code.getInstructions().iterator();
instr != null; instr = instr.getNextByAddr()) { iter.hasNext(); ) {
Instruction instr = (Instruction) iter.next();
if (instr.getTmpInfo() == REACHCHANGED) { if (instr.getTmpInfo() == REACHCHANGED) {
changed = true; changed = true;
instr.setTmpInfo(REACHABLE); instr.setTmpInfo(REACHABLE);
@ -59,7 +58,8 @@ public class DeadCodeAnalysis {
} }
public static void removeDeadCode(BytecodeInfo code) { public static void removeDeadCode(BytecodeInfo code) {
propagateReachability(code.getFirstInstr(), code.getFirstInstr()); ((Instruction) code.getInstructions().get(0)).setTmpInfo(REACHCHANGED);
propagateReachability(code);
Handler[] handlers = code.getExceptionHandlers(); Handler[] handlers = code.getExceptionHandlers();
boolean changed; boolean changed;
do { do {
@ -72,8 +72,8 @@ public class DeadCodeAnalysis {
for (Instruction instr = handlers[i].start; for (Instruction instr = handlers[i].start;
instr != null; instr = instr.getNextByAddr()) { instr != null; instr = instr.getNextByAddr()) {
if (instr.getTmpInfo() != null) { if (instr.getTmpInfo() != null) {
propagateReachability(code.getFirstInstr(), handlers[i].catcher.setTmpInfo(REACHCHANGED);
handlers[i].catcher); propagateReachability(code);
changed = true; changed = true;
break; break;
} }
@ -105,14 +105,12 @@ public class DeadCodeAnalysis {
} }
/* Now remove the dead code and clean up tmpInfo */ /* Now remove the dead code and clean up tmpInfo */
Instruction nextInstr; for (Iterator i = code.getInstructions().iterator(); i.hasNext(); ) {
for (Instruction instr = code.getFirstInstr(); Instruction instr = (Instruction) i.next();
instr != null; instr = nextInstr) { if (instr.getTmpInfo() != null)
nextInstr = instr.getNextByAddr();
if (instr.getTmpInfo() == null)
instr.removeInstruction();
else
instr.setTmpInfo(null); instr.setTmpInfo(null);
else
i.remove();
} }
} }
} }

@ -54,6 +54,7 @@ import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import @COLLECTIONS@.Map; import @COLLECTIONS@.Map;
import @COLLECTIONS@.Iterator;
public class MethodAnalyzer implements Analyzer, Scope, ClassDeclarer { public class MethodAnalyzer implements Analyzer, Scope, ClassDeclarer {
ImportHandler imports; ImportHandler imports;
@ -240,8 +241,9 @@ public class MethodAnalyzer implements Analyzer, Scope, ClassDeclarer {
/* First create a FlowBlock for every block that has a /* First create a FlowBlock for every block that has a
* predecessor other than the previous instruction. * predecessor other than the previous instruction.
*/ */
for (Instruction instr = code.getFirstInstr(); for (Iterator i = code.getInstructions().iterator();
instr != null; instr = instr.getNextByAddr()) { i.hasNext(); ) {
Instruction instr = (Instruction) i.next();
if (instr.getPrevByAddr() == null if (instr.getPrevByAddr() == null
|| instr.getPrevByAddr().doesAlwaysJump() || instr.getPrevByAddr().doesAlwaysJump()
|| instr.getPreds() != null) || instr.getPreds() != null)
@ -271,8 +273,9 @@ public class MethodAnalyzer implements Analyzer, Scope, ClassDeclarer {
int mark = 1000; int mark = 1000;
FlowBlock lastBlock = null; FlowBlock lastBlock = null;
boolean lastSequential = false; boolean lastSequential = false;
for (Instruction instr = code.getFirstInstr(); for (Iterator i = code.getInstructions().iterator();
instr != null; instr = instr.getNextByAddr()) { i.hasNext(); ) {
Instruction instr = (Instruction) i.next();
jode.flow.StructuredBlock block jode.flow.StructuredBlock block
= Opcodes.readOpcode(instr, this); = Opcodes.readOpcode(instr, this);
@ -306,7 +309,8 @@ public class MethodAnalyzer implements Analyzer, Scope, ClassDeclarer {
} }
} }
methodHeader = (FlowBlock) code.getFirstInstr().getTmpInfo(); methodHeader = (FlowBlock)
((Instruction) code.getInstructions().get(0)).getTmpInfo();
excHandlers = new TransformExceptionHandlers(); excHandlers = new TransformExceptionHandlers();
for (int i=0; i<handlers.length; i++) { for (int i=0; i<handlers.length; i++) {
Type type = null; Type type = null;
@ -321,9 +325,10 @@ public class MethodAnalyzer implements Analyzer, Scope, ClassDeclarer {
excHandlers.addHandler(start, endAddr, handler, type); excHandlers.addHandler(start, endAddr, handler, type);
} }
} }
for (Instruction instr = code.getFirstInstr(); for (Iterator i = code.getInstructions().iterator(); i.hasNext(); ) {
instr != null; instr = instr.getNextByAddr()) Instruction instr = (Instruction) i.next();
instr.setTmpInfo(null); instr.setTmpInfo(null);
}
if (GlobalOptions.verboseLevel > 0) if (GlobalOptions.verboseLevel > 0)
GlobalOptions.err.print('-'); GlobalOptions.err.print('-');

@ -92,14 +92,14 @@ public abstract class Opcodes implements jode.bytecode.Opcodes {
Instruction instr) Instruction instr)
{ {
return new EmptyBlock return new EmptyBlock
(new Jump((FlowBlock)instr.getSuccs()[0].getTmpInfo())); (new Jump((FlowBlock)instr.getSingleSucc().getTmpInfo()));
} }
private static StructuredBlock createJsr(MethodAnalyzer ma, private static StructuredBlock createJsr(MethodAnalyzer ma,
Instruction instr) Instruction instr)
{ {
return new JsrBlock return new JsrBlock
(new Jump((FlowBlock)instr.getSuccs()[0].getTmpInfo()), (new Jump((FlowBlock)instr.getSingleSucc().getTmpInfo()),
new Jump(FlowBlock.NEXT_BY_ADDR)); new Jump(FlowBlock.NEXT_BY_ADDR));
} }
@ -108,7 +108,7 @@ public abstract class Opcodes implements jode.bytecode.Opcodes {
Expression expr) Expression expr)
{ {
return new ConditionalBlock return new ConditionalBlock
(expr, new Jump((FlowBlock)instr.getSuccs()[0].getTmpInfo()), (expr, new Jump((FlowBlock)instr.getSingleSucc().getTmpInfo()),
new Jump(FlowBlock.NEXT_BY_ADDR)); new Jump(FlowBlock.NEXT_BY_ADDR));
} }
@ -176,7 +176,7 @@ public abstract class Opcodes implements jode.bytecode.Opcodes {
(ma, instr, new StoreInstruction (ma, instr, new StoreInstruction
(new LocalStoreOperator (new LocalStoreOperator
(types[LOCAL_TYPES][opcode-opc_istore], (types[LOCAL_TYPES][opcode-opc_istore],
ma.getLocalInfo(instr.getAddr()+instr.getLength(), ma.getLocalInfo(instr.getNextByAddr().getAddr(),
instr.getLocalSlot())))); instr.getLocalSlot()))));
case opc_iastore: case opc_lastore: case opc_iastore: case opc_lastore:
case opc_fastore: case opc_dastore: case opc_aastore: case opc_fastore: case opc_dastore: case opc_aastore:
@ -223,7 +223,7 @@ public abstract class Opcodes implements jode.bytecode.Opcodes {
(types[ZBIN_TYPES][(opcode - opc_iand)%2], (types[ZBIN_TYPES][(opcode - opc_iand)%2],
(opcode - opc_iand)/2 + Operator.AND_OP)); (opcode - opc_iand)/2 + Operator.AND_OP));
case opc_iinc: { case opc_iinc: {
int value = instr.getIntData(); int value = instr.getIncrement();
int operation = Operator.ADD_OP; int operation = Operator.ADD_OP;
if (value < 0) { if (value < 0) {
value = -value; value = -value;
@ -294,18 +294,6 @@ public abstract class Opcodes implements jode.bytecode.Opcodes {
return createRet return createRet
(ma, instr, (ma, instr,
ma.getLocalInfo(instr.getAddr(), instr.getLocalSlot())); ma.getLocalInfo(instr.getAddr(), instr.getLocalSlot()));
case opc_tableswitch: {
int low = instr.getIntData();
int[] cases = new int[instr.getSuccs().length-1];
FlowBlock[] dests = new FlowBlock[instr.getSuccs().length];
for (int i=0; i < cases.length; i++) {
cases[i] = i+low;
dests[i] = (FlowBlock) instr.getSuccs()[i].getTmpInfo();
}
dests[cases.length] = (FlowBlock)
instr.getSuccs()[cases.length].getTmpInfo();
return createSwitch(ma, instr, cases, dests);
}
case opc_lookupswitch: { case opc_lookupswitch: {
int[] cases = instr.getValues(); int[] cases = instr.getValues();
FlowBlock[] dests = new FlowBlock[instr.getSuccs().length]; FlowBlock[] dests = new FlowBlock[instr.getSuccs().length];
@ -382,7 +370,7 @@ public abstract class Opcodes implements jode.bytecode.Opcodes {
case opc_multianewarray: { case opc_multianewarray: {
Type type = Type.tType(instr.getClazzType()); Type type = Type.tType(instr.getClazzType());
ma.useType(type); ma.useType(type);
int dimension = instr.getIntData(); int dimension = instr.getDimensions();
return createNormal(ma, instr, return createNormal(ma, instr,
new NewArrayOperator(type, dimension)); new NewArrayOperator(type, dimension));
} }

Loading…
Cancel
Save