Optimizing AspectJ

Post on 11-Jan-2016

24 views 0 download

Tags:

description

Optimizing AspectJ. Pavel Avgustinov, Aske Simon Christensen, Laurie Hendren, Sascha Kuzins, Jennifer Lhotak, Ondrej Lhotak, Oege de Moor, Damien Sereni, Ganesh Sittampalam, Julian Tibble Oxford University University of Aarhus McGill University PLDI 2005. Presented by Geoff Hulette. - PowerPoint PPT Presentation

Transcript of Optimizing AspectJ

Optimizing AspectJ

Pavel Avgustinov, Aske Simon Christensen, Laurie Hendren, Sascha Kuzins, Jennifer Lhotak, Ondrej Lhotak,

Oege de Moor, Damien Sereni, Ganesh Sittampalam, Julian Tibble

Oxford UniversityUniversity of Aarhus

McGill University

PLDI 2005

Presented by Geoff Hulette

What is AspectJ?

• Aspect-Oriented Programming (AOP) language extension for Java

What is AOP?

• AOP addresses cross-cutting concerns

• Examples: logging, debug traces, method-level security

• Goal: remove cross-cutting concerns from objects, put them in aspects

What is an Aspect?

• Join point: span of code in the execution of a program

• Pointcut: query that picks out join points

• Advice: code to execute at a join point

Why Optimize?

• Dynamic model naïve compilers add considerable overhead

• Fortunately, a lot of advice can be compiled statically

Case 1: Around Advice

• Executes instead of a join point, but can transfer control back into the join point using proceed()

• Problem: how do you know where proceed should take you?

Standard Solution

• Closures: pass an object to the advice method with the right code and context

• “Inlining”: duplicate the advice method for each join point

ABC’s Solution

• Keep proceed method in the original class

• Call the advice method with IDs for the originating class and join point

• Sort it out with a switch statement

Results

• Code is 25% smaller, on average.

• Recursive execution times are much faster (3 to 6 times) when recursive advice is applied, about the same otherwise

• ABC is insensitive to recursive advice

Case 2: cflow

• Cflow(p): picks out join points in the control flow of p

• Example pointcut: cflow(call(bar())) && call(foo())

AJC’s Solution

• Create a stack for each cflow

• Where p becomes true, push context

• At join points, test if stack is non-empty

First the easy stuff

• Combine cflow stacks:

cflow(call(a())) && call(b)||cflow(call(a())) && call(c) cflow(call(a())) && (call(b)||call(c))

• Use counters instead of stacks, if possible

• Cache stacks/counters

Then the hard stuff

• Goal: classify instructions to make dynamic checks into static ones

Examples

MayCflow

• Instructions are in mayCflow(sh) if they may be in the scope of update shadow sh

• If a query is not in mayCflow, we can replace it with neverMatch

Compute MayFlow

• Begin with instructions in an update shadow (between push and pop)

• Add all instructions that might be called from within

MustCflow

• Instructions are in MustCflow(stack) if that instruction is always in that cflow

• Replace queries in set with alwaysMatch

Compute MustFlow

• Pre-compute a list of all statements within a cflow that have no dynamic queries

• Start with all statements

• Eliminate those that can be reached from entry points without passing through the pre-computed list

NecessaryShadows

• Set of update shadows whose effects may be observed, and whose effects are not duplicated

• Any update shadow not in this set can be eliminated

Compute NecessaryShadows

• The set of update shadows whose mayFlow sets contain no dynamic queries

• Also remove those that are in the mustflow of another update

Results

• Easy stuff led to biggest gains (up to 54x)

• Hard stuff helped too, but generally not much

Other Optimizations

• Static Joinpoint data

• Eliminate boxing/unboxing

• Other standard optimizations