Pointcuts and Analysis

893 views
805 views

Published on

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
893
On SlideShare
0
From Embeds
0
Number of Embeds
54
Actions
Shares
0
Downloads
0
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Pointcuts and Analysis

  1. 1. Pointcuts and Analysis Oege de Moor, Oxford on behalf of the abc team: Pavel Avgustinov, Eric Bodden, Torbj ő rn Ekman, Elnar Hajiyev, Laurie Hendren, Ond ř ej Lhot á k, Oege de Moor, Neil Ongkingco, Damien Sereni, Ganesh Sittampalam, Julian Tibble
  2. 2. Swing thread safety (Ramnivas Laddad) Once a component is visible only the event-dispatching thread can safely access or modify the state of the realized component. (but some methods are exempt)
  3. 3. Doing it by hand… interface Runnable { void run(); } asynchronous invocation: EventQueue.invokeLater(Runnable run) synchronous invocation: EventQueue.invokeAndWait(Runnable run)
  4. 4. With an aspect… void around () : routedMethods() && voidReturnValueCalls() && !uiSyncMethodCalls() { Runnable worker = new Runnable() { public void run() { proceed (); }}; EventQueue.invokeLater(worker); } only once instead of scattered over Swing client program
  5. 5. Some of the pointcuts <ul><li>pointcut viewMethodCalls() </li></ul><ul><li>: call (* javax..JComponent+.*(..)); </li></ul><ul><li>pointcut modelMethodCalls() </li></ul><ul><li>: call (* javax..*Model+.*(..)) </li></ul><ul><li>|| call (* javax.swing.text.Document+.*(..)); </li></ul><ul><li>pointcut uiMethodCalls() </li></ul><ul><li>: viewMethodCalls() || modelMethodCalls(); </li></ul><ul><li>pointcut uiSyncMethodCalls() : </li></ul><ul><li>call (* javax..JOptionPane+.*(..)); </li></ul>
  6. 6. Nice example of aspects: <ul><li>Clean solution to awkward problem </li></ul><ul><li>Instead of polluting application code, describe policy in one place </li></ul><ul><li>Pointcut language is concise and intuitive </li></ul>
  7. 7. QUIZ: pointcuts are intuitive? Given types with fully qualified names a.b.c.SomeType a.b.c.SomeType.ANestedType <ul><li>In a.b.c.Aspect, which patterns have NO matches? </li></ul><ul><ul><ul><ul><li>SomeType </li></ul></ul></ul></ul><ul><ul><ul><ul><li>*..SomeType </li></ul></ul></ul></ul><ul><ul><ul><ul><li>a.b.c.* </li></ul></ul></ul></ul><ul><ul><ul><ul><li>SomeType.ANestedType </li></ul></ul></ul></ul><ul><ul><ul><ul><li>SomeType.* </li></ul></ul></ul></ul><ul><ul><ul><ul><li>ANestedType </li></ul></ul></ul></ul><ul><ul><ul><ul><li>Some*.ANestedType </li></ul></ul></ul></ul><ul><ul><ul><ul><li>a.b.c..ANestedType </li></ul></ul></ul></ul>(first prize: free copy of abc; second prize: free copy of ajc)
  8. 8. Rules for matching type patterns <ul><li>The pattern is matched against the fully-qualified name of the candidate type, and matches only if that fully-qualified name is “lexically” matched by the type pattern. [imports etc are not taken into account] </li></ul><ul><li>If the pattern contains no wildcards at all it matches only the type that would result from resolving the exact same string using normal Java scoping rules. </li></ul>Adrian Colyer : Bug 141133.
  9. 9. This talk <ul><li>Semantics of static pointcuts: </li></ul><ul><ul><li>Shadow labelling </li></ul></ul><ul><ul><li>Pointcuts are relational queries </li></ul></ul><ul><ul><li>Translating pointcuts to queries </li></ul></ul><ul><li>Queries beyond AspectJ </li></ul><ul><ul><li>Static call graph analysis </li></ul></ul><ul><li>Everything is a joinpoint </li></ul><ul><ul><li>Intercept any instruction </li></ul></ul><ul><li>Aspect interfaces </li></ul><ul><ul><li>Taming the (newly introduced) power </li></ul></ul>POPL 2007 speculative
  10. 10. Semantics of static pointcuts Walker et al. : - formalise shadow matching via explicit labels - operational semantics for explicit labels
  11. 11. From static pointcuts to label sets (0) <ul><li>public class X { </li></ul><ul><li>void f1(int n) { } </li></ul><ul><li>void f2(int n) { f1(n); } </li></ul><ul><li>void f3(int n) { f2(n); } </li></ul><ul><li>public static void </li></ul><ul><li>main(String[] args) { </li></ul><ul><li>X x = new X(); </li></ul><ul><li>x.f3(0); </li></ul><ul><li>x.f2(1); </li></ul><ul><li>} </li></ul><ul><li>} </li></ul>aspect A { pointcut a ( int n) : call (* f*(..)) && args (n) && cflowbelow ( execution (* f3(..))); before ( int n) : a(n) { System.out.println( thisJoinPoint + &quot;: n=&quot;+n); } }
  12. 12. From static pointcuts to label sets (1) <ul><li>public class X { </li></ul><ul><li>void f1(int n) { L1:{} } </li></ul><ul><li>void f2(int n) { L2: { L3: { f1(n); } } } </li></ul><ul><li>void f3(int n) { L4 : {L5: { f2(n); } } } </li></ul><ul><li>public static void </li></ul><ul><li>main(String[] args) { </li></ul><ul><li> L6 : { X x = L7 : {new X()}; </li></ul><ul><li> L8 : {x.f3(0)}; </li></ul><ul><li> L9 : {x.f2(1)}; </li></ul><ul><li>} </li></ul><ul><li>} </li></ul>aspect A { pointcut a ( int n) : label (L3,L5,L8,L9) // call (* f*(..)) && args (n) && cflowbelow ( label (L4) // execution (* f3(..)) ); before ( int n) : a(n) { System.out.println( thisJoinPoint + &quot;: n=&quot;+n); } }
  13. 13. Pointcuts are queries (0) <ul><li>Store program as a set of primitive relations, e.g. </li></ul><ul><li>methodDecl( MethodId , Name , Sig , DeclType , RetType ) </li></ul><ul><li>callShadow( ShadowId , Method , ReceiverType ) </li></ul><ul><li>executionShadow( ShadowId , Method ) </li></ul>(Naïve) query for pointcut “ call (* f*(..))” : p( S ) Ã 9 M : method , N : string . callShadow( S , M , _), methodDecl( M , N , _, _, _), regexpmatch(’f.*’, N ).
  14. 14. Pointcuts are queries (1) <ul><li>Store program as a set of primitive relations, e.g. </li></ul><ul><li>methodDecl( MethodId , Name , Sig , DeclType , RetType ) </li></ul><ul><li>callShadow( ShadowId , Method , ReceiverType ) </li></ul><ul><li>executionShadow( ShadowId , Method ) </li></ul>(Naïve) query for pointcut “ execution (* f3(..))” : p( S ) Ã 9 M : method , N : string . executionShadow( S , M ), methodDecl( M , N , _, _, _), regexpmatch(’f3’, N ).
  15. 15. Overview of semantics <ul><li>Find shadows, store in database relations </li></ul><ul><li>Take pointcuts, rewrite to queries [set of 90 simple rewrite rules] </li></ul><ul><li>Run queries </li></ul><ul><li>Results are instrumentation points </li></ul>
  16. 16. Query language: Datalog <ul><li>Series of backward implications </li></ul><ul><li>p(X 1 : t 1 , X 2 : t 2 , … , X n : t n ) Ã </li></ul><ul><li>q 1 (Y 1 , .., Y k ), … , q m (Z 1 , .., Z j ) . </li></ul><ul><li>Conjunctions indicated by comma </li></ul><ul><li>Disjunctions indicated by semi-colon </li></ul><ul><li>Query itself is formula with free variables </li></ul>
  17. 17. Powered by Tarski (1902-1983) <ul><li>(subject to mild restrictions) </li></ul><ul><li>“ least solution” of implications </li></ul><ul><li>all queries terminate </li></ul><ul><li>all queries have a finite result </li></ul><ul><li>NO surprises </li></ul><ul><li>very deeply investigated in theory of databases </li></ul>
  18. 18. Datalog has two kinds of relations <ul><li>Primitive: stored in database relational representation of program </li></ul><ul><li>Rules: implication rules written in program e.g. for testing transitive subtype relation </li></ul>
  19. 19. Example rule hasSubtype*( T : type , T : type ) . hasSubtype*( T : type , S : type ) Ã 9 U : type . hasSubtype( T , U ), hasSubtype*( U , S ) . hasSubtype is primitive (= stored in database)
  20. 20. Mapping pointcuts to queries <ul><li>Given pointcut pc </li></ul><ul><li>Define query pcq ( Context : type , S : shadow ) </li></ul><ul><li>which is true precisely when shadow S matches pointcut pc declared in type Context </li></ul><ul><li>[ Context is needed for name resolution, Quiz 1] </li></ul>
  21. 21. Example: call versus execution class A { void m() {} } class B extends A {} class C extends B { void m() {} } pointcut c() : call (* B.m(..)); pointcut e() : execution (* B.m(..)); (new A()).m(); (new B()).m(); (new C()).m(); QUIZ 2: Where does c() match? Where does e() match?
  22. 22. Query for c() : call (* B.m(..)) c( Context : type , Shadow : shadow )  9 M : method , Recv : type , N : method . matchpat( Context , M , Recv ) , overrides( N , M ) , callShadow( Shadow , N , Recv ) . reflexive relation overrides(N,M)
  23. 23. Matching method patterns matchpat( Context : type , M : method , Recv : type )   T : type , MD : type . simpleTypeLookup( Context , ‘B’ , T ), hasSubtype*( T , Recv ), methodDecl( M , ‘ m ’ , _, MD , _), ( ( hasStrModifier( M , ‘static ’), MD = T ) ; ( not (hasStrModifier( M , ‘static’ )), hasSubtype*( MD , T ) ) ) .
  24. 24. Query for e() : execution (* B.m(..)) e( Context : type , Shadow : shadow )   M : method , Recv : type , N : method . matchpat( Context , M , Recv ), overrides( N , M ), hasChild( Recv , N ), executionShadow( Shadow , N ) . difference with call
  25. 25. Semantics of static AspectJ pointcuts All static pointcuts covered Only 90 rewrite rules Concrete syntax implementation with Stratego
  26. 26. Flavour of rewrite rules (0) aj2dl (pc1 && pc2, C , S )  aj2dl (pc1, C , S ), aj2dl (pc2, C , S ) aj2dl (pc1 || pc2, C , S )  aj2dl (pc1, C , S ) ; aj2dl (pc2, C , S ) aj2dl (not(pc), C , S )  not ( aj2dl (pc, C , S ))
  27. 27. Flavour of rewrite rules (1) <ul><li>fieldmembpat2dl (namepat..snamepat, C , R , X ) </li></ul><ul><li> </li></ul><ul><li>Y : packageOrType , Z : type , P : type . </li></ul><ul><li>wcnamepat2dl (namepat, Y ), hasChild+( Y , Z ), </li></ul><ul><li>hasSubtype*( P , Z ), hasChild( P , X ), field( X ), </li></ul><ul><li>snamepat2dl (snamepat, X ), </li></ul><ul><li>hasSubtype*( Z , R ) . </li></ul>this is as complex as it gets
  28. 28. Implementation AspectJ program relational database (M$ SQL Server) pointcuts Datalog program Shadow Grab (modified abc) Strip from source Stratego rewrites Matched shadows Procedural SQL CodeQuest compiler primitives
  29. 29. It works! 2.81 43.50 14.93 32.25 101 jigsaw 2.84 26.58 9.94 19.89 51 reweave 4.94 12.15 7.73 5.05 21 jhotdraw 4.09 9.15 7.79 5.49 10 weka Ratio = (PI + AQ + AJC) / AJC Aggregate Query (AQ) Populate + index (PI) ajc ksloc project
  30. 30. Should all AspectJ users learn Datalog? NO But power users will learn it…
  31. 31. Conclusions of pointcut semantics <ul><li>Datalog suitable for pinning down semantics </li></ul><ul><li>Directly generating implementation from semantics is feasible </li></ul><ul><li>Datalog at sweet spot between expressiveness and efficiency </li></ul>
  32. 32. Beyond AspectJ
  33. 33. No calls to UI methods from beans declare error : call (* java.awt..*.*(..)) && within (Bean+) : “ do not call GUI methods from Bean” only catches direct calls
  34. 34. Catching all errors maycall+( M : method , N : method ) Ã maycall( M , N ) ; 9 K : method . maycall( M , K ), maycall+( K , N ). declare warning at M : 9 T : type . bean( T ), methodDecl( M ,_,_, T ,_,_), 9 N : method . maycall+( M , N ), guiMethod( N ): “ may be calling a GUI method from this method”
  35. 35. Other applications <ul><li>Advise methods that “may change the state of class C” </li></ul><ul><li>Find security flaws (PQL, Martin et al) </li></ul><ul><li>Many more in LogicAJ papers </li></ul>BUT: we are limited by the joinpoint model of AspectJ
  36. 36. Everything is a joinpoint
  37. 37. The 11 joinpoint kinds of AspectJ <ul><li>Method call </li></ul><ul><li>Method execution </li></ul><ul><li>Constructor call </li></ul><ul><li>Constructor execution </li></ul><ul><li>Static initializer execution </li></ul><ul><li>Object pre-initialization </li></ul><ul><li>Object initialization </li></ul><ul><li>Field read </li></ul><ul><li>Field write </li></ul><ul><li>Handler execution </li></ul><ul><li>Advice execution </li></ul>Why are these the right choice?
  38. 38. Joinpoints = Jimple instructions 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; } Java: Jimple: Jimple: a typed, 3-address, stack-less representation of bytecode
  39. 39. Advantages of Joinpoints = Jimple <ul><li>Points-to analysis in Datalog [ Whaley et al ], </li></ul><ul><li>and based on that many more complex analyses (like precise predicted cflow ) </li></ul><ul><li>General dataflow pointcuts [ Masuhara et al ] </li></ul><ul><li>Jimple has been designed to make static analyses easy </li></ul>
  40. 40. Disadvantage of Jimple = Joinpoints complete loss of encapsulation AspectJ does not have encapsulation, but now the problem is even worse…
  41. 41. Aspect Interfaces <ul><li>User control over visible joinpoints e.g. hide non-AspectJ joinpoints </li></ul><ul><li>Datalog for semantics-based control e.g. only allow ‘pure’ aspects to advise </li></ul>
  42. 42. Open modules aspects aspects aspects aspects classes Open module: specifies what can be advised by which aspect
  43. 43. An example open module module FigureModule { class Point,Figure; advertise : call(Figure Figure.translate(int,int)); expose to MoveTrackAspect : call (* Point.translate(int,int)) && within (Figure); } classes that are affected only external calls are advised MoveTrackAspect may advise the specified joinpoints
  44. 44. Opening modules for debugging module Debug { open FigureModule; expose to debug.* : call (* *.*(..)); } another form of module inclusion constrains included module
  45. 45. Datalog for semantics-based control expose to <aspect-query> : <event-query> Current abc: aspect-query = classname pattern expression event-query = pointcut Using datalog queries, can express: pureaspect(A) = A’s only side effect is writing to System.err then expose to pureaspect(A) : call(* mysys..*(..))
  46. 46. Hiding non-AspectJ shadows (0) <ul><li>Predicate for each AspectJ shadow: callShadow( S , M , R ); setShadow( S , F , R ); … </li></ul><ul><li>These are defined in terms of primitive relations that store Jimple instructions </li></ul><ul><li>Define new predicate </li></ul><ul><li>aspectj(S)  (  M , R : callShadow( S , M , R )) ; </li></ul><ul><li>(  F , R : setShadow( S , F , R )); … </li></ul>
  47. 47. Hiding non-AspectJ joinpoints (1) module AspectJVisibility { constrain existingModule; expose (S) aspectjShadows(S) ; } only expose AspectJ joinpoints from an existing module:
  48. 48. Discussion points <ul><li>Expose Datalog to power users? </li></ul><ul><ul><li>via new syntax + rewrite rules </li></ul></ul><ul><ul><li>better Datalog syntax </li></ul></ul><ul><li>Whole program accessible via pointcuts? </li></ul><ul><ul><li>via AST </li></ul></ul><ul><ul><li>via IR such as Jimple </li></ul></ul><ul><li>How do we recover encapsulation? </li></ul><ul><ul><li>Open modules </li></ul></ul><ul><ul><li>Datalog to give semantic hiding conditions </li></ul></ul>

×