From f26d8a21e6bcd7cc838cdaef03b4f8a29ceeb279 Mon Sep 17 00:00:00 2001 From: hoenicke Date: Fri, 1 Dec 2000 10:33:58 +0000 Subject: [PATCH] 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 --- jode/jode/bytecode/BytecodeInfo.java.in | 105 +++++++++++++++--- .../obfuscator/modules/LocalOptimizer.java.in | 9 +- 2 files changed, 89 insertions(+), 25 deletions(-) diff --git a/jode/jode/bytecode/BytecodeInfo.java.in b/jode/jode/bytecode/BytecodeInfo.java.in index d7a0169..b098753 100644 --- a/jode/jode/bytecode/BytecodeInfo.java.in +++ b/jode/jode/bytecode/BytecodeInfo.java.in @@ -25,6 +25,8 @@ import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.EOFException; import java.io.IOException; +import java.util.BitSet; +import java.util.Stack; import java.util.Vector; import java.util.Enumeration; 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) { - /* Recalculate addr, length and add all constants to gcp */ + /* Recalculate addr, length, maxStack, maxLocals and add all + * constants to gcp */ int addr = 0; + maxLocals = 0; for (Iterator iter = instructions.iterator(); iter.hasNext(); ) { Instruction instr = (Instruction) iter.next(); int opcode = instr.getOpcode(); @@ -957,22 +1011,44 @@ public class BytecodeInfo extends BinaryInfo implements Opcodes { length = 3; else length = 6; + if (slot >= maxLocals) + maxLocals = slot + 1; break; } - case opc_iload: case opc_lload: - case opc_fload: case opc_dload: case opc_aload: - case opc_istore: case opc_lstore: - case opc_fstore: case opc_dstore: case opc_astore: - if (instr.getLocalSlot() < 4) { + case opc_iload: case opc_fload: case opc_aload: + case opc_istore: case opc_fstore: case opc_astore: { + int slot = instr.getLocalSlot(); + if (slot < 4) length = 1; - break; - } - /* fall through */ + else if (slot < 256) + length = 2; + 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: { - if (instr.getLocalSlot() < 256) + int slot = instr.getLocalSlot(); + if (slot < 256) length = 2; else length = 4; + if (slot >= maxLocals) + maxLocals = slot + 1; break; } case opc_lookupswitch: { @@ -1092,6 +1168,7 @@ public class BytecodeInfo extends BinaryInfo implements Opcodes { addr += length; } instructions.setLastAddr(addr); + calculateMaxStack(); for (int i=0; i< exceptionHandlers.length; i++) if (exceptionHandlers[i].type != null) gcp.putClassName(exceptionHandlers[i].type); @@ -1483,14 +1560,6 @@ public class BytecodeInfo extends BinaryInfo implements Opcodes { return lnt; } - public void setMaxStack(int ms) { - maxStack = ms; - } - - public void setMaxLocals(int ml) { - maxLocals = ml; - } - public void setExceptionHandlers(Handler[] handlers) { exceptionHandlers = handlers; } diff --git a/jode/jode/obfuscator/modules/LocalOptimizer.java.in b/jode/jode/obfuscator/modules/LocalOptimizer.java.in index cb776fc..bb1b0c0 100644 --- a/jode/jode/obfuscator/modules/LocalOptimizer.java.in +++ b/jode/jode/obfuscator/modules/LocalOptimizer.java.in @@ -657,17 +657,12 @@ public class LocalOptimizer implements Opcodes, CodeTransformer { */ distributeLocals(locals); - /* Update the instructions and calculate new maxlocals. + /* Update the instructions. */ - maxlocals = paramLocals.length; for (InstrInfo info = firstInfo; info != null; info = info.nextInfo) { - if (info.local != null) { - if (info.local.newSlot+info.local.size > maxlocals) - maxlocals = info.local.newSlot + info.local.size; + if (info.local != null) info.instr.setLocalSlot(info.local.newSlot); - } } - bc.setMaxLocals(maxlocals); /* Update LocalVariableTable */