22
ABC: an implementation of AspectJ Oege de Moor Programming Tools Group University of Oxford joint work with Ganesh Sittampalam, Sascha Kuzins, Chris Allan, Pavel Avgustinov, Julian Tibble, Damien Sereni (Oxford) Laurie Hendren, Jennifer Lhoták, Ondřej Lhoták, Bruno Dufour, Christopher Goard, Clark Verbrugge (McGill) Aske Simon Christensen (Århus)

ABC: an implementation of AspectJ

  • Upload
    stacia

  • View
    34

  • Download
    0

Embed Size (px)

DESCRIPTION

Oege de Moor Programming Tools Group University of Oxford joint work with Ganesh Sittampalam, Sascha Kuzins, Chris Allan, Pavel Avgustinov, Julian Tibble, Damien Sereni (Oxford) - PowerPoint PPT Presentation

Citation preview

Page 1: ABC: an implementation of AspectJ

ABC: an implementation of AspectJ

Oege de MoorProgramming Tools Group

University of Oxford

joint work with Ganesh Sittampalam, Sascha Kuzins, Chris Allan,

Pavel Avgustinov, Julian Tibble, Damien Sereni (Oxford)Laurie Hendren, Jennifer Lhoták, Ondřej Lhoták, Bruno Dufour,

Christopher Goard, Clark Verbrugge (McGill)Aske Simon Christensen (Århus)

Page 2: ABC: an implementation of AspectJ

What is AspectJ?

disciplined metaprogramming

Page 3: ABC: an implementation of AspectJ

The bluffer's guide to aspect-lingo

Intertype declarations:inject new members intoexisting classes at compile-time

aspect observes base programwhen certain patterns of events happen,run some extra code

Static:

Dynamic:

“join point” = event = node in (dynamic) call graph

“pointcut” = pattern of events = set of nodes in call graph

“shadow” = program point that corresponds to join point

“advice” = extra code

Page 4: ABC: an implementation of AspectJ

EJB policy enforcementpublic aspect DetectEJBViolations {

pointcut uiCalls() : call(* java.awt.*+.*(..));

before() : uiCalls() && cflow(call(* EnterpriseBean+.*(..))) {System.err.println("UI call from EJB");

}

declare error : uiCalls() && within(EnterpriseBean+) : "UI call from EJB";

pointcut staticMemberAccess() : set(static * EnterpriseBean+.*);

declare error : staticMemberAccess() : "EJBs are not allowed to have non-final static vars";

}

Page 5: ABC: an implementation of AspectJ

Counting live objects per classpublic aspect AllocFree {

public interface Finalize {}

declare parents: mypackage..* implements Finalize;

public void Finalize.finalize() throws Throwable { LiveData.decr(this.getClass());

}

before(Object tgt): initialization(mypackage..*.new(..)) && this(tgt) { LiveData.incr(tgt.getClass());

} }

Page 6: ABC: an implementation of AspectJ

Authorisationpublic abstract aspect AbstractAuthAspect { private Subject _authenticatedSubject; public abstract pointcut authOperations(); ... Object around()

: authOperations() && !cflowbelow(authOperations()) {try { return Subject.doAsPrivileged(_authenticatedSubject,

new PrivilegedExceptionAction() {public Object run() throws Exception { return proceed();}}, null);

} catch (PrivilegedActionException ex) { throw new AuthorizationException(ex.getException());}

}}

Page 7: ABC: an implementation of AspectJ

New compiler passpublic aspect AspectTransformPass {

AspectTransformer Assign.aspectTransformEnter(AspectTransformer at) { ....}

Node Assign.aspectTransformLeave(AspectTransformer at) { ...

} }

AST node Assign has subclasses LocalAssign, FieldAssign, ...

Page 8: ABC: an implementation of AspectJ

ajc: “standard” AspectJ compiler

aspects

java source

jars

ajc class files

● builds on Eclipse compiler● weaving with BCEL● incremental● about 45KLOC, excluding IDE support

“weaving”

● started out as source-to-source● java parts may be aspect-aware

Daniel Sabbah (VP of development@ IBM): “critical to our survival”

Page 9: ABC: an implementation of AspectJ

Problems with jars vs sourcepublic class MethodMatch { public static void main(String[] args) { foo((Object)"Object"); foo("String"); } public static void foo(Object o) { System.out.println("An object: " + o); } }

public aspect NewFoo { public static void MethodMatch.foo(String s) { System.out.println("A string: " + s); } }

compile together from source:

An object: ObjectA string: String

weave aspect into MethodMatch.class:

An object: ObjectAn object: String

Page 10: ABC: an implementation of AspectJ

What do you pay at runtime?

From the FAQ on aspectj.org:

We aim for the performance of our implementation of AspectJ to be on par with the same functionality hand-coded in Java. Anything significantly less should be considered a bug.

...we believe that code generated by AspectJ has negligible performance overhead.

Page 11: ABC: an implementation of AspectJ

Measuring the cost with *J

frontend

tagging bytecodeweaver

modified ajc

JVMPI interface

standard JVM

*J dynamic metric tool

JVMPI agent

metric analyser with

