Region Pointcut for AspectJ Shumpei Akai Shigeru Chiba Muga Nishizawa.

22
Region Pointcut for AspectJ Shumpei Akai Shigeru Chiba Muga Nishizawa

Transcript of Region Pointcut for AspectJ Shumpei Akai Shigeru Chiba Muga Nishizawa.

Page 1: Region Pointcut for AspectJ Shumpei Akai Shigeru Chiba Muga Nishizawa.

Region Pointcut for AspectJ

Shumpei Akai

Shigeru Chiba

Muga Nishizawa

Page 2: Region Pointcut for AspectJ Shumpei Akai Shigeru Chiba Muga Nishizawa.

Background: Synchronization

Granularity of synchronization alters performance– Fine-grained: Increase concurrency– Coarse-grained: Less overhead

Which granularity is better on a given machine?

Page 3: Region Pointcut for AspectJ Shumpei Akai Shigeru Chiba Muga Nishizawa.

Motivating example: Javassist

A bug report of synchronization for Javassist

[http://jira.jboss.org/jira/browse/JASSIST-28]

– Adding synchronization to fix the bug.

– coarse-grained is chosen in this case.

Separate synchronization code as an aspect– enable choosing

appropriate granularity.

public class ProxyFactory { public Class createClass() { if (thisClass == null) { ClassLoader cl = getClassLoader(); synchronized (proxyCache) { if (useCache){createClass2(cl);} else {createClass3(cl);} }} return thisClass;} private void createClass2(ClassLoader cl) { CacheKey key = new CacheKey(…); synchronized (proxyCache) { HashMap cacheForTheLoader =…; if (cacheForTheLoader == null) { cacheForTheLoader = new HashMap(); proxyCache.put(cl, cacheForTheLoader); cacheForTheLoader.put(key, key); }else {...}} synchronized (key) { Class c = isValidEntry(key); if (c == null) { createClass3(cl); key.proxyClass = new WeakReference(…); }else{thisClass = c;} }}}

Coarse-grained

candidate

Fine-grained

Page 4: Region Pointcut for AspectJ Shumpei Akai Shigeru Chiba Muga Nishizawa.

Separating synchronization with AOP

New pointcuts are needed– AspectJ provides execution, call, get, set

pointcuts They pick out Join “points”.

– But synchronization is applied to a “range” of code.

Join points are not suitable Need to pick out regions (or pieces of code)

Page 5: Region Pointcut for AspectJ Shumpei Akai Shigeru Chiba Muga Nishizawa.

Region pointcut

Regions are treated like join points– Use pattern matching– Static analysis and code transformation

Regions are determined by static analysis.

Extension to AspectJ

Page 6: Region Pointcut for AspectJ Shumpei Akai Shigeru Chiba Muga Nishizawa.

region[pc1;pc2;pc3;…]

A new pointcut for a region– Specify a sequence of join points– Find a matching path

public void foo() { … obj.criticalSectionBegin();//from here if(…){ a(); } … obj.criticalSectionEnd();//to here …}

void around():region[ call(* *. criticalSectionBegin()); call(* *.a()); call(* *. criticalSectionEnd());]{ synchronized(someObject){ proceed(); }}

Page 7: Region Pointcut for AspectJ Shumpei Akai Shigeru Chiba Muga Nishizawa.

New pointcut: all()

all(pc1, pc2, pc3, …)– Matches a sequence including the join points all

the pointcuts pc1, pc2, pc3, … match in some order.

– The order of pointcuts does not matter. because the order of join points may be changed by

refactoring

Page 8: Region Pointcut for AspectJ Shumpei Akai Shigeru Chiba Muga Nishizawa.

Example of all()

region[ all( call(* *.a()), call(* *.b()), call(* *.c()) )]

{ a(); … b(); … c();}

{ b(); … c(); … a();}

{ c(); … b(); c(); … a();}

matches

Page 9: Region Pointcut for AspectJ Shumpei Akai Shigeru Chiba Muga Nishizawa.

A region may conflict with a control structure

If a region intersects a control structure– we cannot weave an

around advice

public void foo() { ... for(int i=0;i<100;i++){ bar(); beginCriticalSection(); // begin ... } endCriticalSection(); // end ...}

void around():region[ call(* *. criticalSectionBegin()); call(* *. criticalSectionEnd())]{ /* do something*/ }

Page 10: Region Pointcut for AspectJ Shumpei Akai Shigeru Chiba Muga Nishizawa.

Region adjustment

Solves the conflict– Expand a selected

region: to fit a control structure to include the first and

the last selected join points

– A minimum region satisfying the criteria above is selected

public void foo() { ... for(int i=0;i<100;i++){ bar(); beginCriticalSection(); // begin ... } endCriticalSection(); // end ...}

Page 11: Region Pointcut for AspectJ Shumpei Akai Shigeru Chiba Muga Nishizawa.

Context passing

Synchronization needs a lock object– Contexts must be available in an advice body

args(), target() are available in a pattern– Specified values must be accessible at the

beginning of the region

Page 12: Region Pointcut for AspectJ Shumpei Akai Shigeru Chiba Muga Nishizawa.

Example of context passing

… List list = ... ; ... for(int index = 0; i < 100; i++){ beginCriticalSection(); ... Object o=list.get(index); ... endCriticalSection(); } ...

pointcut pc(List l,int i) : region[ call(* *.beginCriticalSection()); call(* List+.get(int)) && target(l) && args(i) ; call(* *.endCriticalSection()); ];

Page 13: Region Pointcut for AspectJ Shumpei Akai Shigeru Chiba Muga Nishizawa.

Implementation

We implemented by extending abc– abc: The AspectBench Compiler for AspectJ

Need information, where blocks, control structures and statements start/end– Add new instruction into Jimple

Page 14: Region Pointcut for AspectJ Shumpei Akai Shigeru Chiba Muga Nishizawa.

public void toBeAdvised(int x){ a(); b(x); c();}

original method

Around advice

In abc, some join points (e.g. execution) are split into static methods to weave an around advice– Local variables are passed through arguments– We adopt this mechanism

This causes a few problems for the region pointcut

public void toBeAdvised(int x){ advice(x);}

public static void advice(int x){ beforeJoinPoint(); shadow(x); afterJoinPoint();}

public static shadow(int x){ a(); b(x); c();}

woven method advice original join point

Page 15: Region Pointcut for AspectJ Shumpei Akai Shigeru Chiba Muga Nishizawa.

Support an around advice : assignment (problem)

Assignment does not change the value of the local variable– Local variables are

replicated.

public void toBeAdvised(int x){ String s="initial string"; a(); s="string was replaced"; b(); System.out.println(s); // what is the value of s?}

void around(): region[call(* *.a());call(* *.b())] { proceed(); }

Page 16: Region Pointcut for AspectJ Shumpei Akai Shigeru Chiba Muga Nishizawa.

Support an around advice : assignment (solution)

Share an object between the region and the original method– Each field contains a

value of a local variable

public void toBeAdvised(int x){ String s="initial string"; $localStorage = new LocalStorage(); $localStorage.s=s;

s=$localStorage.s; a(); s="string was replaced"; b(); $localStorage.s=s;

s=$localStorage.s; System.out.println(s);}

Page 17: Region Pointcut for AspectJ Shumpei Akai Shigeru Chiba Muga Nishizawa.

Support an around advice : jumps (problem)

Jumps (break or continue) to outside of region are unavailable

public void includeJump(){ labelOfFor: for(;;){ a(); if(isFinished()){ break; //goto label0; } b(); } //label0:}void around():

region[call(* *.a());call(* *.b())] { proceed(); }

Page 18: Region Pointcut for AspectJ Shumpei Akai Shigeru Chiba Muga Nishizawa.

Support an around advice : jumps (solution)

Transform the bytecode– Share the ID for each

jump target– Jump to the tail of the

region– After region, check the

ID and jump

public void includeJump(){labelOfFor: for(;;){ a(); if(isFinished()){ $i=0; goto endLabel; } b(); endLabel: switch($i){ case 0: goto label0; } } label0:}

Page 19: Region Pointcut for AspectJ Shumpei Akai Shigeru Chiba Muga Nishizawa.

Applying to Javassist (coarse-grained)

Fixed Javassist’s synchronization problem using region pointcut

static WeakHashMap proxyCache;public Class createClass() { if (thisClass == null) { ClassLoader cl = …; if (useCache) createClass2(cl); else createClass3(cl); } return thisClass;}

void around(): region[ get(static boolean *.useCache); call(* *.createClass2(..)); ] { synchronized(ProxyFactory.class) { proceed(); } }

Page 20: Region Pointcut for AspectJ Shumpei Akai Shigeru Chiba Muga Nishizawa.

Applying to javassist (fine-grained)

void around():region[ call(* WeakHashMap.get(..)); call(* WeakHashMap.put(..));]{ synchronized( ProxyFactory.proxyCache){ proceed(); }}

static WeakHashMap proxyCache;private void createClass2(ClassLoader cl) { CacheKey key =…; HashMap cacheForTheLoader = (HashMap)proxyCache.get(cl); if (cacheForTheLoader == null) { proxyCache.put(...); }else{...}

Page 21: Region Pointcut for AspectJ Shumpei Akai Shigeru Chiba Muga Nishizawa.

Related work

Tracematch [Allan et al. ’05]– History-based pointcut– Dynamic pattern matching with execution history

LoopsAJ [Harbulot et al. ’06]– Picking out loops

Page 22: Region Pointcut for AspectJ Shumpei Akai Shigeru Chiba Muga Nishizawa.

Conclusion

Region pointcut:– Picks out regions as join points– We extended abc

Solved some design issues to weave an around advice

Work in progress– Formalize the pattern matching semantics using

hedge automata– Case study