Advice Weaving in AspectJ
description
Transcript of Advice Weaving in AspectJ
![Page 1: Advice Weaving in AspectJ](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/1.jpg)
Advice Weaving in AspectJ
Alex Gontmakher
![Page 2: Advice Weaving in AspectJ](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/2.jpg)
Outline
Possible implementation approaches
Quick JVM primer
AJC implementation
Performance Evaluation
![Page 3: Advice Weaving in AspectJ](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/3.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/4.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/5.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/6.jpg)
Compile time code generation
Portable
Fast
Necessarily limited
![Page 7: Advice Weaving in AspectJ](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/7.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/8.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/9.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/10.jpg)
Part 2: JVM Primer
![Page 11: Advice Weaving in AspectJ](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/11.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/12.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/13.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/14.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/15.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/16.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/17.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/18.jpg)
Part 3: Aspects implementation
Munger
Shadow
Residue
![Page 19: Advice Weaving in AspectJ](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/19.jpg)
AspectJ: the processJava source Aspects source
Java bytecode Aspects bytecode
JavaLibrary
AspectsLibraryAspectJ compiler
Weaver
Woven program
shadows mungers
![Page 20: Advice Weaving in AspectJ](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/20.jpg)
Advice Implementation:the 4 questions
WHERE - shadows
WHEN - residues
WHAT - the aspect code
HOW - weaving
![Page 21: Advice Weaving in AspectJ](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/21.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/22.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/23.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/24.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/25.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/26.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/27.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/28.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/29.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/30.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/31.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/32.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/33.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/34.jpg)
Weaving: inlining Advice code is [almost] never inlined
Why? Because JIT does a better work.Avoids code duplication
![Page 35: Advice Weaving in AspectJ](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/35.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/36.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/37.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/38.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/39.jpg)
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](https://reader035.fdocuments.in/reader035/viewer/2022062502/56814d27550346895dba5ae7/html5/thumbnails/40.jpg)
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/