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:24:27 -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:24:28 -0000
@@ -27,30 +27,98 @@
public class AndPointcut extends Pointcut {
Pointcut left, right; // exposed for testing
+
+ private final boolean evaluateLeftFirst;
public AndPointcut(Pointcut left, Pointcut right) {
super();
this.left = left;
this.right = right;
setLocation(left.getSourceContext(), left.getStart(), right.getEnd());
+ //if left pc is easier to match, match this one first
+ this.evaluateLeftFirst = this.left.matchingCosts() < this.right.matchingCosts();
}
public FuzzyBoolean fastMatch(FastMatchInfo type) {
- return left.fastMatch(type).and(right.fastMatch(type));
+ if(!Pointcut.USE_LAZY_EVAL)
+ return this.left.fastMatch(type).and(this.right.fastMatch(type));
+ if(this.evaluateLeftFirst) {
+ FuzzyBoolean leftValue = left.fastMatch(type);
+ if(leftValue.maybeTrue()) {
+ return leftValue.and(right.fastMatch(type));
+ } else {
+ return leftValue;
+ }
+ } else {
+ FuzzyBoolean rightValue = right.fastMatch(type);
+ if(rightValue.maybeTrue()) {
+ return rightValue.and(left.fastMatch(type));
+ } else {
+ return rightValue;
+ }
+ }
}
public FuzzyBoolean match(Shadow shadow) {
- return left.match(shadow).and(right.match(shadow));
+ if(!Pointcut.USE_LAZY_EVAL)
+ return this.left.match(shadow).and(this.right.match(shadow));
+ if(this.evaluateLeftFirst) {
+ FuzzyBoolean leftValue = left.match(shadow);
+ if(leftValue.maybeTrue()) {
+ return leftValue.and(right.match(shadow));
+ } else {
+ return leftValue;
+ }
+ } else {
+ FuzzyBoolean rightValue = right.match(shadow);
+ if(rightValue.maybeTrue()) {
+ return rightValue.and(left.match(shadow));
+ } else {
+ return rightValue;
+ }
+ }
}
public FuzzyBoolean match(JoinPoint jp, JoinPoint.StaticPart encJP) {
- return left.match(jp,encJP).and(right.match(jp,encJP));
+ if(!Pointcut.USE_LAZY_EVAL)
+ return this.left.match(jp,encJP).and(this.right.match(jp,encJP));
+ if(this.evaluateLeftFirst) {
+ FuzzyBoolean leftValue = left.match(jp,encJP);
+ if(leftValue.maybeTrue()) {
+ return leftValue.and(right.match(jp,encJP));
+ } else {
+ return leftValue;
+ }
+ } else {
+ FuzzyBoolean rightValue = right.match(jp,encJP);
+ if(rightValue.maybeTrue()) {
+ return rightValue.and(left.match(jp,encJP));
+ } else {
+ return rightValue;
+ }
+ }
}
-
+
public FuzzyBoolean match(JoinPoint.StaticPart jpsp) {
- return left.match(jpsp).and(right.match(jpsp));
+ if(!Pointcut.USE_LAZY_EVAL)
+ return this.left.match(jpsp).and(this.right.match(jpsp));
+ if(this.evaluateLeftFirst) {
+ FuzzyBoolean leftValue = left.match(jpsp);
+ if(leftValue.maybeTrue()) {
+ return leftValue.and(right.match(jpsp));
+ } else {
+ return leftValue;
+ }
+ } else {
+ FuzzyBoolean rightValue = right.match(jpsp);
+ if(rightValue.maybeTrue()) {
+ return rightValue.and(left.match(jpsp));
+ } else {
+ return rightValue;
+ }
+ }
}
-
+
public String toString() {
return "(" + left.toString() + " && " + right.toString() + ")";
}
Index: src/org/aspectj/weaver/patterns/OrPointcut.java
===================================================================
RCS file: /home/technology/org.aspectj/modules/weaver/src/org/aspectj/weaver/patterns/OrPointcut.java,v
retrieving revision 1.8
diff -u -r1.8 OrPointcut.java
--- src/org/aspectj/weaver/patterns/OrPointcut.java 8 Jun 2004 15:04:34 -0000 1.8
+++ src/org/aspectj/weaver/patterns/OrPointcut.java 3 Nov 2004 14:24:28 -0000
@@ -28,28 +28,88 @@
public class OrPointcut extends Pointcut {
private Pointcut left, right;
+ private final boolean evaluateLeftFirst;
+
public OrPointcut(Pointcut left, Pointcut right) {
super();
this.left = left;
this.right = right;
setLocation(left.getSourceContext(), left.getStart(), right.getEnd());
+ //if left pc is easier to match, match this one first
+ this.evaluateLeftFirst = this.left.matchingCosts() < this.right.matchingCosts();
}
public FuzzyBoolean fastMatch(FastMatchInfo type) {
- return left.fastMatch(type).or(right.fastMatch(type));
+ if(this.evaluateLeftFirst) {
+ FuzzyBoolean leftValue = left.fastMatch(type);
+ if(leftValue.maybeFalse()) {
+ return leftValue.or(right.fastMatch(type));
+ } else {
+ return leftValue;
+ }
+ } else {
+ FuzzyBoolean rightValue = right.fastMatch(type);
+ if(rightValue.maybeFalse()) {
+ return rightValue.or(left.fastMatch(type));
+ } else {
+ return rightValue;
+ }
+ }
}
public FuzzyBoolean match(Shadow shadow) {
- return left.match(shadow).or(right.match(shadow));
+ if(this.evaluateLeftFirst) {
+ FuzzyBoolean leftValue = left.match(shadow);
+ if(leftValue.maybeFalse()) {
+ return leftValue.or(right.match(shadow));
+ } else {
+ return leftValue;
+ }
+ } else {
+ FuzzyBoolean rightValue = right.match(shadow);
+ if(rightValue.maybeFalse()) {
+ return rightValue.or(left.match(shadow));
+ } else {
+ return rightValue;
+ }
+ }
}
public FuzzyBoolean match(JoinPoint jp, JoinPoint.StaticPart encJP) {
- return left.match(jp,encJP).or(right.match(jp,encJP));
+ if(this.evaluateLeftFirst) {
+ FuzzyBoolean leftValue = left.match(jp,encJP);
+ if(leftValue.maybeFalse()) {
+ return leftValue.or(right.match(jp,encJP));
+ } else {
+ return leftValue;
+ }
+ } else {
+ FuzzyBoolean rightValue = right.match(jp,encJP);
+ if(rightValue.maybeFalse()) {
+ return rightValue.or(left.match(jp,encJP));
+ } else {
+ return rightValue;
+ }
+ }
}
-
+
public FuzzyBoolean match(JoinPoint.StaticPart jpsp) {
- return left.match(jpsp).or(right.match(jpsp));
+ if(this.evaluateLeftFirst) {
+ FuzzyBoolean leftValue = left.match(jpsp);
+ if(leftValue.maybeFalse()) {
+ return leftValue.or(right.match(jpsp));
+ } else {
+ return leftValue;
+ }
+ } else {
+ FuzzyBoolean rightValue = right.match(jpsp);
+ if(rightValue.maybeFalse()) {
+ return rightValue.or(left.match(jpsp));
+ } else {
+ return rightValue;
+ }
+ }
}
public String toString() {
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:24:29 -0000
@@ -53,6 +53,7 @@
public State state;
+ public static boolean USE_LAZY_EVAL;
/**
* Constructor for Pattern.
@@ -62,7 +63,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 int matchingCosts() {
+ return 0;
+ }
+
+
/**
* Could I match any shadows in the code defined within this type?
*/
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{};
+
+}