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{}; + +}