abc: The AspectBench Compiler for AspectJ


One of the goals of abc is to be a testbed for compiler optimisations. Here is a list of optimisations that are currently implemented by abc. Unless otherwise indicated, these optimisations are unique to abc at the time of writing (October 14th, 2005). Many other optimisations, both intra- and inter-procedural are actively under development by the abc team.


Name Brief description abc version introduced
cflow stack sharing If cflow is used with the same pointcut as a parameter in multiple places, the stacks required to keep track of whether it should apply or not are shared with each other. 0.9.0
cflow counters If the pointcut used as a parameter to cflow does not bind any values, then a counter is used instead of a stack. 0.9.0
Transformation of thisJoinPoint to thisJoinPointStaticPart If the only uses of thisJoinPoint within an advice body are to retrieve static information from it, it can be transformed to the much more efficient thisJoinPointStaticPart.
This optimisation was originally implemented by ajc.
Lazy thisJoinPoint initialisation Initialisation of the thisJoinPoint variable is quite expensive. It is delayed until it is actually needed by a pointcut if expression or an advice body.
This optimisation was originally implemented by ajc.
Closure-free around implementation abc's implementation of around advice uses a novel strategy that avoids allocating closures in almost all cases. A numeric ID is used to record where the advice body was called from, and this ID is used to execute the appropriate piece of code when calling proceed. 0.9.0
Avoiding unnecessary heap allocation for around context passing Various pieces of context information need to be passed to the advice body and then on to the proceed implementation; primitive values are passed in parameters of an appropriate primitive type rather than being boxed to an Object; this is slightly tricky because different join points may need to pass different types of information to the same advice body. It is achieved by specifying method signatures that have enough parameters of each type for any of the relevant join points, and passing dummy "default" values for the unneeded parameters. 0.9.0
The full details of the around implementation can be found in Sascha Kuzins' MSc dissertation, and also in our PLDI 2005 paper.
Soot backend optimisations The Soot backend includes a number of standard optimisations that improve the quality of generated code. Many of these, such as local packing, nop removal and dead code elimination, are important for cleaning up inefficiencies in the code generated by the weaving process. In particular local packing can have a dramatic effect on the efficiency of generated code in some situations where a lot of advice code has been woven into one method. 0.9.0
Context passing to intertype constructors Intertype introduced constructors need to pass context information to the implementation method located in the aspect class. abc avoids boxing values of primitive type when passing this context information. 0.9.0
cflow stack retrieval CSE Before each operation on a cflow stack, we need to retrieve a thread-local copy of that stack. This optimisation ensures that the thread-local cflow stack is retrieved only once per method body. 0.9.1
advice inlining Advice bodies can be inlined to the join point shadows where the advice might apply. By default, a heuristic is used to decide whether or not to do this to provide a good space/time tradeoff and avoid having to generate too many accessor methods for data that can no longer be accessed directly from the target method, but if required it can be turned off completely or made to inline very aggressively.
ajc implements some inlining for around advice which specialises advice methods for specific join points shadows, but does not inline the advice code directly into the method containing the shadow.
Boxing removal Primitively typed values are sometimes boxed for passing to advice methods to allow the same advice method to be used polymorphically. After inlining, the boxing and unboxing operations can often be removed from each join point shadow. 1.0.1
Interprocedural cflow optimisations By static analysis of the call graph of woven code, it is often possible to completely eliminate the overheads of cflow. This is described in detail in our PLDI 2005 paper. The implementation builds on the Paddle framework. 1.1.0

Valid XHTML 1.1!