Advice Weaving in AspectJ

40
Advice Weaving in AspectJ Alex Gontmakhe r

description

Advice Weaving in AspectJ. Alex Gontmakher. Outline. Possible implementation approaches Quick JVM primer AJC implementation Performance Evaluation. Approaches to Aspect code generation. Change the VM to recognize aspects Compile-time weaving of aspects Load-time weaving Reflection. - PowerPoint PPT Presentation

Transcript of Advice Weaving in AspectJ

Page 1: Advice Weaving in AspectJ

Advice Weaving in AspectJ

Alex Gontmakher

Page 2: Advice Weaving in AspectJ

Outline

Possible implementation approaches

Quick JVM primer

AJC implementation

Performance Evaluation

Page 3: Advice Weaving in AspectJ

Approaches to Aspect code generation

Change the VM to recognize aspects

Compile-time weaving of aspects

Load-time weavingReflection

Page 4: Advice Weaving in AspectJ

Changing the VM Can provide full support for all Aspect

features Data for aspects separate from the code Not portable (generated code is not Java

bytecode) Problems with the reference Java

implementationHard to make changes to Java standardHard to evolve AspectJ implementation

Page 5: Advice Weaving in AspectJ

Load-time weaving Modify the code during loading Probably can be done

Same benefits as with VM-supported aspects Potentially slow

Trade-Off between load-time and run-timeExpensive to do static analysis (optimization)

Page 6: Advice Weaving in AspectJ

Compile time code generation

Portable

Fast

Necessarily limited

Page 7: Advice Weaving in AspectJ

Compile-time code generation:The problem

before(): get(int Point.x) { System.out.println(“get x”); }

Compiler doesn't see all the code Code that is dynamically loaded Code that is called through reflection

Page 8: Advice Weaving in AspectJ

Compile-time code generation:Solution

AspectJ solution: aspects apply only to code that the implementation controls

Loosely speaking: all the bytecode available at compile time Can change between implementations and versions

Page 9: Advice Weaving in AspectJ

Compile-time code generation:The limitations Advice on field access

Accessor code must be available Advice on method and constructor call

Calling code must be available Advice on method execution

The method code must be available Etc.

Limitations not met Compile time error!

Page 10: Advice Weaving in AspectJ

Part 2: JVM Primer

Page 11: Advice Weaving in AspectJ

Java Virtual Machine: structure

Frame 0

Frame 1

Frame 2

SP

Stack (per thread)Constant Pool

Class Hellomethod: print()method: <init>()

Class Mainmethod: main()method: <init>() field: int fM

String “hello world”

Frame 2

locals:thisint iint j

Param stack:System.outString…

Class:

Frame 1

locals:this

Param stack:Hello

Class:

HeapObject Hellofield: int f1field: String f2

Page 12: Advice Weaving in AspectJ

JVM primer: instructions 1

Arithmetic Instructions take inputs from param stack, write results back

Getting values to and from local vars Getting values to and from objects Method calls and returns Exception handling Etc.

Page 13: Advice Weaving in AspectJ

JVM Primer: instructions 2 Arithmetic instructions

iadd: …, value1, value2 …, value1+value2 Load and store local variables

iload VAR: … …, <local variable[VAR]> iload_<n>: … …, <local variable[N]> istore VAR: …, value … {VAR = value} istore_<n>: …, value … {VAR_n = value}

Stack manipulation dup: …, value …, value, value

Page 14: Advice Weaving in AspectJ

JVM primer: instructions 3

Object accessAccessing object’s fields: getfield, putfield

getfield FID: …, objectref …, valueputfield FID: …, value, objectref …

Accessing object’s static fields: getstatic, putstaticgetstatic FID: … …, valueputstatic FID: ..., value …

Page 15: Advice Weaving in AspectJ

JVM primer: instructions 4 Calling methods:

invokevirtual N:…, param1, [param2,…] resultcalls Nth method of class

invokespecial Ncalls constructors etc.

