]> source.dussan.org Git - aspectj.git/commitdiff
optimization: use tags not gens. improves memory (create less garbage), faster ...
authoraclement <aclement>
Tue, 21 Feb 2006 10:49:15 +0000 (10:49 +0000)
committeraclement <aclement>
Tue, 21 Feb 2006 10:49:15 +0000 (10:49 +0000)
15 files changed:
bcel-builder/src/org/aspectj/apache/bcel/generic/LineNumberTag.java [new file with mode: 0644]
bcel-builder/src/org/aspectj/apache/bcel/generic/LocalVariableTag.java [new file with mode: 0644]
bcel-builder/src/org/aspectj/apache/bcel/generic/MethodGen.java
bcel-builder/src/org/aspectj/apache/bcel/generic/Tag.java [new file with mode: 0644]
lib/bcel/bcel-src.zip
lib/bcel/bcel.jar
weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java
weaver/src/org/aspectj/weaver/bcel/BcelShadow.java
weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java
weaver/src/org/aspectj/weaver/bcel/LineNumberTag.java [deleted file]
weaver/src/org/aspectj/weaver/bcel/LocalVariableTag.java [deleted file]
weaver/src/org/aspectj/weaver/bcel/Range.java
weaver/src/org/aspectj/weaver/bcel/ShadowRange.java
weaver/src/org/aspectj/weaver/bcel/Tag.java [deleted file]
weaver/src/org/aspectj/weaver/bcel/Utility.java

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 (file)
index 0000000..b8136de
--- /dev/null
@@ -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 (file)
index 0000000..53d43c4
--- /dev/null
@@ -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;
+    }
+}
index 96b2b0f907be44679ac75e1310d5b83431fef66c..e414b94e7335a8b52aa1adc7dd45dbfa2475c4de 100644 (file)
@@ -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 (file)
index 0000000..2cb5f9d
--- /dev/null
@@ -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");
+       }
+    }
+}
index 162657a4e01c1a3f7f9002d614973c9691011565..1376af6d76b47a3d4dbeecde15132c5aa6f4ccee 100644 (file)
Binary files a/lib/bcel/bcel-src.zip and b/lib/bcel/bcel-src.zip differ
index 709d6194d166ccc2060f5c215b89b92fcb86e2cc..87bf5b75bf5bb31ae5a4b61794da5b715c65a489 100644 (file)
Binary files a/lib/bcel/bcel.jar and b/lib/bcel/bcel.jar differ
index d080ec18fded371fdbf7c20ef2dca79919a84e0c..527e7369bdce35ed50dbe4bf1972d8189a5863fe 100644 (file)
@@ -55,6 +55,7 @@ import org.aspectj.apache.bcel.generic.PUTSTATIC;
 import org.aspectj.apache.bcel.generic.RET;
 import org.aspectj.apache.bcel.generic.ReturnInstruction;
 import org.aspectj.apache.bcel.generic.Select;
+import org.aspectj.apache.bcel.generic.Tag;
 import org.aspectj.apache.bcel.generic.Type;
 import org.aspectj.apache.bcel.generic.annotation.AnnotationGen;
 import org.aspectj.bridge.IMessage;
