From d664b267a61c4bad8664d0961e1d55f26404b7d0 Mon Sep 17 00:00:00 2001 From: aclement Date: Sat, 7 Nov 2009 02:04:56 +0000 Subject: [PATCH] more optimizations --- .../src/org/aspectj/weaver/Iterators.java | 8 +- .../src/org/aspectj/weaver/ResolvedType.java | 152 ++++++++++++++++++ .../org/aspectj/weaver/UnresolvedType.java | 4 + .../patterns/ExactAnnotationTypePattern.java | 14 +- .../weaver/patterns/ExactTypePattern.java | 11 ++ .../weaver/patterns/HasMemberTypePattern.java | 6 +- .../weaver/patterns/KindedPointcut.java | 2 - .../weaver/patterns/SignaturePattern.java | 5 +- 8 files changed, 184 insertions(+), 18 deletions(-) diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/Iterators.java b/org.aspectj.matcher/src/org/aspectj/weaver/Iterators.java index 02672b61b..1a2e82006 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/Iterators.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/Iterators.java @@ -118,17 +118,17 @@ public final class Iterators { }; } - public static class ArrayIterator implements Iterator { + public static class ResolvedTypeArrayIterator implements Iterator { private ResolvedType[] array; private int index; private int len; private boolean wantGenerics; private List alreadySeen; // type signatures - public ArrayIterator(ResolvedType[] array, List alreadySeen, boolean genericsAware) { + public ResolvedTypeArrayIterator(ResolvedType[] array, List alreadySeen, boolean wantGenerics) { assert array != null; this.array = array; - this.wantGenerics = genericsAware; + this.wantGenerics = wantGenerics; this.len = array.length; this.index = 0; this.alreadySeen = alreadySeen; @@ -138,7 +138,7 @@ public final class Iterators { private void moveToNextNewOne() { while (index < len) { ResolvedType interfaceType = array[index]; - if (!wantGenerics && (interfaceType.isGenericType() || interfaceType.isParameterizedType())) { + if (!wantGenerics && interfaceType.isParameterizedOrGenericType()) { interfaceType = interfaceType.getRawType(); } String signature = interfaceType.getSignature(); diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/ResolvedType.java b/org.aspectj.matcher/src/org/aspectj/weaver/ResolvedType.java index d3f930abc..341740667 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/ResolvedType.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/ResolvedType.java @@ -21,8 +21,10 @@ import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Queue; import java.util.Set; import org.aspectj.bridge.IMessage; @@ -30,6 +32,7 @@ import org.aspectj.bridge.ISourceLocation; import org.aspectj.bridge.Message; import org.aspectj.bridge.MessageUtil; import org.aspectj.util.FuzzyBoolean; +import org.aspectj.weaver.Iterators.Getter; import org.aspectj.weaver.patterns.Declare; import org.aspectj.weaver.patterns.PerClause; @@ -306,6 +309,155 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl }, Iterators.recur(this, ifaceGetter)), methodGetter); } + /** + * Return an iterator over the types in this types hierarchy - starting with this type first, then all superclasses up to Object + * and then all interfaces (starting with those 'nearest' this type). + * + * @param wantGenerics true if the caller wants full generic information + * @param wantDeclaredParents true if the caller even wants those parents introduced via declare parents + * @return an iterator over all types in the hierarchy of this type + */ + public Iterator getHierarchy(final boolean wantGenerics, final boolean wantDeclaredParents) { + + final Iterators.Getter interfaceGetter = new Iterators.Getter() { + List alreadySeen = new ArrayList(); // Strings are signatures (ResolvedType.getSignature()) + + public Iterator get(ResolvedType type) { + ResolvedType[] interfaces = type.getDeclaredInterfaces(); + + // remove interfaces introduced by declare parents + // relatively expensive but hopefully uncommon + if (!wantDeclaredParents && type.hasNewParentMungers()) { + // Throw away interfaces from that array if they were decp'd onto here + List forRemoval = new ArrayList(); + for (ConcreteTypeMunger munger : type.interTypeMungers) { + if (munger.getMunger() != null) { + ResolvedTypeMunger m = munger.getMunger(); + if (m.getKind() == ResolvedTypeMunger.Parent) { + ResolvedType newType = ((NewParentTypeMunger) m).getNewParent(); + if (!wantGenerics && newType.isParameterizedOrGenericType()) { + newType = newType.getRawType(); + } + for (int ii = 0; ii < interfaces.length; ii++) { + ResolvedType iface = interfaces[ii]; + if (!wantGenerics && iface.isParameterizedOrGenericType()) { + iface = iface.getRawType(); + } + if (newType.getSignature().equals(iface.getSignature())) { // pr171953 + forRemoval.add(ii); + } + } + } + } + } + // Found some to remove from those we are going to iterate over + if (forRemoval.size() > 0) { + ResolvedType[] interfaces2 = new ResolvedType[interfaces.length - forRemoval.size()]; + int p = 0; + for (int ii = 0; ii < interfaces.length; ii++) { + if (!forRemoval.contains(ii)) { + interfaces2[p++] = interfaces[ii]; + } + } + interfaces = interfaces2; + } + } + return new Iterators.ResolvedTypeArrayIterator(interfaces, alreadySeen, wantGenerics); + } + }; + + // If this type is an interface, there are only interfaces to walk + if (this.isInterface()) { + return new SuperInterfaceWalker(interfaceGetter, this); + } else { + SuperInterfaceWalker superInterfaceWalker = new SuperInterfaceWalker(interfaceGetter); + Iterator superClassesIterator = new SuperClassWalker(this, superInterfaceWalker, wantGenerics); + // append() will check if the second iterator is empty before appending - but the types which the superInterfaceWalker + // needs to visit are only accumulated whilst the superClassesIterator is in progress + return Iterators.append1(superClassesIterator, superInterfaceWalker); + } + } + + public static class SuperClassWalker implements Iterator { + + private ResolvedType curr; + private SuperInterfaceWalker iwalker; + private boolean wantGenerics; + + public SuperClassWalker(ResolvedType type, SuperInterfaceWalker iwalker, boolean genericsAware) { + this.curr = type; + this.iwalker = iwalker; + this.wantGenerics = genericsAware; + } + + public boolean hasNext() { + return curr != null; + } + + public ResolvedType next() { + ResolvedType ret = curr; + if (!wantGenerics && ret.isParameterizedOrGenericType()) { + ret = ret.getRawType(); + } + iwalker.push(ret); // tell the interface walker about another class whose interfaces need visiting + curr = curr.getSuperclass(); + return ret; + } + + public void remove() { + throw new UnsupportedOperationException(); + } + } + + static class SuperInterfaceWalker implements Iterator { + + private Getter ifaceGetter; + Iterator delegate = null; + public Queue toPersue = new LinkedList(); + public Set visited = new HashSet(); + + SuperInterfaceWalker(Iterators.Getter ifaceGetter) { + this.ifaceGetter = ifaceGetter; + } + + SuperInterfaceWalker(Iterators.Getter ifaceGetter, ResolvedType interfaceType) { + this.ifaceGetter = ifaceGetter; + this.delegate = Iterators.one(interfaceType); + } + + public boolean hasNext() { + if (delegate == null || !delegate.hasNext()) { + // either we set it up or we have run out, is there anything else to look at? + if (toPersue.isEmpty()) { + return false; + } + do { + ResolvedType next = toPersue.remove(); + visited.add(next); + delegate = ifaceGetter.get(next); // retrieve interfaces from a class or another interface + } while (!delegate.hasNext() && !toPersue.isEmpty()); + } + return delegate.hasNext(); + } + + public void push(ResolvedType ret) { + toPersue.add(ret); + } + + public ResolvedType next() { + ResolvedType next = delegate.next(); + if (!visited.contains(next)) { + visited.add(next); + toPersue.add(next); // pushes on interfaces already visited? + } + return next; + } + + public void remove() { + throw new UnsupportedOperationException(); + } + } + /** * Return a list of methods, first those declared on this class, then those declared on the superclass (recurse) and then those * declared on the superinterfaces. The getMethods() call above doesn't quite work the same as it will (through the iterator) diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/UnresolvedType.java b/org.aspectj.matcher/src/org/aspectj/weaver/UnresolvedType.java index c5fbeac7f..722900666 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/UnresolvedType.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/UnresolvedType.java @@ -168,6 +168,10 @@ public class UnresolvedType implements Traceable, TypeVariableDeclaringElement { return typeKind == TypeKind.PARAMETERIZED; } + public boolean isParameterizedOrGenericType() { + return typeKind == TypeKind.GENERIC || typeKind == TypeKind.PARAMETERIZED; + } + public boolean isTypeVariableReference() { return typeKind == TypeKind.TYPE_VARIABLE; } diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/patterns/ExactAnnotationTypePattern.java b/org.aspectj.matcher/src/org/aspectj/weaver/patterns/ExactAnnotationTypePattern.java index dfa208871..1105d87cf 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/patterns/ExactAnnotationTypePattern.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/patterns/ExactAnnotationTypePattern.java @@ -12,6 +12,7 @@ package org.aspectj.weaver.patterns; import java.io.DataOutputStream; import java.io.IOException; import java.util.HashMap; +import java.util.Iterator; import java.util.Map; import java.util.Set; @@ -75,7 +76,7 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern { return annotationType; } - public Map getAnnotationValues() { + public Map getAnnotationValues() { return annotationValues; } @@ -99,7 +100,7 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern { public FuzzyBoolean matches(AnnotatedElement annotated, ResolvedType[] parameterAnnotations) { if (!isForParameterAnnotationMatch()) { boolean checkSupers = false; - if (getResolvedAnnotationType().hasAnnotation(UnresolvedType.AT_INHERITED)) { + if (getResolvedAnnotationType().isInheritedAnnotation()) { if (annotated instanceof ResolvedType) { checkSupers = true; } @@ -220,7 +221,7 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern { // this version should be called for @this, @target, @args public FuzzyBoolean matchesRuntimeType(AnnotatedElement annotated) { - if (getResolvedAnnotationType().hasAnnotation(UnresolvedType.AT_INHERITED)) { + if (getResolvedAnnotationType().isInheritedAnnotation()) { // a static match is good enough if (matches(annotated).alwaysTrue()) { return FuzzyBoolean.YES; @@ -234,8 +235,8 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern { public void resolve(World world) { if (!resolved) { annotationType = annotationType.resolve(world); + resolved = true; } - resolved = true; } /* @@ -360,8 +361,9 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern { s.writeInt(0); } else { s.writeInt(annotationValues.size()); - Set keys = annotationValues.keySet(); - for (String k : keys) { + Set key = annotationValues.keySet(); + for (Iterator keys = key.iterator(); keys.hasNext();) { + String k = keys.next(); s.writeUTF(k); s.writeUTF(annotationValues.get(k)); } diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/patterns/ExactTypePattern.java b/org.aspectj.matcher/src/org/aspectj/weaver/patterns/ExactTypePattern.java index c9a1a84cb..1f1262317 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/patterns/ExactTypePattern.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/patterns/ExactTypePattern.java @@ -32,6 +32,8 @@ import org.aspectj.weaver.World; public class ExactTypePattern extends TypePattern { protected UnresolvedType type; protected transient ResolvedType resolvedType; + public boolean checked = false; + public boolean isVoid = false; public static final Map> primitiveTypesMap; public static final Map> boxedPrimitivesMap; @@ -176,6 +178,15 @@ public class ExactTypePattern extends TypePattern { return resolvedType; } + @Override + public boolean isVoid() { + if (!checked) { + isVoid = this.type.getSignature().equals("V"); + checked = true; + } + return isVoid; + } + // true if (matchType instanceof this.type) @Override public FuzzyBoolean matchesInstanceof(ResolvedType matchType) { diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/patterns/HasMemberTypePattern.java b/org.aspectj.matcher/src/org/aspectj/weaver/patterns/HasMemberTypePattern.java index cd8162522..8a202d71b 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/patterns/HasMemberTypePattern.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/patterns/HasMemberTypePattern.java @@ -90,9 +90,9 @@ public class HasMemberTypePattern extends TypePattern { } } // try itds before we give up - List mungers = type.getInterTypeMungersIncludingSupers(); - for (Iterator iter = mungers.iterator(); iter.hasNext();) { - ConcreteTypeMunger munger = (ConcreteTypeMunger) iter.next(); + List mungers = type.getInterTypeMungersIncludingSupers(); + for (Iterator iter = mungers.iterator(); iter.hasNext();) { + ConcreteTypeMunger munger = iter.next(); Member member = munger.getSignature(); if (signaturePattern.matches(member, type.getWorld(), false)) { if (!Modifier.isPublic(member.getModifiers())) { diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/patterns/KindedPointcut.java b/org.aspectj.matcher/src/org/aspectj/weaver/patterns/KindedPointcut.java index 39f73f8b8..68d8f05ee 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/patterns/KindedPointcut.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/patterns/KindedPointcut.java @@ -101,7 +101,6 @@ public class KindedPointcut extends Pointcut { @Override protected FuzzyBoolean matchInternal(Shadow shadow) { - long time = System.nanoTime(); if (shadow.getKind() != kind) { return FuzzyBoolean.NO; } @@ -116,7 +115,6 @@ public class KindedPointcut extends Pointcut { if (!signature.matches(shadow.getMatchingSignature(), shadow.getIWorld(), this.kind == Shadow.MethodCall)) { if (kind == Shadow.MethodCall) { - long t2 = System.nanoTime(); warnOnConfusingSig(shadow); // warnOnBridgeMethod(shadow); } diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/patterns/SignaturePattern.java b/org.aspectj.matcher/src/org/aspectj/weaver/patterns/SignaturePattern.java index 22a359040..06934d563 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/patterns/SignaturePattern.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/patterns/SignaturePattern.java @@ -601,7 +601,7 @@ public class SignaturePattern extends PatternNode { return true; } - Collection declaringTypes = member.getDeclaringTypes(world); + Collection declaringTypes = member.getDeclaringTypes(world); boolean checkReturnType = true; // XXX Possible enhancement? Doesn't seem to speed things up @@ -614,8 +614,7 @@ public class SignaturePattern extends PatternNode { // Sometimes that list includes types that don't explicitly declare the member we are after - // they are on the list because their supertype is on the list, that's why we use // lookupMethod rather than lookupMemberNoSupers() - for (Iterator i = declaringTypes.iterator(); i.hasNext();) { - ResolvedType type = (ResolvedType) i.next(); + for (ResolvedType type : declaringTypes) { if (declaringType.matchesStatically(type)) { if (!checkReturnType) { return true; -- 2.39.5