invokestatic N Invokeinterface N return, ireturn, …

Creating objects:new N – allocates and inits memory.Then, constructor must be called

Page 16: Advice Weaving in AspectJ

JVM Primer: exampleint i; // An instance variableMyObj example() { MyObj o = new MyObj(); return silly(o);}MyObj silly(MyObj o) { if (o != null) { return o; } else { return o; }}

Method MyObj example() 0 new [Class MyObj] 3 dup 4 invokespecial [MyObj.<init>()] 7 astore_1 8 aload_0 9 aload_1 10 invokevirtual [silly] 13 areturn

Method MyObj silly(MyObj) 0 aload_1 1 ifnull 6 4 aload_1 5 areturn 6 aload_1 7 areturn

Page 17: Advice Weaving in AspectJ

JVM primer: exception handling

Exception handling throw N: throw an exception of class NException table:

FROM TO Class Handler

1 3 17 8

Page 18: Advice Weaving in AspectJ

Part 3: Aspects implementation

Munger

Shadow

Residue

Page 19: Advice Weaving in AspectJ

AspectJ: the processJava source Aspects source

Java bytecode Aspects bytecode

JavaLibrary

AspectsLibraryAspectJ compiler

Weaver

Woven program

shadows mungers

Page 20: Advice Weaving in AspectJ

Advice Implementation:the 4 questions

WHERE - shadows

WHEN - residues

WHAT - the aspect code

HOW - weaving

Page 21: Advice Weaving in AspectJ

Join Point Shadows: WHERE Static code sections that potentially match

a join point Example: “hello world”public static void main(String[] s) { System.out.println(“hello world”);}

0: getstatic [java/lang/System.out]

3: ldc [String “hello world”]

5: invokevirtual [java/io/Printstream.println]

8: return

Field-getTarget: from stackArgs: none

Method-callTarget: From stackArgs: From stack!Parameters must be stored and re-loaded

Method-executionTarget: thisArgs: local vars

Page 22: Advice Weaving in AspectJ

Join Point Shadows: Notes Java bytecodes carry plentiful meta-

information Instructions’ intent easily recognizableShadow is completely defined by region of

codeNo need for source code!

It is sometimes impossible to determine statically if aspect should be executed residue

Page 23: Advice Weaving in AspectJ

Advice compilation: WHAT Each advice compiles to a regular Java

methodParameters statically typed

used for matchingAdvice always runs in the context of aspect

instanceAdditional information encoded in attributes

Each residue compiles to a regular Java method

Page 24: Advice Weaving in AspectJ

Residues: WHENDynamic part of the pointcutResidue types:

if Computes conditions on parameters Parameters passed if necessary

instanceof Checks type

cflow Check the stack for cflow conditions Store cflow status in the stack Each relevant join point checks the status

Page 25: Advice Weaving in AspectJ

Residues example: if residuebefore(): execution(void main(*)) && if(Tracing.level == 1) { System.out.println(“here”);}

0: invokestatic [A.ajc$if_0]3: ifeq 126: invokestatic [A.aspectof]9: invokevirtual [A.ajc$before$A$a6]12: getstatic [java/lang/System.out]15: ldc [String “hello world”]17: invokevirtual [java/io/Printstream.println]20: return

Residue

Aspect

Page 26: Advice Weaving in AspectJ

Residues example: instanceofbefore(String s): execution(void go(*)) && args(s) { System.out.println(s);} Case 1: void go(java.lang.String) { }

Advice is always called

Case 2: void go(java.lang.Object) { }

Advice called only if the parameter is a String

Page 27: Advice Weaving in AspectJ

Residues: instanceof contd

void go(java/lang/Object); 0: aload_1 1: astore_2 2: aload_2 3: instanceof [String] 6: ifeq 14 # skip advice 9: invokestatic [A.aspectOf] 10: aload_1 13: invokevirtual [A.ajc$before$A$a3] 16: return

Residue