@@ -769,7 +770,7 @@ class BcelClassWeaver implements IClassWeaver {
                                Annotation a = decaM.getAnnotationX().getBcelAnnotation();
                                AnnotationGen ag = new AnnotationGen(a,clazz.getConstantPoolGen(),true);
                                Method oldMethod = mg.getMethod();
-                               MethodGen myGen = new MethodGen(oldMethod,clazz.getClassName(),clazz.getConstantPoolGen());
+                               MethodGen myGen = new MethodGen(oldMethod,clazz.getClassName(),clazz.getConstantPoolGen(),false);// dont use tags, they won't get repaired like for woven methods.
                                myGen.addAnnotation(ag);
                                Method newMethod = myGen.getMethod();
                                mg.addAnnotation(decaM.getAnnotationX());
index a5dd6091065bc1e62f58577757e1635d09983aed..b6b6611548b32a6b364fc0712a316df61c71c33f 100644 (file)
@@ -43,6 +43,7 @@ import org.aspectj.apache.bcel.generic.InstructionList;
 import org.aspectj.apache.bcel.generic.InstructionTargeter;
 import org.aspectj.apache.bcel.generic.InvokeInstruction;
 import org.aspectj.apache.bcel.generic.LoadInstruction;
+import org.aspectj.apache.bcel.generic.LocalVariableTag;
 import org.aspectj.apache.bcel.generic.MULTIANEWARRAY;
 import org.aspectj.apache.bcel.generic.NEW;
 import org.aspectj.apache.bcel.generic.ObjectType;
@@ -1344,12 +1345,13 @@ public class BcelShadow extends Shadow {
      */
     public UnresolvedType ensureTargetTypeIsCorrect(UnresolvedType tx) {
        
-       
-       if (tx.equals(ResolvedType.OBJECT) && getKind() == MethodCall && 
-           getSignature().getReturnType().equals(ResolvedType.OBJECT) && 
-                       getSignature().getArity()==0 && 
-                       getSignature().getName().charAt(0) == 'c' &&
-                       getSignature().getName().equals("clone")) {
+       Member msig = getSignature();
+       if (msig.getArity()==0 && 
+               getKind() == MethodCall && 
+               msig.getName().charAt(0) == 'c' &&
+               tx.equals(ResolvedType.OBJECT) && 
+               msig.getReturnType().equals(ResolvedType.OBJECT) && 
+                       msig.getName().equals("clone")) {
                
                // Lets go back through the code from the start of the shadow
             InstructionHandle searchPtr = range.getStart().getPrev();
@@ -1363,7 +1365,7 @@ public class BcelShadow extends Shadow {
                LoadInstruction li = (LoadInstruction)searchPtr.getInstruction();
                li.getIndex();
                LocalVariableTag lvt = LazyMethodGen.getLocalVariableTag(searchPtr,li.getIndex());
-               if (lvt!=null)  return lvt.getType();
+               if (lvt!=null)  return UnresolvedType.forSignature(lvt.getType());
             }
             // A field access instruction may tell us the real type of what the clone() call is on
             if (searchPtr.getInstruction() instanceof FieldInstruction) {
index 809d41225041e25e1a8b4e7f59c6055359c3f292..043537de1cc169dabd0b90f5f9fbf76d27df59d0 100644 (file)
@@ -24,6 +24,7 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.ListIterator;
 import java.util.Map;
+import java.util.Properties;
 import java.util.Set;
 import java.util.Stack;
 
@@ -44,15 +45,19 @@ 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.LineNumberGen;
+import org.aspectj.apache.bcel.generic.LineNumberTag;
 import org.aspectj.apache.bcel.generic.LocalVariableGen;
 import org.aspectj.apache.bcel.generic.LocalVariableInstruction;
+import org.aspectj.apache.bcel.generic.LocalVariableTag;
 import org.aspectj.apache.bcel.generic.MethodGen;
 import org.aspectj.apache.bcel.generic.ObjectType;
 import org.aspectj.apache.bcel.generic.Select;
+import org.aspectj.apache.bcel.generic.Tag;
 import org.aspectj.apache.bcel.generic.Type;
 import org.aspectj.apache.bcel.generic.annotation.AnnotationGen;
 import org.aspectj.bridge.IMessage;
 import org.aspectj.bridge.ISourceLocation;
+import org.aspectj.bridge.MessageUtil;
 import org.aspectj.weaver.AjAttribute;
 import org.aspectj.weaver.AnnotationX;
 import org.aspectj.weaver.BCException;
@@ -94,6 +99,27 @@ public final class LazyMethodGen {
     private BcelMethod memberView;
     private AjAttribute.EffectiveSignatureAttribute effectiveSignature;
     int highestLineNumber = 0;
+    
+
+    /*
+     * This option specifies whether we let the BCEL classes create LineNumberGens and LocalVariableGens
+     * or if we make it create LineNumberTags and LocalVariableTags.  Up until 1.5.1 we always created
+     * Gens - then on return from the MethodGen ctor we took them apart, reprocessed them all and 
+     * created Tags. (see unpackLocals/unpackLineNumbers).  As we have our own copy of Bcel, why not create
+     * the right thing straightaway?  So setting this to true will call the MethodGen ctor() in such
+     * a way that it creates Tags - removing the need for unpackLocals/unpackLineNumbers - HOWEVER see
+     * the ensureAllLineNumberSetup() method for some other relevant info.
+     * 
+     * Whats the difference between a Tag and a Gen?  A Tag is more lightweight, it doesn't know which
+     * instructions it targets, it relies on the instructions targetting *it* - this reduces the amount
+     * of targeter manipulation we have to do.
+     * 
+     * Because this *could* go wrong - it passes all our tests, but you never know, the option:
+     * -Xset:optimizeWithTags=false
+     * will turn it *OFF*
+     */
+       public static boolean avoidUseOfBcelGenObjects = true;
+       public static boolean checkedXsetOption = false;
 
        /** This is nonnull if this method is the result of an "inlining".  We currently
         * copy methods into other classes for around advice.  We add this field so
@@ -248,9 +274,20 @@ public final class LazyMethodGen {
     private void initialize() {
        if (returnType != null) return; 
        
+       // Check whether we need to configure the optimization
+       if (!checkedXsetOption) {
+               Properties p = enclosingClass.getWorld().getExtraConfiguration();
+               if (p!=null) {
+                       avoidUseOfBcelGenObjects = Boolean.parseBoolean(p.getProperty("optimizeWithTags","true"));
+                       if (!avoidUseOfBcelGenObjects) 
+                               enclosingClass.getWorld().getMessageHandler().handleMessage(MessageUtil.info("[optimizeWithTags=false] Disabling optimization to use Tags rather than Gens"));
+               }
+               checkedXsetOption=true;
+        }
+       
        //System.err.println("initializing: " + getName() + ", " + enclosingClass.getName() + ", " + returnType + ", " + savedMethod);
        
-               MethodGen gen = new MethodGen(savedMethod, enclosingClass.getName(), enclosingClass.getConstantPoolGen());
+               MethodGen gen = new MethodGen(savedMethod, enclosingClass.getName(), enclosingClass.getConstantPoolGen(),avoidUseOfBcelGenObjects);
         
                this.returnType = gen.getReturnType();
                this.argumentTypes = gen.getArgumentTypes();
@@ -273,10 +310,16 @@ public final class LazyMethodGen {
         } else {
                //body = new InstructionList(savedMethod.getCode().getCode());
             body = gen.getInstructionList();
-            
+
             unpackHandlers(gen);
-            unpackLineNumbers(gen);
-            unpackLocals(gen);
+            
+                       if (avoidUseOfBcelGenObjects) {
+                               ensureAllLineNumberSetup(gen);
+                           highestLineNumber = gen.getHighestlinenumber();
+                       } else {
+                               unpackLineNumbers(gen);
+                           unpackLocals(gen);
+                       }
         }
         assertGoodBody();
         
@@ -363,6 +406,33 @@ public final class LazyMethodGen {
         gen.removeLineNumbers();
     }
 
+    /**
+     * On entry to this method we have a method whose instruction stream contains a few instructions 
+     * that have line numbers assigned to them (LineNumberTags).  The aim is to ensure every instruction
+     * has the right line number. This is necessary because some of them may be extracted out into other
+     * methods - and it'd be useful for them to maintain the source line number for debugging.
+     */
+    private void ensureAllLineNumberSetup(MethodGen gen) {
+        LineNumberTag lr = null;
+        boolean skip = false;
+        for (InstructionHandle ih = body.getStart(); ih != null; ih = ih.getNext()) {
+            InstructionTargeter[] targeters = ih.getTargeters();
+            skip = false;
+            if (targeters != null) {
+                for (int i = targeters.length - 1; i >= 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 (file)
index 9dc5b8a..0000000
+++ /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 (file)
index 14bb30a..0000000
+++ /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;
-    }
-}
index 60702912b127f2b1c374713fedecb17107e3122f..f32335dd4d168078bcdceba922b20ad5f0683512 100644 (file)
@@ -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;
     }
 
index 7632c3e16ad937e7da0dad9060d4811367b587d8..cf46cbf680625430a9fa4f63b064a86ec23364e2 100644 (file)
@@ -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 (file)
index 427fc3f..0000000
+++ /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");
-       }
-    }
-}
index 7eec5ef41e263d0ba35ab2d964454e3c0218c120..79571fcf772280cc5b28b02d02f7c6ecf48189dd 100644 (file)
@@ -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) {