Top Banner
Seminar on Aspect- Oriented Software Development (236800) Static Analysis of Aspects December 5, 2004 Static Analysis of Aspects Evgeniy Gabrilovich http://www.cs.technion.ac.il/ ~gabr CS Department, Technion
40

December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Dec 20, 2015

Download

Documents

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Static Analysis of Aspects

Evgeniy Gabrilovich

http://www.cs.technion.ac.il/~gabr

CS Department, Technion

Page 2: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Problems with AOP

1. Aspect applicability is usually decided dynamically

– Matching join points with pointcut designators incurs significant run-time overhead

2. Multiple pieces of advice may apply at the same program point Programs are difficult to maintain and debug

ComposeJ, JasCo/JAC

Page 3: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

60 seconds about Dynamic Matching

• Aspect code monitors the execution of the base program

• Certain (sequences of) events trigger the aspect code (aka advice)– Monitored events are defined as patterns in

the call stack– An aspect can be applied recursively,

monitoring its own execution

• Dynamic matching is expensive !

Observer Pattern

Page 4: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Outline

• New syntax for pointcut designators

• Running example

• Compiling aspects in AspectJ

• Static analysis

• Running example revisited

• Limitations of the approach

• Conclusions

Page 5: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Reminder: Join points and pointcuts in AspectJ• Join point – a machine configuration

where advice might intervene

• Pointcut – a set of join points where a given advice should be executed– Examples: call(…), execution(…),

cflow(…), cflowbelow(…)– Complex pointcuts use boolean operators:

•!p, p1 || p2, p1 && p2

Page 6: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

New syntax – regular expressions over control stack

• Intuition: join points as abstractions over control stack– modeling the sequence of procedure calls as

a graph

• A join point is a sequence of– Procedure calls (call)– Procedure executions (exec)– Advice executions (aexec)

Invocation of a procedure at the call site

Entry into the procedure’s body

Demeter used object

graphs

Page 7: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Grammar for the language of possible join points

jp ::= jp_element*

jp_element ::= call(name, name,

actual_param*)

| exec name

| aexec name

Called procedure

Calling context

Page 8: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Pointcut designators (PCDs)

• Regular expressions over an alphabet of element designators:ed ::= pcall pname

| pwithin name

| args var*

| ed or ed

| ed and ed

| not ed

| true

Matches join point elements of the form call(n,_,_)

Matches calls made from the context n: call(_,n,_)

args(x1,…,xn) matches call(_,_,[a1,…,an]), binding xi to ai

Page 9: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Profiling Quicksort

• linesbuf is a global variable holding an array of strings

compare(i,j) returns true if linesbuf[i] < linesbuf[j]

swap(i,j) swaps lines i and j

readln(i) reads a line into linesbuf[i]

writeln(i) prints linesbuf[i]

partition(a,b) partitions linesbuf[a..b) with pivot linesbuf[a]

quicksort(a,b) sorts linesbuf[a..b)

Page 10: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Gathering Quicksort statistics

1. Count the number of calls to partition2. Count the number of swap operations

• Note that– there may be other uses of swap apart from

the obvious ones within the partition routine– both swap and partition may also be used

outside quicksort

Page 11: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Profiling aspect for Quicksort (1/4)

aspect Counts

var swaps, partitions: int;

advice PCount

before: {pcall(partition) /\ pwithin(quicksort)}; {true}*

begin

partitions := partitions + 1

end

Top of the call stack

A call to partition from the body of

quicksort

Page 12: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Profiling aspect for Quicksort (2/4)

advice SCount

