It would actually be interesting to discuss cflow(depth) in the
paper - often when I first describe tracematches in a casual conversation,
people ask whether you cannot express these things with cflow in AspectJ
already.
So I think it makes a valid benchmark in a paper about general language
mechanisms for trace monitoring: cflow is such a feature, albeit a rather
restricted one. Because it is very restricted, we can implement it
efficiently.
In the same vein, perhaps we ought to have another (more realistic)
benchmark where cflow is expressed via PQL queries - any of our old cflow
benchmarks will do.
-Oege
On Sun, 11 Dec 2005, Pavel Avgustinov wrote:
> I've run into some unexpected conceptual complications trying to express
> Walker's safe-unsafe method call example.
>
> Here a summary of it for those who are unfamiliar with it:
>
> Suppose you have methods getConnection() and getOptimalConnection().
> However, getOptimalConnection() requires certain invariants to be in
> place when it is called, as otherwise it fails. These invariants are
> established by methods matched by a pointcut safe(), and they are
> destroyed by methods matched by a pointcut unsafe(). The base program
> contains only calls to getConnection(). The task is to replace these
> with calls to getOptimalConnection() wherever possible.
>
> The tracecut implementation does it like this:
>
> tracecut a() ::= entry(safe());
> tracecut b() ::= exit(safe());
> tracecut c() ::= entry(unsafe());
> tracecut d() ::= exit(unsafe());
> tracecut completed() ::= a() [completed()] b() | c() [completed()] d();
> tracecut isSafe() ::= a() completed()* $;
>
> It then proceeds to add around advice on getConnection() whenever
> isSafe() holds of the execution history.
>
> Now, it is true that we can express this benchmark given cflowdepth --
> unfortunately, however, we don't need tracematches:
>
> around(int safeDepth, int unsafeDepth) : call(getConnection()) &&
> ((cflow(safe()) && !cflowbelow(safe)) ||
> (cflowdepth(safe(), safeDepth) && cflowdepth(unsafe(),
> unsafeDepth) && if(safeDepth > unsafeDepth))) {
> getOptimalConnection();
> }
>
> This, of course, makes for an exceedingly poor tracematch benchmark, as
> it doesn't involve any TMs. Now, we could, in theory, express it as a
> proper tracematch, as follows:
>
> pointcut either() : safe() || unsafe();
> void tracematch(int depth) {
> sym beforeSafe : before(safe());
> sym beforeCompleted : before(either() && cflowdepth(either(), depth)
> && !cflowbelow(either());
> sym afterCompleted : after(either() && cflowdepth(either(), depth);
> sym replaceableCall : around(call(getConnection()));
>
> beforeSafe (beforeCompleted afterCompleted)* replaceableCall {
> getOptimalConnection();
> }
> }
>
> This seems to me, however, to be significantly more cumbersome than the
> "pure EAJ" version, and therefore makes me wonder if it makes a good
> benchmark. Also, I couldn't think of a simple variation of the example
> that would be inexpressible in both EAJ (with no TMs) and in TMs with no
> cflowdepth().
>
> Opinions on what we should do about this?
>
> - P
>
>
Received on Sun Dec 11 13:04:39 2005
This archive was generated by hypermail 2.1.8 : Sun Dec 11 2005 - 16:50:10 GMT