Download presentation
Presentation is loading. Please wait.
Published byLynne Harmon Modified over 9 years ago
1
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)
2
What is AspectJ? disciplined metaprogramming
3
The bluffer's guide to aspect-lingo Intertype declarations: inject new members into existing classes at compile-time aspect observes base program when 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
4
EJB policy enforcement public 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"; }
5
Counting live objects per class public 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()); }
6
Authorisation public 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()); }
7
New compiler pass public aspect AspectTransformPass { AspectTransformer Assign.aspectTransformEnter(AspectTransformer at) {.... } Node Assign.aspectTransformLeave(AspectTransformer at) {... } } AST node Assign has subclasses LocalAssign, FieldAssign,...
8
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”
9
Problems with jars vs source public 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: Object A string: String weave aspect into MethodMatch.class: An object: Object An object: String
10
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.
11
Measuring the cost with *J frontend tagging bytecode weaver 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
12
ajc performance
13
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
14
The AspectBench Compiler: ABC AspectJ extension AspectJ source, and jars Polyglot Java compiler aspectInfo Java extracts of source Jimple intertype adjuster advice weaver Soot analysis and transformation framework class files
15
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
16
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
17
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 (); virtualinvoke theAspect. (); nop; theAspect1 = staticinvoke (); adviceformal = $i1; virtualinvoke theAspect1. (adviceformal); nop;
18
ABC performance
19
Win (1) : no closures for around public 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,...)
20
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 completely allow cflow in declare warning/error Sereni et al, AOSD 2003.
21
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: 40KLOC polyglot: 60KLOC Soot: 180KLOC
22
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
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.