]> source.dussan.org Git - aspectj.git/commitdiff
fastmatch for execution!
authoraclement <aclement>
Sun, 8 Nov 2009 22:56:18 +0000 (22:56 +0000)
committeraclement <aclement>
Sun, 8 Nov 2009 22:56:18 +0000 (22:56 +0000)
org.aspectj.matcher/src/org/aspectj/weaver/ReferenceType.java
org.aspectj.matcher/src/org/aspectj/weaver/UnresolvedType.java
org.aspectj.matcher/src/org/aspectj/weaver/patterns/FastMatchInfo.java
org.aspectj.matcher/src/org/aspectj/weaver/patterns/KindedPointcut.java
org.aspectj.matcher/src/org/aspectj/weaver/patterns/NotTypePattern.java
org.aspectj.matcher/src/org/aspectj/weaver/patterns/SignaturePattern.java

index caca8f444d8858b09b7002e7c9661b62f37e4ae5..e8e7e0b4cb4c98b911e3292f93bbe341df7d3c9f 100644 (file)
@@ -609,6 +609,7 @@ public class ReferenceType extends ResolvedType {
                }
                ResolvedType[] delegateInterfaces = delegate.getDeclaredInterfaces();
                if (newInterfaces != null) {
+                       // OPTIMIZE does this part of the method trigger often?
                        ResolvedType[] extraInterfaces = new ResolvedType[delegateInterfaces.length + newInterfaces.length];
                        System.arraycopy(delegateInterfaces, 0, extraInterfaces, 0, delegateInterfaces.length);
                        System.arraycopy(newInterfaces, 0, extraInterfaces, delegateInterfaces.length, newInterfaces.length);
index 722900666e23ad3575363e64cc62edf1f7aa941f..666fed2788592ba63aaf940c0c97a4d79b120dc4 100644 (file)
@@ -152,6 +152,11 @@ public class UnresolvedType implements Traceable, TypeVariableDeclaringElement {
                return typeKind == TypeKind.PRIMITIVE;
        }
 
+       public boolean isVoid() {
+               // OPTIMIZE promote to bitflag?
+               return signature.equals("V");
+       }
+
        public boolean isSimpleType() {
                return typeKind == TypeKind.SIMPLE;
        }
index d9fddd30177a3d7e75a1096150482b619c4b701e..a18830832d9fc4b4bae24b1cac90ae08b2a9d8ca 100644 (file)
@@ -17,6 +17,9 @@ import org.aspectj.weaver.Shadow;
 import org.aspectj.weaver.World;
 import org.aspectj.weaver.Shadow.Kind;
 
+/**
+ * Represents a type that pointcuts may match. Fast match for a pointcut should quickly say NO if it can.
+ */
 public class FastMatchInfo {
        private Kind kind;
        private ResolvedType type;
index 68d8f05ee0094f718b59022bf30eb37e853ded47..bdfab6714226fad8501c9a0847c1b18da890c865 100644 (file)
 
 package org.aspectj.weaver.patterns;
 
+import static org.aspectj.util.FuzzyBoolean.MAYBE;
+
 import java.io.DataOutputStream;
 import java.io.IOException;
+import java.util.Iterator;
 import java.util.Map;
 
 import org.aspectj.bridge.ISourceLocation;
@@ -90,12 +93,96 @@ public class KindedPointcut extends Pointcut {
 
        @Override
        public FuzzyBoolean fastMatch(FastMatchInfo info) {
+               // info.getKind()==null means all kinds
                if (info.getKind() != null) {
                        if (info.getKind() != kind) {
                                return FuzzyBoolean.NO;
                        }
                }
 
+               // KindedPointcut represents these join points:
+               // method-execution/ctor-execution/method-call/ctor-call/field-get/field-set/advice-execution/static-initialization
+               // initialization/pre-initialization
+
+               // Check if the global fastmatch flag is on - the flag can be removed (and this made default) once it proves stable!
+               if (info.world.optimizedMatching) {
+
+                       // For now, just consider MethodExecution and Initialization
+                       if ((kind == Shadow.MethodExecution || kind == Shadow.Initialization) && info.getKind() == null) {
+                               boolean fastMatchingOnAspect = info.getType().isAspect();
+                               // an Aspect may define ITDs, and although our signature declaring type pattern may not match on the
+                               // aspect, the ITDs may have a different signature as we iterate through the members of the aspect. Let's not
+                               // try and work through that here and just say MAYBE
+                               if (fastMatchingOnAspect) {
+                                       return MAYBE;
+                               }
+                               // Aim here is to do the same test as is done for signature pattern declaring type pattern matching
+                               if (this.getSignature().isExactDeclaringTypePattern()) {
+                                       ExactTypePattern typePattern = (ExactTypePattern) this.getSignature().getDeclaringType();
+                                       // Interface checks are more expensive, they could be anywhere...
+                                       ResolvedType patternExactType = typePattern.getResolvedExactType(info.world);
+                                       if (patternExactType.isInterface()) {
+                                               ResolvedType curr = info.getType();
+                                               Iterator<ResolvedType> hierarchyWalker = curr.getHierarchy(true, true);
+                                               boolean found = false;
+                                               while (hierarchyWalker.hasNext()) {
+                                                       curr = hierarchyWalker.next();
+                                                       if (typePattern.matchesStatically(curr)) {
+                                                               found = true;
+                                                               break;
+                                                       }
+                                               }
+                                               if (!found) {
+                                                       return FuzzyBoolean.NO;
+                                               }
+                                       } else if (patternExactType.isClass()) {
+                                               ResolvedType curr = info.getType();
+                                               do {
+                                                       if (typePattern.matchesStatically(curr)) {
+                                                               break;
+                                                       }
+                                                       curr = curr.getSuperclass();
+                                               } while (curr != null);
+                                               if (curr == null) {
+                                                       return FuzzyBoolean.NO;
+                                               }
+                                       }
+                               } else if (this.getSignature().getDeclaringType() instanceof AnyWithAnnotationTypePattern) {
+                                       // aim here is to say NO if the annotation is not possible in the hierarchy here
+                                       ResolvedType type = info.getType();
+                                       AnnotationTypePattern annotationTypePattern = ((AnyWithAnnotationTypePattern) getSignature().getDeclaringType())
+                                                       .getAnnotationPattern();
+                                       if (annotationTypePattern instanceof ExactAnnotationTypePattern) {
+                                               ExactAnnotationTypePattern exactAnnotationTypePattern = (ExactAnnotationTypePattern) annotationTypePattern;
+                                               if (exactAnnotationTypePattern.getAnnotationValues() == null
+                                                               || exactAnnotationTypePattern.getAnnotationValues().size() == 0) {
+                                                       ResolvedType annotationType = exactAnnotationTypePattern.getAnnotationType().resolve(info.world);
+                                                       if (type.hasAnnotation(annotationType)) {
+                                                               return FuzzyBoolean.MAYBE;
+                                                       }
+                                                       if (annotationType.isInheritedAnnotation()) {
+                                                               // ok - we may be picking it up from further up the hierarchy (but only a super*class*)
+                                                               ResolvedType toMatchAgainst = type.getSuperclass();
+                                                               boolean found = false;
+                                                               while (toMatchAgainst != null) {
+                                                                       if (toMatchAgainst.hasAnnotation(annotationType)) {
+                                                                               found = true;
+                                                                               break;
+                                                                       }
+                                                                       toMatchAgainst = toMatchAgainst.getSuperclass();
+                                                               }
+                                                               if (!found) {
+                                                                       return FuzzyBoolean.NO;
+                                                               }
+                                                       } else {
+                                                               return FuzzyBoolean.NO;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+
                return FuzzyBoolean.MAYBE;
        }
 
index 01adce402e9787873ab90816af05af1bf3499d43..14f7dad6d0f9b53a411783e7043fe56cfa9b96d2 100644 (file)
@@ -34,6 +34,8 @@ import org.aspectj.weaver.World;
  */
 public class NotTypePattern extends TypePattern {
        private TypePattern negatedPattern;
+       private boolean isBangVoid = false; // is this '!void'
+       private boolean checked = false;
 
        public NotTypePattern(TypePattern pattern) {
                super(false, false); // ??? we override all methods that care about includeSubtypes
@@ -106,6 +108,15 @@ public class NotTypePattern extends TypePattern {
                return this;
        }
 
+       @Override
+       public boolean isBangVoid() {
+               if (!checked) {
+                       isBangVoid = negatedPattern.getExactType().isVoid();
+                       checked = true;
+               }
+               return isBangVoid;
+       }
+
        @Override
        public TypePattern parameterizeWith(Map typeVariableMap, World w) {
                TypePattern newNegatedPattern = negatedPattern.parameterizeWith(typeVariableMap, w);
index 51251d9b746ff61007355caab8d4c27090ff3cf2..3ca7c2d2f92b53859f04a807d99a107263d6f896 100644 (file)
@@ -419,6 +419,32 @@ public class SignaturePattern extends PatternNode {
                return FuzzyBoolean.YES;
        }
 
+       /**
+        * Quickly detect if the joinpoint absolutely cannot match becaused the method parameters at the joinpoint cannot match against
+        * this signature pattern.
+        * 
+        * @param methodJoinpoint the joinpoint to quickly match against
+        * @return true if it is impossible for the joinpoint to match this signature
+        */
+       private boolean parametersCannotMatch(JoinPointSignature methodJoinpoint) {
+               int patternParameterCount = parameterTypes.size();
+               int joinpointParameterCount = methodJoinpoint.getParameterTypes().length;
+               boolean isVarargs = methodJoinpoint.isVarargsMethod();
+
+               // Quick rule: pattern specifies zero parameters, and joinpoint has parameters *OR*
+               if (patternParameterCount == 0 && joinpointParameterCount > 0) { // varargs may allow this...
+                       return true;
+               }
+
+               // Quick rule: pattern doesn't specify ellipsis and there are a different number of parameters on the
+               // method join point as compared with the pattern
+               if (parameterTypes.ellipsisCount == 0 && patternParameterCount != joinpointParameterCount) {
+                       return true;
+               }
+
+               return false;
+       }
+
        /**
         * Matches on name, declaring type, return type, parameter types, throws types
         */