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 10:15:24 2005
This archive was generated by hypermail 2.1.8 : Sun Dec 11 2005 - 13:10:10 GMT