From: aclement Date: Tue, 21 Feb 2006 10:49:15 +0000 (+0000) Subject: optimization: use tags not gens. improves memory (create less garbage), faster ... X-Git-Tag: POST_MEMORY_CHANGES~58 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=3b4d09438dd366cf4bb90c9d19cc8134853a347d;p=aspectj.git optimization: use tags not gens. improves memory (create less garbage), faster (dont need to transform the garbage): see pr128650, optimization #6. --- 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 M. Dahm * @author Patrick C. Beard [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()= 0; i--) { + InstructionTargeter targeter = targeters[i]; + if (targeter instanceof LineNumberTag) { + lr = (LineNumberTag) targeter; + skip=true; + } + } + } + if (lr != null && !skip) { + ih.addTargeter(lr); + } + } + } + private void unpackLocals(MethodGen gen) { Set locals = new HashSet(); for (InstructionHandle ih = body.getStart(); ih != null; ih = ih.getNext()) { @@ -373,7 +443,7 @@ public final class LazyMethodGen { InstructionTargeter targeter = targeters[i]; if (targeter instanceof LocalVariableGen) { LocalVariableGen lng = (LocalVariableGen) targeter; - LocalVariableTag lr = new LocalVariableTag(BcelWorld.fromBcel(lng.getType()), lng.getName(), lng.getIndex(), lng.getStart().getPosition()); + LocalVariableTag lr = new LocalVariableTag(lng.getType().getSignature()/*BcelWorld.fromBcel(lng.getType())*/, lng.getName(), lng.getIndex(), lng.getStart().getPosition()); if (lng.getStart() == ih) { locals.add(lr); } else { @@ -1006,9 +1076,13 @@ public final class LazyMethodGen { continue; } slots.add(new Integer(tag.getSlot())); - - gen.addLocalVariable(tag.getName(), - BcelWorld.makeBcelType(tag.getType()), + Type t = tag.getRealType(); + if (t==null) { + t = BcelWorld.makeBcelType(UnresolvedType.forSignature(tag.getType())); + } + gen.addLocalVariable( + tag.getName(), + t, tag.getSlot(),(InstructionHandle) start,(InstructionHandle) lvpos.end); } } diff --git a/weaver/src/org/aspectj/weaver/bcel/LineNumberTag.java b/weaver/src/org/aspectj/weaver/bcel/LineNumberTag.java deleted file mode 100644 index 9dc5b8a15..000000000 --- a/weaver/src/org/aspectj/weaver/bcel/LineNumberTag.java +++ /dev/null @@ -1,39 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). - * 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 - * ******************************************************************/ - - -package org.aspectj.weaver.bcel; - -/** 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/weaver/src/org/aspectj/weaver/bcel/LocalVariableTag.java b/weaver/src/org/aspectj/weaver/bcel/LocalVariableTag.java deleted file mode 100644 index 14bb30acf..000000000 --- a/weaver/src/org/aspectj/weaver/bcel/LocalVariableTag.java +++ /dev/null @@ -1,73 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). - * 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 - * ******************************************************************/ - - -package org.aspectj.weaver.bcel; - -import org.aspectj.weaver.UnresolvedType; - -public final class LocalVariableTag extends Tag { - private final UnresolvedType type; - 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(UnresolvedType type, String name, int slot, int startPosition) { - this.type = type; - this.name = name; - this.slot = slot; - this.startPos = startPosition; - } - - public String getName() { - return name; - } - public int getSlot() { - return slot; - } - public UnresolvedType getType() { - 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 + ": " + type + " " + name; - } - public boolean equals(Object other) { - if (!(other instanceof LocalVariableTag)) return false; - LocalVariableTag o = (LocalVariableTag)other; - return o.type.equals(type) && o.name.equals(name) && o.slot == slot && o.startPos == startPos; - } - private volatile int hashCode = 0; - public int hashCode() { - if (hashCode == 0) { - int ret = 17; - ret = 37*ret + type.hashCode(); - ret = 37*ret + name.hashCode(); - ret = 37*ret + slot; - ret = 37*ret + startPos; - hashCode = ret; - } - return hashCode; - } -} diff --git a/weaver/src/org/aspectj/weaver/bcel/Range.java b/weaver/src/org/aspectj/weaver/bcel/Range.java index 60702912b..f32335dd4 100644 --- a/weaver/src/org/aspectj/weaver/bcel/Range.java +++ b/weaver/src/org/aspectj/weaver/bcel/Range.java @@ -197,6 +197,7 @@ abstract class Range implements InstructionTargeter { // assert isRangeHandle(ih) Range ret = null; InstructionTargeter[] targeters = ih.getTargeters(); + if (targeters!=null) { for (int i = targeters.length - 1; i >= 0; i--) { if (targeters[i] instanceof Range) { Range r = (Range) targeters[i]; @@ -205,7 +206,10 @@ abstract class Range implements InstructionTargeter { ret = (Range) targeters[i]; } } - if (ret == null) throw new BCException("shouldn't happen"); + } + if (ret == null) { + throw new BCException("shouldn't happen"); + } return ret; } diff --git a/weaver/src/org/aspectj/weaver/bcel/ShadowRange.java b/weaver/src/org/aspectj/weaver/bcel/ShadowRange.java index 7632c3e16..cf46cbf68 100644 --- a/weaver/src/org/aspectj/weaver/bcel/ShadowRange.java +++ b/weaver/src/org/aspectj/weaver/bcel/ShadowRange.java @@ -21,6 +21,7 @@ import org.aspectj.apache.bcel.generic.InstructionHandle; import org.aspectj.apache.bcel.generic.InstructionList; import org.aspectj.apache.bcel.generic.InstructionTargeter; import org.aspectj.apache.bcel.generic.LocalVariableInstruction; +import org.aspectj.apache.bcel.generic.LocalVariableTag; import org.aspectj.apache.bcel.generic.RET; import org.aspectj.apache.bcel.generic.Select; import org.aspectj.apache.bcel.generic.TargetLostException; diff --git a/weaver/src/org/aspectj/weaver/bcel/Tag.java b/weaver/src/org/aspectj/weaver/bcel/Tag.java deleted file mode 100644 index 427fc3f94..000000000 --- a/weaver/src/org/aspectj/weaver/bcel/Tag.java +++ /dev/null @@ -1,43 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). - * 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 - * ******************************************************************/ - - -package org.aspectj.weaver.bcel; - -import org.aspectj.apache.bcel.generic.InstructionHandle; -import org.aspectj.apache.bcel.generic.InstructionTargeter; - -/** A tag is an instruction-targeter that doesn't bother remembering its target(s) */ -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"); - } - } -} diff --git a/weaver/src/org/aspectj/weaver/bcel/Utility.java b/weaver/src/org/aspectj/weaver/bcel/Utility.java index 7eec5ef41..79571fcf7 100644 --- a/weaver/src/org/aspectj/weaver/bcel/Utility.java +++ b/weaver/src/org/aspectj/weaver/bcel/Utility.java @@ -44,6 +44,7 @@ import org.aspectj.apache.bcel.generic.InstructionHandle; import org.aspectj.apache.bcel.generic.InstructionList; import org.aspectj.apache.bcel.generic.InstructionTargeter; import org.aspectj.apache.bcel.generic.LDC; +import org.aspectj.apache.bcel.generic.LineNumberTag; import org.aspectj.apache.bcel.generic.ObjectType; import org.aspectj.apache.bcel.generic.ReferenceType; import org.aspectj.apache.bcel.generic.SIPUSH; @@ -655,9 +656,8 @@ public class Utility { // } // return getSourceLine(ih.getNext()); // } - - public static int getSourceLine(InstructionHandle ih) { + public static int getSourceLine(InstructionHandle ih) {//,boolean goforwards) { int lookahead=0; // arbitrary rule that we will never lookahead more than 100 instructions for a line # while (lookahead++ < 100) { @@ -672,11 +672,16 @@ public class Utility { } } } - ih = ih.getNext(); +// if (goforwards) ih=ih.getNext(); else + ih=ih.getPrev(); } //System.err.println("no line information available for: " + ih); return -1; } + +// public static int getSourceLine(InstructionHandle ih) { +// return getSourceLine(ih,false); +// } // assumes that there is no already extant source line tag. Otherwise we'll have to be better. public static void setSourceLine(InstructionHandle ih, int lineNumber) {