1 / 40

Advice Weaving in AspectJ

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.

monty
Download Presentation

Advice Weaving in AspectJ

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Advice Weaving in AspectJ Alex Gontmakher

  2. Outline • Possible implementation approaches • Quick JVM primer • AJC implementation • Performance Evaluation

  3. Approaches to Aspect code generation • Change the VM to recognize aspects • Compile-time weaving of aspects • Load-time weaving • Reflection

  4. 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 implementation • Hard to make changes to Java standard • Hard to evolve AspectJ implementation

  5. 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-time • Expensive to do static analysis (optimization)

  6. Compile time code generation • Portable • Fast • Necessarily limited

  7. 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

  8. 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

  9. Compile-time code generation:The limitations Limitations not met Compile time error! • 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.

  10. Part 2: JVM Primer

  11. Frame 2 Frame 1 Class: Class: locals: this … locals: this int i int j Param stack: Hello … Param stack: System.out String … Java Virtual Machine: structure Constant Pool Stack (per thread) ClassHello method: print() method: <init>() ClassMain method: main() method: <init>() field: int fM SP Frame 2 String “hello world” Frame 1 Heap ObjectHello field: int f1 field: String f2 Frame 0

  12. 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.

  13. 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

  14. JVM primer: instructions 3 • Object access • Accessing object’s fields: getfield, putfieldgetfield FID: …, objectref  …, valueputfield FID: …, value, objectref  … • Accessing object’s static fields: getstatic, putstaticgetstatic FID: …  …, valueputstatic FID: ..., value  …

  15. 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

  16. int i; // An instance variable MyObj 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 JVM Primer: example

  17. JVM primer: exception handling • Exception handling • throw N: throw an exception of class N • Exception table:

  18. Munger Part 3: Aspects implementation Shadow Residue

  19. AspectJ: the process Java source Aspects source Java Library Aspects Library AspectJ compiler Java bytecode Aspects bytecode Weaver  mungers  shadows Woven program

  20. Advice Implementation:the 4 questions • WHERE - shadows • WHEN - residues • WHAT - the aspect code • HOW - weaving

  21. 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-get Target: from stack Args: none Method-execution Target: this Args: local vars Method-call Target: From stack Args: From stack !Parameters must be stored and re-loaded

  22. Join Point Shadows: Notes • Java bytecodes carry plentiful meta-information • Instructions’ intent easily recognizable • Shadow is completely defined by region of code • No need for source code! • It is sometimes impossible to determine statically if aspect should be executed residue

  23. Advice compilation: WHAT • Each advice compiles to a regular Java method • Parameters statically typed used for matching • Advice always runs in the context of aspect instance • Additional information encoded in attributes • Each residue compiles to a regular Java method

  24. Residues: WHEN • Dynamic part of the pointcut • Residue 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

  25. Residues example: if residue before(): execution(void main(*)) && if(Tracing.level == 1) { System.out.println(“here”); } 0: invokestatic [A.ajc$if_0] 3: ifeq 12 6: 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

  26. Residues example: instanceof before(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

  27. 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

  28. Residues: cflow • On entry to the method, compute the cflow conditions • Store the result in a local variable • At the join point, check the variable • The test is completely dynamic • Static optimization would need whole-program analysis

  29. The Matching process • For each advice: • Create a shadow munger • 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

  30. Weaving: HOW • Expose the context • Copy stack parameters • Push 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 kind • Weaving in inverse precedence order

  31. Weaving: advice types • Before advice • Advice code just inserted in the beginning of the shadow • After returning advice • Call: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

  32. Weaving: more advice types • After throwing advice • Add a new exception handler in the enclosing method • After finally advice • Combine After returning and After throwing • Control flow entry advice • Same as before advice • Control flow exit advice • Same as After finally advice

  33. 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

  34. Weaving: inlining • Advice code is [almost] never inlined • Why? Because JIT does a better work. • Avoids code duplication

  35. 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()); } }

  36. Aspects Performance: first results • Loggingenabled • Loggingdisabled

  37. Aspects performance: optimizing • Avoid class.getName() if not used before() traced() { if (!log.isLoggable(Level.FINER)) return; … } • Check log.isLoggable in the residue pointcut 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

  38. Aspects performance: results • Best implementation: 76% better than handcoded • Same could be done manually, but impractical

  39. Conclusions • Weaving advices in Java is easy • Rich bytecode • C++ would be much harder – certainly would require source code access! • More static analysis will allow for faster code

  40. 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/

More Related