Index: .classpath
===================================================================
RCS file: /home/technology/org.aspectj/modules/weaver/.classpath,v
retrieving revision 1.1
diff -u -r1.1 .classpath
--- .classpath 16 Dec 2002 18:02:43 -0000 1.1
+++ .classpath 3 Nov 2004 14:37:28 -0000
@@ -1,15 +1,14 @@
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
Index: src/org/aspectj/weaver/patterns/AndPointcut.java
===================================================================
RCS file: /home/technology/org.aspectj/modules/weaver/src/org/aspectj/weaver/patterns/AndPointcut.java,v
retrieving revision 1.8
diff -u -r1.8 AndPointcut.java
--- src/org/aspectj/weaver/patterns/AndPointcut.java 8 Jun 2004 15:04:34 -0000 1.8
+++ src/org/aspectj/weaver/patterns/AndPointcut.java 3 Nov 2004 14:37:29 -0000
@@ -18,6 +18,7 @@
import java.io.IOException;
import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.JoinPoint.StaticPart;
import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.IntMap;
@@ -26,31 +27,260 @@
import org.aspectj.weaver.ast.Test;
public class AndPointcut extends Pointcut {
- Pointcut left, right; // exposed for testing
+
+ private interface MatcherState {
+ public FuzzyBoolean fastMatch(FastMatchInfo type);
+ public FuzzyBoolean match(Shadow shadow);
+ public FuzzyBoolean match(JoinPoint jp, JoinPoint.StaticPart encJP);
+ public FuzzyBoolean match(JoinPoint.StaticPart jpsp);
+ }
+
+ private class MatcherStateLeftFirst implements MatcherState {
+ public FuzzyBoolean fastMatch(FastMatchInfo type) {
+ FuzzyBoolean leftValue = left.fastMatch(type);
+ if(leftValue==FuzzyBoolean.NEVER) {
+ state = new MatcherStateRightOnly();
+ return leftValue;
+ } else if(leftValue==FuzzyBoolean.NO) {
+ return leftValue;
+ } else {
+ return leftValue.and(right.fastMatch(type));
+ }
+ }
+
+ public FuzzyBoolean match(Shadow shadow) {
+ FuzzyBoolean leftValue = left.match(shadow);
+ if(leftValue==FuzzyBoolean.NEVER) {
+ state = new MatcherStateRightOnly();
+ return leftValue;
+ } else if(leftValue==FuzzyBoolean.NO) {
+ return leftValue;
+ } else {
+ return leftValue.and(right.match(shadow));
+ }
+ }
+
+ public FuzzyBoolean match(JoinPoint jp, StaticPart encJP) {
+ FuzzyBoolean leftValue = left.match(jp,encJP);
+ if(leftValue==FuzzyBoolean.NEVER) {
+ state = new MatcherStateRightOnly();
+ return leftValue;
+ } else if(leftValue==FuzzyBoolean.NO) {
+ return leftValue;
+ } else {
+ return leftValue.and(right.match(jp,encJP));
+ }
+ }
+
+ public FuzzyBoolean match(StaticPart jpsp) {
+ FuzzyBoolean leftValue = left.match(jpsp);
+ if(leftValue==FuzzyBoolean.NEVER) {
+ state = new MatcherStateRightOnly();
+ return leftValue;
+ } else if(leftValue==FuzzyBoolean.NO) {
+ return leftValue;
+ } else {
+ return leftValue.and(right.match(jpsp));
+ }
+ }
+
+ };
+
+ private class MatcherStateRightFirst implements MatcherState {
+
+ public FuzzyBoolean fastMatch(FastMatchInfo type) {
+ FuzzyBoolean rightValue = right.fastMatch(type);
+ if(rightValue==FuzzyBoolean.NEVER) {
+ state = new MatcherStateLeftOnly();
+ return rightValue;
+ } else if(rightValue==FuzzyBoolean.NO) {
+ return rightValue;
+ } else {
+ return rightValue.and(left.fastMatch(type));
+ }
+ }
+
+ public FuzzyBoolean match(Shadow shadow) {
+ FuzzyBoolean rightValue = right.match(shadow);
+ if(rightValue==FuzzyBoolean.NEVER) {
+ state = new MatcherStateLeftOnly();
+ return rightValue;
+ } else if(rightValue==FuzzyBoolean.NO) {
+ return rightValue;
+ } else {
+ return rightValue.and(left.match(shadow));
+ }
+ }
+
+ public FuzzyBoolean match(JoinPoint jp, StaticPart encJP) {
+ FuzzyBoolean rightValue = right.match(jp,encJP);
+ if(rightValue==FuzzyBoolean.NEVER) {
+ state = new MatcherStateLeftOnly();
+ return rightValue;
+ } else if(rightValue==FuzzyBoolean.NO) {
+ return rightValue;
+ } else {
+ return rightValue.and(left.match(jp,encJP));
+ }
+ }
+
+ public FuzzyBoolean match(StaticPart jpsp) {
+ FuzzyBoolean rightValue = right.match(jpsp);
+ if(rightValue==FuzzyBoolean.NEVER) {
+ state = new MatcherStateLeftOnly();
+ return rightValue;
+ } else if(rightValue==FuzzyBoolean.NO) {
+ return rightValue;
+ } else {
+ return rightValue.and(left.match(jpsp));
+ }
+ }
+
+ };
+
+ private class MatcherStateLeftOnly implements MatcherState {
+
+ public FuzzyBoolean fastMatch(FastMatchInfo type) {
+ FuzzyBoolean leftValue = left.fastMatch(type);
+ if(leftValue==FuzzyBoolean.NEVER) {
+ state = new MatcherStateNever();
+ }
+ return leftValue;
+ }
+
+ public FuzzyBoolean match(Shadow shadow) {
+ FuzzyBoolean leftValue = left.match(shadow);
+ if(leftValue==FuzzyBoolean.NEVER) {
+ state = new MatcherStateNever();
+ }
+ return leftValue;
+ }
+
+ public FuzzyBoolean match(JoinPoint jp, StaticPart encJP) {
+ FuzzyBoolean leftValue = left.match(jp,encJP);
+ if(leftValue==FuzzyBoolean.NEVER) {
+ state = new MatcherStateNever();
+ }
+ return leftValue;
+ }
+
+ public FuzzyBoolean match(StaticPart jpsp) {
+ FuzzyBoolean leftValue = left.match(jpsp);
+ if(leftValue==FuzzyBoolean.NEVER) {
+ state = new MatcherStateNever();
+ }
+ return leftValue;
+ }
+
+ };
+
+ private class MatcherStateRightOnly implements MatcherState {
+
+ public FuzzyBoolean fastMatch(FastMatchInfo type) {
+ FuzzyBoolean rightValue = right.fastMatch(type);
+ if(rightValue==FuzzyBoolean.NEVER) {
+ state = new MatcherStateNever();
+ }
+ return rightValue;
+ }
+
+ public FuzzyBoolean match(Shadow shadow) {
+ FuzzyBoolean rightValue = right.match(shadow);
+ if(rightValue==FuzzyBoolean.NEVER) {
+ state = new MatcherStateNever();
+ }
+ return rightValue;
+ }
+
+ public FuzzyBoolean match(JoinPoint jp, StaticPart encJP) {
+ FuzzyBoolean rightValue = right.match(jp,encJP);
+ if(rightValue==FuzzyBoolean.NEVER) {
+ state = new MatcherStateNever();
+ }
+ return rightValue;
+ }
+
+ public FuzzyBoolean match(StaticPart jpsp) {
+ FuzzyBoolean leftValue = left.match(jpsp);
+ if(leftValue==FuzzyBoolean.NEVER) {
+ state = new MatcherStateNever();
+ }
+ return leftValue;
+ }
+
+ };
+
+ private class MatcherStateNever implements MatcherState {
+
+ public FuzzyBoolean fastMatch(FastMatchInfo type) {
+ return FuzzyBoolean.NEVER;
+ }
+
+ public FuzzyBoolean match(Shadow shadow) {
+ return FuzzyBoolean.NEVER;
+ }
+
+ public FuzzyBoolean match(JoinPoint jp, StaticPart encJP) {
+ return FuzzyBoolean.NEVER;
+ }
+
+ public FuzzyBoolean match(StaticPart jpsp) {
+ return FuzzyBoolean.NEVER;
+ }
+
+ };
+
+ private MatcherState state;
+
+ Pointcut left, right; // exposed for testing
+
public AndPointcut(Pointcut left, Pointcut right) {
super();
this.left = left;
this.right = right;
setLocation(left.getSourceContext(), left.getStart(), right.getEnd());
+//TODO Compilerfehler bei conditional assignment hier?
+ //if left pc is easier to match, match this one first
+ if(this.left.matchingCosts() < this.right.matchingCosts()) {
+ this.state = new MatcherStateLeftFirst();
+ } else {
+ this.state = new MatcherStateRightFirst();
+ }
}
public FuzzyBoolean fastMatch(FastMatchInfo type) {
- return left.fastMatch(type).and(right.fastMatch(type));
+ //only for testing
+ if(!Pointcut.USE_LAZY_EVAL)
+ return this.left.fastMatch(type).and(this.right.fastMatch(type));
+ //
+ return this.state.fastMatch(type);
}
public FuzzyBoolean match(Shadow shadow) {
- return left.match(shadow).and(right.match(shadow));
+ //only for testing
+ if(!Pointcut.USE_LAZY_EVAL)
+ return this.left.match(shadow).and(this.right.match(shadow));
+ //
+ return this.state.match(shadow);
}
public FuzzyBoolean match(JoinPoint jp, JoinPoint.StaticPart encJP) {
- return left.match(jp,encJP).and(right.match(jp,encJP));
+ //only for testing
+ if(!Pointcut.USE_LAZY_EVAL)
+ return this.left.match(jp,encJP).and(this.right.match(jp,encJP));
+ //
+ return this.state.match(jp,encJP);
}
-
+
public FuzzyBoolean match(JoinPoint.StaticPart jpsp) {
- return left.match(jpsp).and(right.match(jpsp));
+ //only for testing
+ if(!Pointcut.USE_LAZY_EVAL)
+ return this.left.match(jpsp).and(this.right.match(jpsp));
+ //
+ return this.state.match(jpsp);
}
-
+
public String toString() {
return "(" + left.toString() + " && " + right.toString() + ")";
}
@@ -109,4 +339,12 @@
return right;
}
+ /**
+ * {@inheritDoc}
+ */
+ public double matchingCosts() {
+ //this is a heuristic
+ return this.left.matchingCosts()*0.5 +
+ this.right.matchingCosts()*0.5;
+ }
}
Index: src/org/aspectj/weaver/patterns/Pointcut.java
===================================================================
RCS file: /home/technology/org.aspectj/modules/weaver/src/org/aspectj/weaver/patterns/Pointcut.java,v
retrieving revision 1.12
diff -u -r1.12 Pointcut.java
--- src/org/aspectj/weaver/patterns/Pointcut.java 28 Jul 2004 15:14:50 -0000 1.12
+++ src/org/aspectj/weaver/patterns/Pointcut.java 3 Nov 2004 14:37:29 -0000
@@ -51,7 +51,15 @@
public static final State RESOLVED = new State("resolved", 1);
public static final State CONCRETE = new State("concrete", 2);
-
+ /** Cost involved for pointcuts, returning FuzzyBoolean.MAYBE
+ * on match(), resp. fastMatch()
+ * @see #match(Shadow)
+ * @see #fastMatch(FastMatchInfo)
+ */
+ //public static final double MATCHING_COST_MAYBE = 1000.0;
+
+ public static /*final*/ boolean USE_LAZY_EVAL = true; //non-final for testing
+
public State state;
/**
@@ -62,7 +70,15 @@
this.state = SYMBOLIC;
}
-
+ /**
+ * @return The approximate costs of checking for a match
+ * of this pointcut. This should in most cases be implemented by subclasses.
+ */
+ public double matchingCosts() {
+ return 0;
+ }
+
+
/**
* Could I match any shadows in the code defined within this type?
*/
@@ -278,6 +294,14 @@
}
public String toString() { return ""; }
+
+ /**
+ * {@inheritDoc}
+ */
+ public double matchingCosts() {
+ //no costs here
+ return 0;
+ }
}
//public static Pointcut MatchesNothing = new MatchesNothingPointcut();
Index: testsrc/org/aspectj/weaver/patterns/AndOrPerformanceTestCase.java
===================================================================
RCS file: testsrc/org/aspectj/weaver/patterns/AndOrPerformanceTestCase.java
diff -N testsrc/org/aspectj/weaver/patterns/AndOrPerformanceTestCase.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsrc/org/aspectj/weaver/patterns/AndOrPerformanceTestCase.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,97 @@
+/* *******************************************************************
+ * 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.patterns;
+
+import junit.framework.TestCase;
+
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.Signature;
+import org.aspectj.runtime.reflect.Factory;
+import org.aspectj.util.FuzzyBoolean;
+
+/**
+ * @author Eric Bodden
+ *
+ * Runs performance tests measuring lazy evaluation of
+ * pointcut matching.
+ */
+public class AndOrPerformanceTestCase extends TestCase {
+ private static final int INNER_ITERATIONS = 100000;
+ private static final int GLOBAL_ITERATIONS = 10;
+ /**
+ * Constructor for PatternTestCase.
+ * @param name
+ */
+ public AndOrPerformanceTestCase(String name) {
+ super(name);
+ }
+
+ public void testLazyEvalPerformance() {
+
+ Pointcut foo = makePointcut("this(org.aspectj.weaver.patterns.AndOrPerformanceTestCase.Foo)").resolve();
+ Pointcut bar = makePointcut("this(org.aspectj.weaver.patterns.AndOrPerformanceTestCase.Bar)").resolve();
+ Pointcut c = makePointcut("this(org.aspectj.weaver.patterns.AndOrPerformanceTestCase.C)").resolve();
+
+ Factory f = new Factory("AndOrNotTestCase.java",AndOrPerformanceTestCase.class);
+
+ Signature methodSig = f.makeMethodSig("void aMethod()");
+ JoinPoint.StaticPart jpsp = f.makeSJP(JoinPoint.METHOD_EXECUTION,methodSig,1);
+ JoinPoint jp = Factory.makeJP(jpsp,new Foo(),new Foo());
+
+ long speedUp=0;
+ long timeNonLazy=Long.MAX_VALUE;
+
+ for(int iterations=0; iterations0);
+ }
+
+ private Pointcut makePointcut(String pattern) {
+ return new PatternParser(pattern).parsePointcut();
+ }
+
+ private void checkMatches(Pointcut p, JoinPoint jp, JoinPoint.StaticPart jpsp, FuzzyBoolean expected) {
+ assertEquals(expected,p.match(jp,jpsp));
+ }
+
+ private static class Foo{};
+ private static class Bar{};
+ private static class C{};
+
+}