aboutsummaryrefslogtreecommitdiffstats
path: root/bcel-builder
diff options
context:
space:
mode:
authoraclement <aclement>2006-02-21 10:49:15 +0000
committeraclement <aclement>2006-02-21 10:49:15 +0000
commit3b4d09438dd366cf4bb90c9d19cc8134853a347d (patch)
tree7c3dc1ed2130409eeb4b1ffb966a0d9f524126f0 /bcel-builder
parentbf5612533611857b24a90ba8ef19fe4023329b6e (diff)
downloadaspectj-3b4d09438dd366cf4bb90c9d19cc8134853a347d.tar.gz
aspectj-3b4d09438dd366cf4bb90c9d19cc8134853a347d.zip
optimization: use tags not gens. improves memory (create less garbage), faster (dont need to transform the garbage): see pr128650, optimization #6.
Diffstat (limited to 'bcel-builder')
-rw-r--r--bcel-builder/src/org/aspectj/apache/bcel/generic/LineNumberTag.java40
-rw-r--r--bcel-builder/src/org/aspectj/apache/bcel/generic/LocalVariableTag.java79
-rw-r--r--bcel-builder/src/org/aspectj/apache/bcel/generic/MethodGen.java85
-rw-r--r--bcel-builder/src/org/aspectj/apache/bcel/generic/Tag.java42
4 files changed, 224 insertions, 22 deletions
diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/LineNumberTag.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/LineNumberTag.java
new file mode 100644
index 000000000..b8136de35
--- /dev/null
+++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/LineNumberTag.java
@@ -0,0 +1,40 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Contributors
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * PARC initial implementation
+ * Andy Clement pushed down into bcel module
+ * ******************************************************************/
+
+
+package org.aspectj.apache.bcel.generic;
+
+/** we don't actually target instructions, but instructions target us. */
+public class LineNumberTag extends Tag {
+
+ private final int lineNumber;
+
+ public LineNumberTag(int lineNumber) {
+ this.lineNumber = lineNumber;
+ }
+
+ public int getLineNumber() { return lineNumber; }
+
+ // ---- from Object
+
+ public String toString() {
+ return "line " + lineNumber;
+ }
+ public boolean equals(Object other) {
+ if (! (other instanceof LineNumberTag)) return false;
+ return lineNumber == ((LineNumberTag)other).lineNumber;
+ }
+ public int hashCode() {
+ return lineNumber;
+ }
+}
diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/LocalVariableTag.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/LocalVariableTag.java
new file mode 100644
index 000000000..53d43c462
--- /dev/null
+++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/LocalVariableTag.java
@@ -0,0 +1,79 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Contributors
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * PARC initial implementation
+ * Andy Clement pushed down into bcel module
+ * ******************************************************************/
+
+
+package org.aspectj.apache.bcel.generic;
+
+public final class LocalVariableTag extends Tag {
+ private Type type; // not always known, in which case signature has to be used
+ private final String signature;
+ private final String name;
+ private int slot;
+ private final int startPos;
+ boolean remapped = false;
+
+ // AMC - pr101047, two local vars with the same name can share the same slot, but must in that case
+ // have different start positions.
+ public LocalVariableTag(String sig, String name, int slot, int startPosition) {
+ this.signature = sig;
+ this.name = name;
+ this.slot = slot;
+ this.startPos = startPosition;
+ }
+
+ public LocalVariableTag(Type t,String sig, String name, int slot, int startPosition) {
+ this.type = t;
+ this.signature = sig;
+ this.name = name;
+ this.slot = slot;
+ this.startPos = startPosition;
+ }
+
+
+ public String getName() {return name;}
+ public int getSlot() {return slot;}
+ public String getType() {return signature;}
+ public Type getRealType() {return type;}
+
+ public void updateSlot(int newSlot) {
+ this.slot = newSlot;
+ this.remapped = true;
+ }
+
+ public boolean isRemapped() { return this.remapped; }
+
+ // ---- from Object
+
+ public String toString() {
+ return "local " + slot + ": " + signature + " " + name;
+ }
+
+ public boolean equals(Object other) {
+ if (!(other instanceof LocalVariableTag)) return false;
+ LocalVariableTag o = (LocalVariableTag)other;
+ return o.slot == slot && o.startPos == startPos && o.signature.equals(signature) && o.name.equals(name);
+ }
+
+ private int hashCode = 0;
+ public int hashCode() {
+ if (hashCode == 0) {
+ int ret = 17;
+ ret = 37*ret + signature.hashCode();
+ ret = 37*ret + name.hashCode();
+ ret = 37*ret + slot;
+ ret = 37*ret + startPos;
+ hashCode = ret;
+ }
+ return hashCode;
+ }
+}
diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/MethodGen.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/MethodGen.java
index 96b2b0f90..e414b94e7 100644
--- a/bcel-builder/src/org/aspectj/apache/bcel/generic/MethodGen.java
+++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/MethodGen.java
@@ -86,7 +86,7 @@ import org.aspectj.apache.bcel.generic.annotation.AnnotationGen;
* use the `removeNOPs' method to get rid off them.
* The resulting method object can be obtained via the `getMethod()' method.
*
- * @version $Id: MethodGen.java,v 1.6 2006/02/14 13:32:07 aclement Exp $
+ * @version $Id: MethodGen.java,v 1.7 2006/02/21 10:49:15 aclement Exp $
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @author <A HREF="http://www.vmeng.com/beard">Patrick C. Beard</A> [setMaxStack()]
* @see InstructionList
@@ -100,6 +100,7 @@ public class MethodGen extends FieldGenOrMethodGen {
private int max_stack;
private InstructionList il;
private boolean strip_attributes;
+ private int highestLineNumber = 0;
private ArrayList variable_vec = new ArrayList();
private ArrayList line_number_vec = new ArrayList();
@@ -188,6 +189,8 @@ public class MethodGen extends FieldGenOrMethodGen {
}
}
}
+
+ public int getHighestlinenumber() { return highestLineNumber; }
/**
* Instantiate from existing method.
@@ -198,6 +201,10 @@ public class MethodGen extends FieldGenOrMethodGen {
*/
public MethodGen(Method m, String class_name, ConstantPoolGen cp) {
+ this(m,class_name,cp,false);
+ }
+
+ public MethodGen(Method m, String class_name, ConstantPoolGen cp,boolean useTags) {
this(
m.getAccessFlags(),
@@ -261,29 +268,63 @@ public class MethodGen extends FieldGenOrMethodGen {
if (a instanceof LineNumberTable) {
LineNumber[] ln = ((LineNumberTable) a).getLineNumberTable();
-
- for (int k = 0; k < ln.length; k++) {
- LineNumber l = ln[k];
- addLineNumber(il.findHandle(l.getStartPC(),arrayOfInstructions),
- l.getLineNumber());
+ if (useTags) {
+ // abracadabra, lets create tags rather than linenumbergens.
+ for (int k = 0; k < ln.length; k++) {
+ LineNumber l = ln[k];
+ int lnum = l.getLineNumber();
+ if (lnum>highestLineNumber) highestLineNumber=lnum;
+ LineNumberTag lt = new LineNumberTag(lnum);
+ il.findHandle(l.getStartPC(),arrayOfInstructions).addTargeter(lt);
+ }
+ } else {
+ for (int k = 0; k < ln.length; k++) {
+ LineNumber l = ln[k];
+ addLineNumber(il.findHandle(l.getStartPC(),arrayOfInstructions),
+ l.getLineNumber());
+ }
}
} else if (a instanceof LocalVariableTable) {
- LocalVariable[] lv = ((LocalVariableTable) a).getLocalVariableTable();
-
- removeLocalVariables();
-
- for (int k = 0; k < lv.length; k++) {
- LocalVariable l = lv[k];
- InstructionHandle start = il.findHandle(l.getStartPC(), arrayOfInstructions);
- InstructionHandle end = il.findHandle(l.getStartPC() + l.getLength(), arrayOfInstructions);
- // AMC, this actually gives us the first instruction AFTER the range,
- // so move back one... (findHandle can't cope with mid-instruction indices)
- if (end != null) end = end.getPrev();
- // Repair malformed handles
- if (null == start) start = il.getStart();
- if (null == end) end = il.getEnd();
-
- addLocalVariable(l.getName(), Type.getType(l.getSignature()), l.getIndex(), start, end);
+
+ // Lets have a go at creating Tags directly
+ if (useTags) {
+ LocalVariable[] lv = ((LocalVariableTable) a).getLocalVariableTable();
+
+ for (int k = 0; k < lv.length; k++) {
+ LocalVariable l = lv[k];
+ Type t = Type.getType(l.getSignature());
+ LocalVariableTag lvt = new LocalVariableTag(t,l.getSignature(),l.getName(),l.getIndex(),l.getStartPC());
+ InstructionHandle start = il.findHandle(l.getStartPC(), arrayOfInstructions);
+ byte b = t.getType();
+ if (b!= Constants.T_ADDRESS) {
+ int increment = t.getSize();
+ if (l.getIndex()+increment>max_locals) max_locals = l.getIndex()+increment;
+ }
+ int end = l.getStartPC()+l.getLength();
+ do {
+ start.addTargeter(lvt);
+ start = start.getNext();
+ } while (start!=null && start.getPosition()<end);
+ }
+ } else {
+
+ LocalVariable[] lv = ((LocalVariableTable) a).getLocalVariableTable();
+
+ removeLocalVariables();
+
+ for (int k = 0; k < lv.length; k++) {
+ LocalVariable l = lv[k];
+ InstructionHandle start = il.findHandle(l.getStartPC(), arrayOfInstructions);
+ InstructionHandle end = il.findHandle(l.getStartPC() + l.getLength(), arrayOfInstructions);
+ // AMC, this actually gives us the first instruction AFTER the range,
+ // so move back one... (findHandle can't cope with mid-instruction indices)
+ if (end != null) end = end.getPrev();
+ // Repair malformed handles
+ if (null == start) start = il.getStart();
+ if (null == end) end = il.getEnd();
+
+ addLocalVariable(l.getName(), Type.getType(l.getSignature()), l.getIndex(), start, end);
+ }
}
} else addCodeAttribute(a);
}
diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/Tag.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/Tag.java
new file mode 100644
index 000000000..2cb5f9ddc
--- /dev/null
+++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/Tag.java
@@ -0,0 +1,42 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Contributors
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * PARC initial implementation
+ * Andy Clement pushed down into bcel module
+ * ******************************************************************/
+
+
+package org.aspectj.apache.bcel.generic;
+
+
+/** A tag is an instruction-targeter that doesn't bother remembering its target(s) */
+public abstract class Tag implements InstructionTargeter, Cloneable {
+
+ public Tag() {
+ }
+
+ // ---- from InstructionTargeter
+ public boolean containsTarget(InstructionHandle ih) {
+ return false;
+ }
+
+ public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) {
+ old_ih.removeTargeter(this);
+ if (new_ih != null)
+ new_ih.addTargeter(this);
+ }
+
+ public Tag copy() {
+ try {
+ return (Tag)clone();
+ } catch (CloneNotSupportedException e) {
+ throw new RuntimeException("Sanity check, can't clone me");
+ }
+ }
+}