From e4e47c617dcb9e4aed78ed25b586b7806222f3c2 Mon Sep 17 00:00:00 2001 From: aclement Date: Wed, 12 May 2010 20:19:44 +0000 Subject: [PATCH] more overweaving tests and fixes --- .../aspectj/weaver/bcel/BcelClassWeaver.java | 84 +++++++------------ .../aspectj/weaver/bcel/BcelTypeMunger.java | 8 +- .../org/aspectj/weaver/bcel/BcelWeaver.java | 24 +++++- 3 files changed, 62 insertions(+), 54 deletions(-) diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java b/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java index 76c9dd300..895bcfa9b 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java @@ -111,6 +111,9 @@ class BcelClassWeaver implements IClassWeaver { private final List typeMungers; private final List lateTypeMungers; + private List[] 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 shadowMungers, List 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[] perKindShadowMungers; - private boolean canMatchBodyShadows = false; - - // private boolean canMatchInitialization = false; - private void fastMatchShadowMungers(List 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(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(); + 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 candidateMungers = perKindShadowMungers[shadowKind.getKey()]; + List 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 candidateMungers = perKindShadowMungers[shadowKind.getKey()]; + List 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 getShadowMungers() { - return shadowMungers; - } - public BcelWorld getWorld() { return world; } diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java b/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java index c68a37a4e..861082fd1 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java @@ -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) { diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java index 04dcb35f3..fff7bcba5 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java @@ -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 fastMatch(List 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()) { -- 2.39.5