]> source.dussan.org Git - aspectj.git/commitdiff
more overweaving tests and fixes
authoraclement <aclement>
Wed, 12 May 2010 20:19:44 +0000 (20:19 +0000)
committeraclement <aclement>
Wed, 12 May 2010 20:19:44 +0000 (20:19 +0000)
weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java
weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java
weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java

index 76c9dd30001374d05b72a96e80ea0c5bd48fb968..895bcfa9b144622f9de6bbe61e3de76f8621ac8e 100644 (file)
@@ -111,6 +111,9 @@ class BcelClassWeaver implements IClassWeaver {
        private final List<ConcreteTypeMunger> typeMungers;
        private final List lateTypeMungers;
 
+       private List<ShadowMunger>[] indexedShadowMungers;
+       private boolean canMatchBodyShadows = false;
+
        private final BcelObjectType ty; // alias of clazz.getType()
        private final BcelWorld world; // alias of ty.getWorld()
        private final ConstantPool cpg; // alias of clazz.getConstantPoolGen()
@@ -139,7 +142,6 @@ class BcelClassWeaver implements IClassWeaver {
        private BcelClassWeaver(BcelWorld world, LazyClassGen clazz, List<ShadowMunger> shadowMungers,
                        List<ConcreteTypeMunger> typeMungers, List lateTypeMungers) {
                super();
-               // assert world == clazz.getType().getWorld()
                this.world = world;
                this.clazz = clazz;
                this.shadowMungers = shadowMungers;
@@ -149,7 +151,7 @@ class BcelClassWeaver implements IClassWeaver {
                this.cpg = clazz.getConstantPool();
                this.fact = clazz.getFactory();
 
-               fastMatchShadowMungers(shadowMungers);
+               indexShadowMungers();
 
                initializeSuperInitializerMap(ty.getResolvedTypeX());
                if (!checkedXsetForLowLevelContextCapturing) {
@@ -167,50 +169,8 @@ class BcelClassWeaver implements IClassWeaver {
                }
        }
 
-       private List<ShadowMunger>[] perKindShadowMungers;
-       private boolean canMatchBodyShadows = false;
-
-       // private boolean canMatchInitialization = false;
-       private void fastMatchShadowMungers(List<ShadowMunger> shadowMungers) {
-               // beware the annoying property that SHADOW_KINDS[i].getKey == (i+1) !
-
-               perKindShadowMungers = new List[Shadow.MAX_SHADOW_KIND + 1];
-               for (int i = 0; i < perKindShadowMungers.length; i++) {
-                       perKindShadowMungers[i] = new ArrayList<ShadowMunger>(0);
-               }
-               for (ShadowMunger munger : shadowMungers) {
-                       int couldMatchKinds = munger.getPointcut().couldMatchKinds();
-                       for (int i = 0; i < Shadow.SHADOW_KINDS.length; i++) {
-                               Shadow.Kind kind = Shadow.SHADOW_KINDS[i];
-                               if (kind.isSet(couldMatchKinds)) {
-                                       perKindShadowMungers[kind.getKey()].add(munger);
-                               }
-                       }
-
-                       // Set couldMatchKinds = munger.getPointcut().couldMatchKinds();
-                       // for (Iterator kindIterator = couldMatchKinds.iterator();
-                       // kindIterator.hasNext();) {
-                       // Shadow.Kind aKind = (Shadow.Kind) kindIterator.next();
-                       // perKindShadowMungers[aKind.getKey()].add(munger);
-                       // }
-               }
-
-               // if (!perKindShadowMungers[Shadow.Initialization.getKey()].isEmpty())
-               // canMatchInitialization = true;
-
-               for (int i = 0; i < Shadow.SHADOW_KINDS.length; i++) {
-                       Shadow.Kind kind = Shadow.SHADOW_KINDS[i];
-                       if (!kind.isEnclosingKind() && !perKindShadowMungers[i + 1].isEmpty()) {
-                               canMatchBodyShadows = true;
-                       }
-                       if (perKindShadowMungers[i + 1].isEmpty()) {
-                               perKindShadowMungers[i + 1] = null;
-                       }
-               }
-       }
-
        private boolean canMatch(Shadow.Kind kind) {
-               return perKindShadowMungers[kind.getKey()] != null;
+               return indexedShadowMungers[kind.getKey()] != null;
        }
 
        // private void fastMatchShadowMungers(List shadowMungers, ArrayList
@@ -236,6 +196,30 @@ class BcelClassWeaver implements IClassWeaver {
                }
        }
 
+       /**
+        * Process the shadow mungers into array 'buckets', each bucket represents a shadow kind and contains a list of shadowmungers
+        * that could potentially apply at that shadow kind.
+        */
+       private void indexShadowMungers() {
+               // beware the annoying property that SHADOW_KINDS[i].getKey == (i+1) !
+               indexedShadowMungers = new List[Shadow.MAX_SHADOW_KIND + 1];
+               for (ShadowMunger shadowMunger : shadowMungers) {
+                       int couldMatchKinds = shadowMunger.getPointcut().couldMatchKinds();
+                       for (Shadow.Kind kind : Shadow.SHADOW_KINDS) {
+                               if (kind.isSet(couldMatchKinds)) {
+                                       byte k = kind.getKey();
+                                       if (indexedShadowMungers[k] == null) {
+                                               indexedShadowMungers[k] = new ArrayList<ShadowMunger>();
+                                               if (!kind.isEnclosingKind()) {
+                                                       canMatchBodyShadows = true;
+                                               }
+                                       }
+                                       indexedShadowMungers[k].add(shadowMunger);
+                               }
+                       }
+               }
+       }
+
        private boolean addSuperInitializer(ResolvedType onType) {
                if (onType.isRawType() || onType.isParameterizedType()) {
                        onType = onType.getGenericType();
@@ -2105,7 +2089,7 @@ class BcelClassWeaver implements IClassWeaver {
         * 
         * @param donor the method from which we will copy (and adjust frame and jumps) instructions.
         * @param recipient the method the instructions will go into. Used to get the frame size so we can allocate new frame locations
-        *            for locals in donor.
+        *        for locals in donor.
         * @param frameEnv an environment to map from donor frame to recipient frame, initially populated with argument locations.
         * @param fact an instruction factory for recipient
         */
@@ -3072,7 +3056,7 @@ class BcelClassWeaver implements IClassWeaver {
                        boolean isMatched = false;
 
                        Shadow.Kind shadowKind = shadow.getKind();
-                       List<ShadowMunger> candidateMungers = perKindShadowMungers[shadowKind.getKey()];
+                       List<ShadowMunger> candidateMungers = indexedShadowMungers[shadowKind.getKey()];
 
                        // System.out.println("Candidates " + candidateMungers);
                        if (candidateMungers != null) {
@@ -3100,7 +3084,7 @@ class BcelClassWeaver implements IClassWeaver {
                        boolean isMatched = false;
 
                        Shadow.Kind shadowKind = shadow.getKind();
-                       List<ShadowMunger> candidateMungers = perKindShadowMungers[shadowKind.getKey()];
+                       List<ShadowMunger> candidateMungers = indexedShadowMungers[shadowKind.getKey()];
 
                        // System.out.println("Candidates at " + shadowKind + " are " + candidateMungers);
                        if (candidateMungers != null) {
@@ -3150,10 +3134,6 @@ class BcelClassWeaver implements IClassWeaver {
                return clazz;
        }
 
-       public List<ShadowMunger> getShadowMungers() {
-               return shadowMungers;
-       }
-
        public BcelWorld getWorld() {
                return world;
        }
index c68a37a4efc6459ca28573a24c4db3b4ccfe4a04..861082fd118e8bc476f9485516dba1ad317d9534 100644 (file)
@@ -63,7 +63,6 @@ import org.aspectj.weaver.UnresolvedType;
 import org.aspectj.weaver.WeaverMessages;
 import org.aspectj.weaver.WeaverStateInfo;
 import org.aspectj.weaver.World;
-import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
 import org.aspectj.weaver.model.AsmRelationshipProvider;
 import org.aspectj.weaver.patterns.DeclareAnnotation;
 import org.aspectj.weaver.patterns.Pointcut;
@@ -89,6 +88,13 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
                boolean changed = false;
                boolean worthReporting = true;
 
+               if (weaver.getWorld().isOverWeaving()) {
+                       WeaverStateInfo typeWeaverState = weaver.getLazyClassGen().getType().getWeaverState();
+                       if (typeWeaverState != null && typeWeaverState.isAspectAlreadyApplied(getAspectType())) {
+                               return false;
+                       }
+               }
+
                if (munger.getKind() == ResolvedTypeMunger.Field) {
                        changed = mungeNewField(weaver, (NewFieldTypeMunger) munger);
                } else if (munger.getKind() == ResolvedTypeMunger.Method) {
index 04dcb35f39272c3d91819edf2298aa8d32c23789..fff7bcba503cc76863f0f018c612155c4d6f0148 100644 (file)
@@ -1865,7 +1865,7 @@ public class BcelWeaver {
                                        getWorld().getMessageHandler().handleMessage(new Message(messageText, IMessage.ABORT, re, null));
                                }
                        } else {
-                                checkDeclareTypeErrorOrWarning(world, classType);
+                               checkDeclareTypeErrorOrWarning(world, classType);
                        }
                        // this is very odd return behavior trying to keep everyone happy
                        /*
@@ -1955,10 +1955,20 @@ public class BcelWeaver {
                zipOutputStream.closeEntry();
        }
 
+       /**
+        * Perform a fast match of the specified list of shadowmungers against the specified type. A subset of those that might match is
+        * returned.
+        * 
+        * @param list list of all shadow mungers that might match
+        * @param type the target type
+        * @return a list of shadow mungers that might match with those that cannot (according to fast match rules) removed
+        */
        private List<ShadowMunger> fastMatch(List<ShadowMunger> list, ResolvedType type) {
                if (list == null) {
                        return Collections.emptyList();
                }
+               boolean isOverweaving = world.isOverWeaving();
+               WeaverStateInfo typeWeaverState = (isOverweaving ? type.getWeaverState() : null);
 
                // here we do the coarsest grained fast match with no kind constraints
                // this will remove all obvious non-matches and see if we need to do any
@@ -1969,6 +1979,12 @@ public class BcelWeaver {
 
                if (world.areInfoMessagesEnabled() && world.isTimingEnabled()) {
                        for (ShadowMunger munger : list) {
+                               if (typeWeaverState != null) { // will only be null if overweaving is ON and there is weaverstate
+                                       ResolvedType declaringAspect = munger.getDeclaringType();
+                                       if (typeWeaverState.isAspectAlreadyApplied(declaringAspect)) {
+                                               continue;
+                                       }
+                               }
                                Pointcut pointcut = munger.getPointcut();
                                long starttime = System.nanoTime();
                                FuzzyBoolean fb = pointcut.fastMatch(info);
@@ -1980,6 +1996,12 @@ public class BcelWeaver {
                        }
                } else {
                        for (ShadowMunger munger : list) {
+                               if (typeWeaverState != null) { // will only be null if overweaving is ON and there is weaverstate
+                                       ResolvedType declaringAspect = munger.getDeclaringType();
+                                       if (typeWeaverState.isAspectAlreadyApplied(declaringAspect)) {
+                                               continue;
+                                       }
+                               }
                                Pointcut pointcut = munger.getPointcut();
                                FuzzyBoolean fb = pointcut.fastMatch(info);
                                if (fb.maybeTrue()) {