[abc] cflowdepth considered unnecessary

From: Oege de Moor <Oege.de.Moor@comlab.ox.ac.uk>
Date: Wed Dec 14 2005 - 08:11:44 GMT

Belatedly, I've realised there's no need for cflowdepth to do
"context-free" tracematches if you have "let" pointcuts.
As an example, here is Neil's "lock/unlock must occur in
the same method" aspect written without cflowdepth.

Interestingly, for this micro-benchmark, it is almost twice
as fast as the cflowdepth version, despite the fact that
the thisJoinPoint objects will contain loads of spurious
information [we only need their identity]. So *if* we
had implemented an optimisation that only constructs those
parts of thisJoinPoint that are actually accessed, it's
quite likely that the thisJP version would be a lot faster
than the cflowdepth one.

Many thanks to Heffalump for fixing a bug that prevented
this yesterday!

-Oege

---------------------------------------------------------

import org.aspectj.lang.*;

aspect LockTraceMatch {

    private static boolean debug;
    private void debPrint(String s) {
        System.out.println(s);
    }

    pointcut anyfunc() : execution( * *(..)) && !within(LockTraceMatch);

    pointcut lock(A r) :
        call(* A.lock()) && target(r);

    pointcut unlock(A r) :
        call(* A.unlock()) && target(r);

    pointcut enclosingExec(JoinPoint jp) :
        cflowbelow(anyfunc() && let(jp,thisJoinPoint));

    //generates a memory leak warning
    perthread tracematch(A r,JoinPoint jp) {

        sym beforefunc before : anyfunc() && let(jp,thisJoinPoint) ;
        sym afterfunc after : anyfunc() && let(jp,thisJoinPoint) ;
        sym lock after : lock(r) && enclosingExec(jp) ;
        sym unlock after : unlock(r) && enclosingExec(jp) ;

        beforefunc lock afterfunc {
            try {
                throw new Exception("Unmatched lock");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

public class JPMain {
    void f(A a) {
        a.lock();
        a.unlock();
    }

    void g(A a) {
        a.lock();
    }

    void h(A a) {
        a.lock();
        f(a);
        g(a);
        a.unlock();
    }

    void k(A a) {
        a.lock();
        f(a);
        g(a);
    }

    void test() {
        A a = new A();
        f(a);
        g(a);
        h(a);
        k(a);
    }

    private static class TestThread extends Thread {
        public void run() {
           new JPMain() .
            test();
        }
    }

    public static void main(String args[]) {
         //This runs fast
        for (int i = 0; i < 10000; i++) {
            new JPMain(). test();
        }

         //This starts out fast, but slows down consderably
        for (int i = 0; i < 10000; i++) {
            Thread t = new TestThread();
            t.start();
        }
    }

}

class A {
    A lock() {
        System.out.println("A.lock");
        return this;
    }
    void unlock() {
        System.out.println("A.unlock");
        return;
    }
}
Received on Wed Dec 14 08:11:49 2005

This archive was generated by hypermail 2.1.8 : Wed Dec 14 2005 - 11:10:08 GMT