before: {pcall(swap);{true}*;{pcall(quicksort)};{true}*

begin

swaps := swaps + 1

endA call to swap within the context of a call

to quicksort

pcall(swap) /\ cflow(quicksort)

Page 13: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Profiling aspect for Quicksort (3/4)

advice Init

before: {pcall(quicksort)}; {not pcall(quicksort)}*

begin

partitions := 0;

swaps := 0

end

Only matches non-recursive calls to

quicksort

pcall(quicksort) /\ not cflowbelow(quicksort)

Page 14: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Profiling aspect for Quicksort (4/4)

advice Print

after: {pcall(quicksort)}; {not pcall(quicksort)}*

begin

println “Partitions: “ ++ partitions;

println “Swaps: “ ++ swaps;

end

end Counts

Only matches non-recursive calls to

quicksort

Page 15: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Example

main()

quicksort()

f()

{pcall(quicksort)}; {not pcall(quicksort)}*

quicksort()

X

Page 16: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

More examples

main()

quicksort()

f()

{pcall(swap);{true}*;{pcall(quicksort)};{true}*

partition()

swap()

main()readln()swap()X

Page 17: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Interpreting aspects• Localizing the code that gathers quicksort

statistics is nice … provided the run-time cost is negligible

• Dynamic matching– Whenever a new join point is created,

it’s matched against all PCDs– If a match is found, the corresponding advice

is executed, with PCD variables bound in matching

Page 18: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Interpreting aspects: example• Initialization trigger:

{pcall(quicksort)}; {not pcall(quicksort)}*• To check that a join point satisfies this

PCD, we must traverse the whole join point (= call stack)

• Upon each creation of a new join point, the interpreter may have to traverse the whole join point for each PCD

Page 19: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

The AspectJ approach

• Each PCD corresponds to a DFA• The compiled program maintains a set of

such automata• Inspecting the automaton state determines

in O(1) whether the corresponding aspect code should be executed

Maintaining these automata is still a significant overhead, proportional to the number of PCDs (= pieces of advice)

Page 20: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Static analysis of aspects• Our goal:

– Completely eliminate the matching process– Determine for each point in the program

exactly what PCDs will apply at run-time

• Then, a compiler can generate a tangled program that the programmer might have written before aspects were invented

Page 21: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

The approach• Given the program call graph

– determine for each procedure call the set of all join points possible at that call

– statically determine all matching PCDs

• Perform source-to-source transformation by weaving all applicable advice at compile-time– No PCD matching is needed at run-time! – This is not always possible

Page 22: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Analysis overview

• Each piece of advice (a) is associated with a PCD (pcd), which denotes a (usually infinite) set of join points: join_points(pcd)

• Advice a is executed if the current join point (= sequence of procedure calls in the call stack) belongs to join_points(pcd)

• For each procedure call p in the program, compute a set L(p) of all possible join points at evaluation of the call p.

Page 23: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Static analysis by computing language containment

• L(p) is defined as a regular language over the call graph of the program

• join_points(pcd) is a regular language defined by the regular expression of pcd

Then:

• a always applies at p

• a never applies at p

• Otherwise, the analysis is inconclusive

s(pcd)join_point)( pL

s(pcd)join_point)( pL

Page 24: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Examples {pcall(quicksort)}; {not pcall(quicksort)}*

main()quicksort()

Init

{pcall(swap);{true}*;{pcall(quicksort)};{true}*

main()swap()

quicksort()

partition()

SCount

Page 25: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Constructing the call graph

• Nodes – procedure calls + aspects

• Edges – join point elements– elementary operations affecting the control

stack

• Join points – sequences of join point elements = paths in the call graph

• L(p) = a set of paths from the source

vertex v (main) to the vertex representing p

Page 26: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Constructing the call graph (2)• Every path from v to p is a valid join point

at p – although it doesn’t have to occur in actual

program runs – overestimation !

• Every valid join point is represented by a path

• 3 kinds of edges (= join point elements):– procedure calls– procedure executions– advice executions

Page 27: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Direct (unadvised)

path

Advised paths (possibly chaining multiple aspects)

Page 28: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Pruning the call graph

• The construction yields a huge call graph with many infeasible edges

• Reducing the graph size by considering the topmost element of the call stack:– PCDs of the form {pcall(f) /\ …}; … can never

apply to a call to procedure g ≠ f

nodes for corresponding advice need not be included for such calls, and may be pruned

Page 29: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Meet-over-all-paths analysis• Given the source program, construct its

call graph– The set of paths from v to p is a superset of

the set of possible call stacks at point p during program execution

• For each procedure call p– obtain a regular expression L(p)

• Tarjan’s algorithm – O(|E| · log (|V|)

– Test it for inclusion w.r.t. each PCD• O(|E| + |V|)

The set of join points at p

s(pcd)join_point)( pLs(pcd)join_point)( pL

Page 30: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Analyzing the Quicksort example

• Legend (for a procedure call p and an advice a):– √ - a always applies at p– x – a can never apply at p– (blank) – the analysis is inconclusive

Page 31: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Examples {pcall(quicksort)}; {not pcall(quicksort)}*

main()quicksort()

Init

{pcall(swap);{true}*;{pcall(quicksort)};{true}*

main()swap()

quicksort()

partition()

SCount

Page 32: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Quicksort example (cont’d)

• PCount advice is in a sense static – it only depends on the textual location of the call– Only the topmost item of the stack is matched:

{pcall(partition) /\ pwithin(quicksort)}; {true}*

quicksort() {

partition();

}

partition() {

}

jp_element = call(partition,quicksort,_)

Page 33: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Quicksort example (cont’d)

• The other two PCDs are truly dynamic and depend on the call stack:– {pcall(swap);{true}*;{pcall(quicksort)};{true}* - a call to

swap is within dynamic scope of quicksort– {pcall(quicksort)}; {not pcall(quicksort)}* - a call to

quicksort is not recursive

Page 34: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Quicksort example (cont’d)

• The analysis was successful for each advice and each procedure call

Dynamic PCDs are in fact static in the context of the base program

Static matching is possible!

• Separation of concerns (sorting per se and profiling) does not sacrifice run-time efficiency

Page 35: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Limitations of the approach• Static analysis is not always possible for

arbitrary PCDs– Consider a simple procedure f with a single

recursive call to itself– {pcall(f)}; {true}*; {pcall(f)}; {true}*; {pcall(f)}; {true}*;

• recursion depth ≥ 3

– This PCD applies to some – but not all – recursive calls from f to itself

• For example, it does not apply to the first such call

pcall(f) /\ cflowbelow ( pcall(f) /\ cflowbelow(pcall(f))

Page 36: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Limitations (cont’d)• PCDs cannot make tests that depend on

dynamic values of variables (args)– Otherwise, the matching code cannot be

eliminated – we still must maintain a stack of variable bindings

• The construction of the call graph is complicated by virtual methods– At each virtual method call, we need to

determine what instances might be called– Open issue

Page 37: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Conclusions

• Primitive language for describing patterns in the call stack using regular expressions

• Meet-over-all-paths analysis enables the compiler to determine aspect applicability statically– Run-time overhead of matching PCDs can be

reduced, and sometimes completely eliminated

Page 38: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Conclusions (cont’d)

• In practice, static undecidability is limited to a few procedure calls in the program– Large portions of the call graph can still be

woven statically

• In large AO programs, it is important to warn programmers of potential interactions between aspects– Static analysis can detect when different

pieces of advice may both be executed at the same program point

Page 39: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Bibliography1. D. Sereni and Oege de Moor. “Static Analysis of

Aspects”, AOSD 2003

2. H. Masuhara, G. Kiczales and C. Dutchyn. “Compilation Semantics of Aspect-Oriented Programs”, FOAL Workshop at AOSD 2002

3. M. Wand, G. Kiczales and C. Dutchyn. “A Semantics for Advice and Dynamic Join Points in AOP”, FOAL Workshop at AOSD 2002

4. E. Gamma, R. Helm, R. Johnson and J. Vlissides. “Design Patterns”, Addison-Wesley, 1995

5. R.E. Tarjan. “Fast Algorithms for Solving Path Problems”, JACM 28(3), 1981

Page 40: December 5, 2004 Seminar on Aspect-Oriented Software Development (236800) Static Analysis of Aspects Evgeniy Gabrilovich gabr.

Seminar on Aspect-Oriented Software Development (236800)

Static Analysis of Aspects December 5, 2004

Questions?