From 78e22836ceeb746446dc0aded64a0e6df3b78743 Mon Sep 17 00:00:00 2001 From: aclement Date: Wed, 13 Aug 2008 18:18:22 +0000 Subject: [PATCH] 243192: optimizing handling of constant instructions (eg. ALOAD_0) --- .../apache/bcel/generic/Instruction.java | 83 ++++++++++--------- .../apache/bcel/generic/InstructionCLV.java | 9 +- .../bcel/generic/InstructionConstants.java | 36 +++++--- .../apache/bcel/generic/InstructionLV.java | 53 +++++++++++- 4 files changed, 123 insertions(+), 58 deletions(-) diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/Instruction.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/Instruction.java index 1470c3637..de43f4697 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/Instruction.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/Instruction.java @@ -66,7 +66,7 @@ import org.aspectj.apache.bcel.util.ByteSequence; /** * Abstract super class for all Java byte codes. * - * @version $Id: Instruction.java,v 1.5 2008/05/28 23:52:58 aclement Exp $ + * @version $Id: Instruction.java,v 1.6 2008/08/13 18:18:22 aclement Exp $ * @author M. Dahm */ public class Instruction implements Cloneable, Serializable, Constants { @@ -157,48 +157,49 @@ public class Instruction implements Cloneable, Serializable, Constants { case Constants.ALOAD : obj = new InstructionLV(Constants.ALOAD,wide?bytes.readUnsignedShort():bytes.readUnsignedByte()); break; // move these to InstructionConstants - case Constants.ILOAD_0: obj = new InstructionLV(Constants.ILOAD_0);break; - case Constants.ILOAD_1: obj = new InstructionLV(Constants.ILOAD_1);break; - case Constants.ILOAD_2: obj = new InstructionLV(Constants.ILOAD_2);break; - case Constants.ILOAD_3: obj = new InstructionLV(Constants.ILOAD_3);break; - case Constants.LLOAD_0: obj = new InstructionLV(Constants.LLOAD_0);break; - case Constants.LLOAD_1: obj = new InstructionLV(Constants.LLOAD_1);break; - case Constants.LLOAD_2: obj = new InstructionLV(Constants.LLOAD_2);break; - case Constants.LLOAD_3: obj = new InstructionLV(Constants.LLOAD_3);break; - case Constants.FLOAD_0: obj = new InstructionLV(Constants.FLOAD_0);break; - case Constants.FLOAD_1: obj = new InstructionLV(Constants.FLOAD_1);break; - case Constants.FLOAD_2: obj = new InstructionLV(Constants.FLOAD_2);break; - case Constants.FLOAD_3: obj = new InstructionLV(Constants.FLOAD_3);break; - case Constants.DLOAD_0: obj = new InstructionLV(Constants.DLOAD_0);break; - case Constants.DLOAD_1: obj = new InstructionLV(Constants.DLOAD_1);break; - case Constants.DLOAD_2: obj = new InstructionLV(Constants.DLOAD_2);break; - case Constants.DLOAD_3: obj = new InstructionLV(Constants.DLOAD_3);break; - case Constants.ALOAD_0: obj = new InstructionLV(Constants.ALOAD_0);break; - case Constants.ALOAD_1: obj = new InstructionLV(Constants.ALOAD_1);break; - case Constants.ALOAD_2: obj = new InstructionLV(Constants.ALOAD_2);break; - case Constants.ALOAD_3: obj = new InstructionLV(Constants.ALOAD_3);break; +// case Constants.ILOAD_0: obj = new InstructionLV(Constants.ILOAD_0);break; +// case Constants.ILOAD_1: obj = new InstructionLV(Constants.ILOAD_1);break; +// case Constants.ILOAD_2: obj = new InstructionLV(Constants.ILOAD_2);break; +// case Constants.ILOAD_3: obj = new InstructionLV(Constants.ILOAD_3);break; +// case Constants.LLOAD_0: obj = new InstructionLV(Constants.LLOAD_0);break; +// case Constants.LLOAD_1: obj = new InstructionLV(Constants.LLOAD_1);break; +// case Constants.LLOAD_2: obj = new InstructionLV(Constants.LLOAD_2);break; +// case Constants.LLOAD_3: obj = new InstructionLV(Constants.LLOAD_3);break; +// case Constants.FLOAD_0: obj = new InstructionLV(Constants.FLOAD_0);break; +// case Constants.FLOAD_1: obj = new InstructionLV(Constants.FLOAD_1);break; +// case Constants.FLOAD_2: obj = new InstructionLV(Constants.FLOAD_2);break; +// case Constants.FLOAD_3: obj = new InstructionLV(Constants.FLOAD_3);break; +// case Constants.DLOAD_0: obj = new InstructionLV(Constants.DLOAD_0);break; +// case Constants.DLOAD_1: obj = new InstructionLV(Constants.DLOAD_1);break; +// case Constants.DLOAD_2: obj = new InstructionLV(Constants.DLOAD_2);break; +// case Constants.DLOAD_3: obj = new InstructionLV(Constants.DLOAD_3);break; +// case Constants.ALOAD_0: obj = new InstructionLV(Constants.ALOAD_0);break; +// case Constants.ALOAD_1: obj = new InstructionLV(Constants.ALOAD_1);break; +// case Constants.ALOAD_2: obj = new InstructionLV(Constants.ALOAD_2);break; +// case Constants.ALOAD_3: obj = new InstructionLV(Constants.ALOAD_3);break; // move to constants? - case Constants.ISTORE_0: obj = new InstructionLV(Constants.ISTORE_0);break; - case Constants.ISTORE_1: obj = new InstructionLV(Constants.ISTORE_1);break; - case Constants.ISTORE_2: obj = new InstructionLV(Constants.ISTORE_2);break; - case Constants.ISTORE_3: obj = new InstructionLV(Constants.ISTORE_3);break; - case Constants.LSTORE_0: obj = new InstructionLV(Constants.LSTORE_0);break; - case Constants.LSTORE_1: obj = new InstructionLV(Constants.LSTORE_1);break; - case Constants.LSTORE_2: obj = new InstructionLV(Constants.LSTORE_2);break; - case Constants.LSTORE_3: obj = new InstructionLV(Constants.LSTORE_3);break; - case Constants.FSTORE_0: obj = new InstructionLV(Constants.FSTORE_0);break; - case Constants.FSTORE_1: obj = new InstructionLV(Constants.FSTORE_1);break; - case Constants.FSTORE_2: obj = new InstructionLV(Constants.FSTORE_2);break; - case Constants.FSTORE_3: obj = new InstructionLV(Constants.FSTORE_3);break; - case Constants.DSTORE_0: obj = new InstructionLV(Constants.DSTORE_0);break; - case Constants.DSTORE_1: obj = new InstructionLV(Constants.DSTORE_1);break; - case Constants.DSTORE_2: obj = new InstructionLV(Constants.DSTORE_2);break; - case Constants.DSTORE_3: obj = new InstructionLV(Constants.DSTORE_3);break; - case Constants.ASTORE_0: obj = new InstructionLV(Constants.ASTORE_0);break; - case Constants.ASTORE_1: obj = new InstructionLV(Constants.ASTORE_1);break; - case Constants.ASTORE_2: obj = new InstructionLV(Constants.ASTORE_2);break; - case Constants.ASTORE_3: obj = new InstructionLV(Constants.ASTORE_3);break; +// case Constants.ISTORE_0: obj = new InstructionLV(Constants.ISTORE_0);break; +// case Constants.ISTORE_1: obj = new InstructionLV(Constants.ISTORE_1);break; +// case Constants.ISTORE_2: obj = new InstructionLV(Constants.ISTORE_2);break; +// case Constants.ISTORE_3: obj = new InstructionLV(Constants.ISTORE_3);break; +// case Constants.LSTORE_0: obj = new InstructionLV(Constants.LSTORE_0);break; +// case Constants.LSTORE_1: obj = new InstructionLV(Constants.LSTORE_1);break; +// case Constants.LSTORE_2: obj = new InstructionLV(Constants.LSTORE_2);break; +// case Constants.LSTORE_3: obj = new InstructionLV(Constants.LSTORE_3);break; +// case Constants.FSTORE_0: obj = new InstructionLV(Constants.FSTORE_0);break; +// case Constants.FSTORE_1: obj = new InstructionLV(Constants.FSTORE_1);break; +// case Constants.FSTORE_2: obj = new InstructionLV(Constants.FSTORE_2);break; +// case Constants.FSTORE_3: obj = new InstructionLV(Constants.FSTORE_3);break; +// case Constants.DSTORE_0: obj = new InstructionLV(Constants.DSTORE_0);break; +// case Constants.DSTORE_1: obj = new InstructionLV(Constants.DSTORE_1);break; +// case Constants.DSTORE_2: obj = new InstructionLV(Constants.DSTORE_2);break; +// case Constants.DSTORE_3: obj = new InstructionLV(Constants.DSTORE_3);break; +// case Constants.ASTORE_0: obj = new InstructionLV(Constants.ASTORE_0);break; +// case Constants.ASTORE_1: obj = new InstructionLV(Constants.ASTORE_1);break; +// case Constants.ASTORE_2: obj = new InstructionLV(Constants.ASTORE_2);break; +// case Constants.ASTORE_3: obj = new InstructionLV(Constants.ASTORE_3);break; + // case Constants.IALOAD : obj = new IALOAD(); break; // case Constants.LALOAD : obj = new LALOAD(); break; // case Constants.FALOAD : obj = new FALOAD(); break; diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionCLV.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionCLV.java index 21e504c73..85ae588e5 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionCLV.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionCLV.java @@ -15,8 +15,13 @@ public class InstructionCLV extends InstructionLV { } public void setIndex(int localVariableIndex) { - if (localVariableIndex!=getIndex())//allow this, shouldnt really... - throw new ClassGenException("Do not attempt to modify the index for this constant instruction: "+this); + if (localVariableIndex!=getIndex()) { + throw new ClassGenException("Do not attempt to modify the index to '"+localVariableIndex+"' for this constant instruction: "+this); + } + } + + public boolean canSetIndex() { + return false; } } diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionConstants.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionConstants.java index 553b67986..e6f884793 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionConstants.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionConstants.java @@ -70,7 +70,7 @@ import org.aspectj.apache.bcel.Constants; * The Instructions can also accessed directly under their names, so * it's possible to write il.append(Instruction.ICONST_0); * - * @version $Id: InstructionConstants.java,v 1.3 2008/05/28 23:52:55 aclement Exp $ + * @version $Id: InstructionConstants.java,v 1.4 2008/08/13 18:18:22 aclement Exp $ * @author M. Dahm */ public interface InstructionConstants { @@ -351,17 +351,29 @@ public interface InstructionConstants { INSTRUCTIONS[Constants.MONITORENTER] = MONITORENTER; INSTRUCTIONS[Constants.MONITOREXIT] = MONITOREXIT; INSTRUCTIONS[Constants.IMPDEP1] = IMPDEP1; - INSTRUCTIONS[Constants.IMPDEP2] = IMPDEP2; -// INSTRUCTIONS[Constants.ALOAD_0] = ALOAD_0;INSTRUCTIONS[Constants.ALOAD_1] = ALOAD_1; -// INSTRUCTIONS[Constants.ALOAD_2] = ALOAD_2;INSTRUCTIONS[Constants.ALOAD_3] = ALOAD_3; -// INSTRUCTIONS[Constants.LLOAD_0] = LLOAD_0;INSTRUCTIONS[Constants.LLOAD_1] = LLOAD_1; -// INSTRUCTIONS[Constants.LLOAD_2] = LLOAD_2;INSTRUCTIONS[Constants.LLOAD_3] = LLOAD_3; -// INSTRUCTIONS[Constants.DLOAD_0] = DLOAD_0;INSTRUCTIONS[Constants.DLOAD_1] = DLOAD_1; -// INSTRUCTIONS[Constants.DLOAD_2] = DLOAD_2;INSTRUCTIONS[Constants.DLOAD_3] = DLOAD_3; -// INSTRUCTIONS[Constants.FLOAD_0] = FLOAD_0;INSTRUCTIONS[Constants.FLOAD_1] = FLOAD_1; -// INSTRUCTIONS[Constants.FLOAD_2] = FLOAD_2;INSTRUCTIONS[Constants.FLOAD_3] = FLOAD_3; -// INSTRUCTIONS[Constants.ILOAD_0] = ILOAD_0;INSTRUCTIONS[Constants.ILOAD_1] = ILOAD_1; -// INSTRUCTIONS[Constants.ILOAD_2] = ILOAD_2;INSTRUCTIONS[Constants.ILOAD_3] = ILOAD_3; + INSTRUCTIONS[Constants.IMPDEP2] = IMPDEP2; + + INSTRUCTIONS[Constants.ALOAD_0] = ALOAD_0;INSTRUCTIONS[Constants.ALOAD_1] = ALOAD_1; + INSTRUCTIONS[Constants.ALOAD_2] = ALOAD_2;INSTRUCTIONS[Constants.ALOAD_3] = ALOAD_3; + INSTRUCTIONS[Constants.LLOAD_0] = LLOAD_0;INSTRUCTIONS[Constants.LLOAD_1] = LLOAD_1; + INSTRUCTIONS[Constants.LLOAD_2] = LLOAD_2;INSTRUCTIONS[Constants.LLOAD_3] = LLOAD_3; + INSTRUCTIONS[Constants.DLOAD_0] = DLOAD_0;INSTRUCTIONS[Constants.DLOAD_1] = DLOAD_1; + INSTRUCTIONS[Constants.DLOAD_2] = DLOAD_2;INSTRUCTIONS[Constants.DLOAD_3] = DLOAD_3; + INSTRUCTIONS[Constants.FLOAD_0] = FLOAD_0;INSTRUCTIONS[Constants.FLOAD_1] = FLOAD_1; + INSTRUCTIONS[Constants.FLOAD_2] = FLOAD_2;INSTRUCTIONS[Constants.FLOAD_3] = FLOAD_3; + INSTRUCTIONS[Constants.ILOAD_0] = ILOAD_0;INSTRUCTIONS[Constants.ILOAD_1] = ILOAD_1; + INSTRUCTIONS[Constants.ILOAD_2] = ILOAD_2;INSTRUCTIONS[Constants.ILOAD_3] = ILOAD_3; + + INSTRUCTIONS[Constants.ASTORE_0] = ASTORE_0;INSTRUCTIONS[Constants.ASTORE_1] = ASTORE_1; + INSTRUCTIONS[Constants.ASTORE_2] = ASTORE_2;INSTRUCTIONS[Constants.ASTORE_3] = ASTORE_3; + INSTRUCTIONS[Constants.LSTORE_0] = LSTORE_0;INSTRUCTIONS[Constants.LSTORE_1] = LSTORE_1; + INSTRUCTIONS[Constants.LSTORE_2] = LSTORE_2;INSTRUCTIONS[Constants.LSTORE_3] = LSTORE_3; + INSTRUCTIONS[Constants.DSTORE_0] = DSTORE_0;INSTRUCTIONS[Constants.DSTORE_1] = DSTORE_1; + INSTRUCTIONS[Constants.DSTORE_2] = DSTORE_2;INSTRUCTIONS[Constants.DSTORE_3] = DSTORE_3; + INSTRUCTIONS[Constants.FSTORE_0] = FSTORE_0;INSTRUCTIONS[Constants.FSTORE_1] = FSTORE_1; + INSTRUCTIONS[Constants.FSTORE_2] = FSTORE_2;INSTRUCTIONS[Constants.FSTORE_3] = FSTORE_3; + INSTRUCTIONS[Constants.ISTORE_0] = ISTORE_0;INSTRUCTIONS[Constants.ISTORE_1] = ISTORE_1; + INSTRUCTIONS[Constants.ISTORE_2] = ISTORE_2;INSTRUCTIONS[Constants.ISTORE_3] = ISTORE_3; } } } diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionLV.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionLV.java index cfeeac0bd..5afe7344f 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionLV.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionLV.java @@ -61,11 +61,11 @@ import org.aspectj.apache.bcel.Constants; /** * Abstract super class for instructions dealing with local variables. * - * @version $Id: InstructionLV.java,v 1.2 2008/05/28 23:52:57 aclement Exp $ + * @version $Id: InstructionLV.java,v 1.3 2008/08/13 18:18:22 aclement Exp $ * @author M. Dahm */ public class InstructionLV extends Instruction { - protected int lvar = -1; + protected int lvar = -1; public InstructionLV(short opcode, int lvar) { @@ -128,6 +128,23 @@ public class InstructionLV extends Instruction { public boolean isASTORE() { return opcode==ASTORE || (opcode>=ASTORE_0 && opcode<=ASTORE_3); } + + public int getBaseOpcode() { + if ((opcode>=ILOAD && opcode<=ALOAD) || (opcode>=ISTORE && opcode<=ASTORE)) { + // not an optimized instruction + return opcode; + } + if ((opcode>=Constants.ILOAD_0) && (opcode<=Constants.ALOAD_3)) { + int ret = opcode - ILOAD_0; + ret = ret - (ret%4); + ret = ret / 4; + return ret + ILOAD; + } + int ret = opcode - ISTORE_0; + ret = ret - (ret%4); + ret = ret / 4; + return ret + ISTORE; + } /** * @return local variable index referred by this instruction. @@ -155,7 +172,37 @@ public class InstructionLV extends Instruction { this.lvar = i; } } - + + public boolean canSetIndex() { + return true; + } + + public InstructionLV setIndexAndCopyIfNecessary(int newIndex) { + if (canSetIndex()) { + setIndex(newIndex); + return this; + } else { + if (getIndex()==newIndex) { + return this; + } + InstructionLV newInstruction = null; + int baseOpCode = getBaseOpcode(); + if (newIndex<4) { + if (isStoreInstruction()) { + newInstruction = (InstructionLV) InstructionConstants.INSTRUCTIONS[(baseOpCode-Constants.ISTORE)*4+Constants.ISTORE_0+newIndex]; + } else { + newInstruction = (InstructionLV) InstructionConstants.INSTRUCTIONS[(baseOpCode-Constants.ILOAD)*4+Constants.ILOAD_0+newIndex]; + } + } else { + newInstruction = new InstructionLV((short) baseOpCode, newIndex); + } +// if (getBaseOpcode()!=newInstruction.getBaseOpcode() || newInstruction.getIndex()!=newIndex) { +// throw new RuntimeException("New Instruction created does not appear to be valid: originalBaseOpcode="+getBaseOpcode()+" newBaseOpcode="+newInstruction.getBaseOpcode()); +// } + return newInstruction; + } + } + public int getLength() { int size=Constants.iLen[opcode]; if (lvar==-1) { -- 2.39.5