diff options
author | aclement <aclement> | 2006-02-21 10:49:15 +0000 |
---|---|---|
committer | aclement <aclement> | 2006-02-21 10:49:15 +0000 |
commit | 3b4d09438dd366cf4bb90c9d19cc8134853a347d (patch) | |
tree | 7c3dc1ed2130409eeb4b1ffb966a0d9f524126f0 /bcel-builder | |
parent | bf5612533611857b24a90ba8ef19fe4023329b6e (diff) | |
download | aspectj-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')
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"); + } + } +} |