Aspect

Page 28: Advice Weaving in AspectJ

Residues: cflow On entry to the method, compute the cflow

conditionsStore the result in a local variableAt the join point, check the variable

The test is completely dynamicStatic optimization would need whole-program

analysis

Page 29: Advice Weaving in AspectJ

The Matching process1. For each advice:

Create a shadow munger

2. For each shadow munger: For each class:

For each shadow, apply the munger [optimization] If the munger has withincode

attribute, check only in that method

Page 30: Advice Weaving in AspectJ

Weaving: HOW Expose the context

Copy stack parametersPush local variables (for calls)Create a JoinPoint object if necessary

Reflective information on the join point: getKind(), getSignature(), getLocation(), getArgs(), …

Done once per shadow Insert the advice code

Implementation depends on advice kindWeaving in inverse precedence order

Page 31: Advice Weaving in AspectJ

Weaving: advice types Before advice

Advice code just inserted in the beginning of the shadow

After returning adviceCall:

Expose the return valueInsert the code in the end of the shadow

Execution:All the return points must be capturedGenerate gotos into a single return point

Page 32: Advice Weaving in AspectJ

Weaving: more advice types After throwing advice

Add a new exception handler in the enclosing method

After finally adviceCombine After returning and After throwing

Control flow entry adviceSame as before advice

Control flow exit adviceSame as After finally advice

Page 33: Advice Weaving in AspectJ

Weaving: more advice types Around advice

Replaces the original shadow code If no call to proceed, just inline the advice code If there is a call to proceed:

class Closure$i extends AroundClosure { public void run() { // perform the advised code }}Create the Closure$i object and pass it as a parameter to

advice Declare warning and error

Just print the message, no bytecode changes

Page 34: Advice Weaving in AspectJ

Weaving: inlining Advice code is [almost] never inlined

Why? Because JIT does a better work.Avoids code duplication

Page 35: Advice Weaving in AspectJ

Aspects performance: Benchmark Xalan – XSLT processor

826 source files, 7700 methods, 144K lines of code Measure the slowdown caused by aspects Compare to hand-coded version

public aspect Trace { private static Logger log = Logger.getLogger(“xalan”); pointcut traced(): execution(* *(..)); before(): traced() { Signature s = thisJoinPointStaticPart.getSignature(); log.entering( s.getDeclaringType().getName(), s.getname()); }}

Page 36: Advice Weaving in AspectJ

Aspects Performance: first results

Loggingenabled

Loggingdisabled

0

5

10

15

20

25

30

35

no logging hand-coded naïve AspectJ

Logg

ing

Ove

rhea

d

Page 37: Advice Weaving in AspectJ

Aspects performance: optimizing Avoid class.getName() if not used

before() traced() { if (!log.isLoggable(Level.FINER)) return; …}

Check log.isLoggable in the residuepointcut traced(): execution(* *(..)) && if (log.isLoggable(Level.FINER)); Avoids method call of the aspect

Store the result of log.isLoggable()pointcut traced(): … && if (enabled) && log.isLoggable() Faster than hand-coded version

Remove the aspect altogether

Page 38: Advice Weaving in AspectJ

Aspects performance: results Best implementation: 76% better than

handcoded Same could be done manually, but impractical

0

0.2

0.4

0.6

0.8

1

1.2

1.4

no logging hand-coded AspectJloggable

AspectJif(loggable)

AspectJif(enabled)

Ove

rhea

d

Page 39: Advice Weaving in AspectJ

Conclusions

Weaving advices in Java is easyRich bytecodeC++ would be much harder – certainly would

require source code access!

More static analysis will allow for faster code

Page 40: Advice Weaving in AspectJ

References

Advice weaving in AspectJ, Eric Hillsdale and Jim Hugunin, In Proceedings of AOSD'04

The AspectJ project homepage, http://eclipse.org/aspectj

The JVM Specification book, http://java.sun.com/docs/books/vmspec/