tag propagator

standard metrics

AspectJ-specific metrics

Dufour, Goard et al,OOPSLA 2004

Page 12: ABC: an implementation of AspectJ

ajc performance

DCM ProdLin Bean NllChk Figure LoD0

20

40

60

80

100

120

Overheads(%)Slowdown(*)

Page 13: ABC: an implementation of AspectJ

The need for a second compiler

● language definition other than test suite

● explore AOP language design space

● experiment with better code generation

● experiment with static analyses

for safety checks and optimisations

Page 14: ABC: an implementation of AspectJ

The AspectBench Compiler: ABC

AspectJextension

AspectJsource,and jars

Polyglot Javacompiler

aspectInfo

Java extracts of source

Jimple

intertypeadjuster

advice weaver

Sootanalysis and

transformationframework

class files

Page 15: ABC: an implementation of AspectJ

Polyglot: scope for intertype decls

public class A {

int x;

class B {

int x;

}

}

aspect Aspect {

static int x;

static int y;

int A.B.foo() {

class C {

int x = 3;

int bar() {return x + A.this.x;}

}

return (new C()).bar() + x + y;

}

}

when does field or call refer to host class A.B?● no explicit receiver? if it was introduced

into environment via the ITD, give it “this” from host.● explicit “this” or “super”? if there is no

qualifier and we're not inside a local class,

it refers to the host. If there is a qualifier Q,

it refers to the host if the host has an enclosing

instance of type Q.

implementation:● extend environment type● new AST nodes “hostSpecial” (this/super)● ITDs add accessible members from host● rewrite rules to disambiguate this/super to “Special” or “hostSpecial”

host class

Page 16: ABC: an implementation of AspectJ

Soot: Jimple int foo(int x, int y) {

if (x<y) return (y-x);else return (x-y);

}

int foo(int, int) {

Example this; int x, y, $i0, $i1;

this := @this:Example; x := @parameter0: int; y := @parameter1: int; if x >= y goto label0;

$i0 = y - x; return $i0;

label0: $i1 = x - y; return $i1; }

want to weave:aspect Aspect { after() returning : execution(* foo(..)) {

System.out.println("woven"); } after() returning(int x) : execution(int foo(..)) {

System.out.println("result="+x); } }

normal compilation

Page 17: ABC: an implementation of AspectJ

Weaving at shadows this := @this:Example; x := @parameter0: int; y := @parameter1: int; nop; if x >= y goto label0;

$i0 = y - x; $i1 = $i0; goto label1;

label0: $i1 = x - y;

label1: nop; return $i1; }

nop;

theAspect = staticinvoke <Aspect: Aspect

aspectOf()>();

virtualinvoke theAspect.<Aspect: void

afterReturning$0()>();

nop;

theAspect1 = staticinvoke <Aspect: Aspect

aspectOf()>();

adviceformal = $i1;

virtualinvoke theAspect1.<Aspect: void

afterReturning$1(int)>

(adviceformal);

nop;

Page 18: ABC: an implementation of AspectJ

ABC performance

dcm prdlin bean nllchk figure LoD0

2

4

6

8

10

12

14

16

ajc/abc

JIT interpreter

Page 19: ABC: an implementation of AspectJ

Win (1) : no closures for aroundpublic class ShadowClass implements AroundClosure$1 {

public [ret-type] proceed(int shadowID, [arg-type] arg1, ...) {switch(shadowID) {

case 0:... do what first shadow did ...

case 1:... do what second shadow did ...

}}

public void shadowMethod() {... Aspect.aspectOf().adviceMethod$1(this,0,arg1,...); ...

}

public void anotherShadowMethod() {... Aspect.aspectOf().adviceMethod$1(this,1,arg1,...); ...

}}

calls thisparam.proceed(0,...)

calls thisparam.proceed(1,...)

Page 20: ABC: an implementation of AspectJ

Win (2) : no stacks for cflow

cflow(call(* foo(..))) && call (* bar(..))

matches call stack:

bar

foo

...

...

ajc:● simulates call stack by pushing and

popping around foo calls ● one stack per thread

abc:● use counter in lieu of stack when possible● CSE on cflow expressions● look up thread-local stack/counter only once per body ● static estimate of possible call stacks can

eliminate runtime cost completelyallow cflow in declare warning/error

Sereni et al, AOSD 2003.

Page 21: ABC: an implementation of AspectJ

Extensibility of abc

three extensions:● local variables in pointcuts● cast pointcut● global pointcuts

● 3 new ast classes● 3 new weaver classes● override 1 ast class● 1 new node factory● 1 new visitor pass● total 946 lines● enable with compiler flags

in the works:pointcuts that query program trace“pure” modifier on aspects

size of abc: 40KLOCpolyglot: 60KLOCSoot: 180KLOC

Page 22: ABC: an implementation of AspectJ

ABC Summary● Implements the same language as ajc● Whole-program, aimed at

– extensibility

– static analysis

– performance of compiled code

● Suite of associated tools: decompiler, performance measurement, visualisation in Eclipse

● Current status:– pass majority of ajc test suite

– likely release mid-October:complete development in 9 months