Calculate number of stack elements and local variables in prepareWriting.

Removed setting of number of local variables from LocalOptimizer.


git-svn-id: https://svn.code.sf.net/p/jode/code/branches/branch_1_1@1275 379699f6-c40d-0410-875b-85095c16579e
branch_1_1
hoenicke 24 years ago
parent a56a7f0e98
commit f26d8a21e6
  1. 105
      jode/jode/bytecode/BytecodeInfo.java.in
  2. 9
      jode/jode/obfuscator/modules/LocalOptimizer.java.in

@ -25,6 +25,8 @@ import java.io.ByteArrayInputStream;
import java.io.InputStream; import java.io.InputStream;
import java.io.EOFException; import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
import java.util.BitSet;
import java.util.Stack;
import java.util.Vector; import java.util.Vector;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
@ -901,9 +903,61 @@ public class BytecodeInfo extends BinaryInfo implements Opcodes {
} }
} }
private void calculateMaxStack() {
maxStack = 0;
int[] stackHeights = new int[instructions.getCodeLength()];
int[] poppush = new int[2];
Stack todo = new Stack();
for (int i=0; i < stackHeights.length; i++)
stackHeights[i] = -1;
stackHeights[0] = 0;
todo.push(instructions.get(0));
while (!todo.isEmpty()) {
Instruction instr = (Instruction) todo.pop();
Instruction next = instr.getNextByAddr();
Instruction[] succs = instr.getSuccs();
int addr = instr.getAddr();
instr.getStackPopPush(poppush);
int sh = stackHeights[addr] - poppush[0] + poppush[1];
// System.err.println("Instr: "+instr.getDescription()+
// "; before: "+stackHeights[addr]+" after: "+sh);
if (maxStack < sh)
maxStack = sh;
if (instr.getOpcode() == opc_jsr) {
if (stackHeights[next.getAddr()] == -1) {
stackHeights[next.getAddr()] = sh - 1;
todo.push(next);
}
if (stackHeights[succs[0].getAddr()] == -1) {
stackHeights[succs[0].getAddr()] = sh;
todo.push(succs[0]);
}
} else {
if (succs != null) {
for (int i=0; i < succs.length; i++) {
if (stackHeights[succs[i].getAddr()] == -1) {
stackHeights[succs[i].getAddr()] = sh;
todo.push(succs[i]);
}
}
}
if (!instr.doesAlwaysJump()
&& stackHeights[next.getAddr()] == -1) {
stackHeights[next.getAddr()] = sh;
todo.push(next);
}
}
}
// System.err.println("New maxStack: "+maxStack+" Locals: "+maxLocals);
}
public void prepareWriting(GrowableConstantPool gcp) { public void prepareWriting(GrowableConstantPool gcp) {
/* Recalculate addr, length and add all constants to gcp */ /* Recalculate addr, length, maxStack, maxLocals and add all
* constants to gcp */
int addr = 0; int addr = 0;
maxLocals = 0;
for (Iterator iter = instructions.iterator(); iter.hasNext(); ) { for (Iterator iter = instructions.iterator(); iter.hasNext(); ) {
Instruction instr = (Instruction) iter.next(); Instruction instr = (Instruction) iter.next();
int opcode = instr.getOpcode(); int opcode = instr.getOpcode();
@ -957,22 +1011,44 @@ public class BytecodeInfo extends BinaryInfo implements Opcodes {
length = 3; length = 3;
else else
length = 6; length = 6;
if (slot >= maxLocals)
maxLocals = slot + 1;
break; break;
} }
case opc_iload: case opc_lload: case opc_iload: case opc_fload: case opc_aload:
case opc_fload: case opc_dload: case opc_aload: case opc_istore: case opc_fstore: case opc_astore: {
case opc_istore: case opc_lstore: int slot = instr.getLocalSlot();
case opc_fstore: case opc_dstore: case opc_astore: if (slot < 4)
if (instr.getLocalSlot() < 4) {
length = 1; length = 1;
break; else if (slot < 256)
} length = 2;
/* fall through */ else
length = 4;
if (slot >= maxLocals)
maxLocals = slot + 1;
break;
}
case opc_lload: case opc_dload:
case opc_lstore: case opc_dstore: {
int slot = instr.getLocalSlot();
if (slot < 4)
length = 1;
else if (slot < 256)
length = 2;
else
length = 4;
if (slot+1 >= maxLocals)
maxLocals = slot + 2;
break;
}
case opc_ret: { case opc_ret: {
if (instr.getLocalSlot() < 256) int slot = instr.getLocalSlot();
if (slot < 256)
length = 2; length = 2;
else else
length = 4; length = 4;
if (slot >= maxLocals)
maxLocals = slot + 1;
break; break;
} }
case opc_lookupswitch: { case opc_lookupswitch: {
@ -1092,6 +1168,7 @@ public class BytecodeInfo extends BinaryInfo implements Opcodes {
addr += length; addr += length;
} }
instructions.setLastAddr(addr); instructions.setLastAddr(addr);
calculateMaxStack();
for (int i=0; i< exceptionHandlers.length; i++) for (int i=0; i< exceptionHandlers.length; i++)
if (exceptionHandlers[i].type != null) if (exceptionHandlers[i].type != null)
gcp.putClassName(exceptionHandlers[i].type); gcp.putClassName(exceptionHandlers[i].type);
@ -1483,14 +1560,6 @@ public class BytecodeInfo extends BinaryInfo implements Opcodes {
return lnt; return lnt;
} }
public void setMaxStack(int ms) {
maxStack = ms;
}
public void setMaxLocals(int ml) {
maxLocals = ml;
}
public void setExceptionHandlers(Handler[] handlers) { public void setExceptionHandlers(Handler[] handlers) {
exceptionHandlers = handlers; exceptionHandlers = handlers;
} }

@ -657,17 +657,12 @@ public class LocalOptimizer implements Opcodes, CodeTransformer {
*/ */
distributeLocals(locals); distributeLocals(locals);
/* Update the instructions and calculate new maxlocals. /* Update the instructions.
*/ */
maxlocals = paramLocals.length;
for (InstrInfo info = firstInfo; info != null; info = info.nextInfo) { for (InstrInfo info = firstInfo; info != null; info = info.nextInfo) {
if (info.local != null) { if (info.local != null)
if (info.local.newSlot+info.local.size > maxlocals)
maxlocals = info.local.newSlot + info.local.size;
info.instr.setLocalSlot(info.local.newSlot); info.instr.setLocalSlot(info.local.newSlot);
}
} }
bc.setMaxLocals(maxlocals);
/* Update LocalVariableTable /* Update LocalVariableTable
*/ */

Loading…
Cancel
Save