Date post: | 20-Dec-2015 |
Category: |
Documents |
View: | 216 times |
Download: | 0 times |
Compositional Pointer and Escape Analysis for Java Programs
Martin RinardLaboratory for
Computer ScienceMIT
John Whaley IBM TokyoResearch
Laboratory
AnalysisPoints-to informationEscape information
OptimizationsStack allocation
Synchronization elimination
Outline
• Example• Analysis Algorithm• Optimizations• Experimental Results• Conclusion
Employee Database Example
• Read in database of employee records• Extract statistics like max salary
Employee Database Example
• Read in database of employee records• Extract statistics like max salary
Name
Salary
John Doe
$45,000
Ben Bit
$30,000
Jane Roe
$55,000
Vector
Computing Max Salary
• Traverse Records to Find Max Salary
John Doe
$45,000
Name
Salary
Ben Bit
$30,000
Jane Roe
$55,000
Vector
max = $0
Computing Max Salary
• Traverse Records to Find Max Salary
John Doe
$45,000
Name
Salary
Ben Bit
$30,000
Jane Roe
$55,000
Vector
max = $45,000
who = John Doe
Computing Max Salary
• Traverse Records to Find Max Salary
John Doe
$45,000
Name
Salary
Ben Bit
$30,000
Jane Roe
$55,000
Vector
max = $45,000
who = John Doe
Computing Max Salary
• Traverse Records to Find Max Salary
John Doe
$45,000
Name
Salary
Ben Bit
$30,000
Jane Roe
$55,000
Vector
max = $55,000
who = Jane Roe
Computing Max Salary
• Traverse Records to Find Max Salary
John Doe
$45,000
Name
Salary
Ben Bit
$30,000
Jane Roe
$55,000
Vector
max salary = $55,000
highest paid = Jane Roe
Coding Max Computationclass EmployeeDatabase {
Vector database = new Vector();Employee highestPaid;void computeMax() {
int max = 0;Enumeration enum = database.elements();while (enum.hasMoreElements()) {
Employee e = enum.nextElement();if (max < e.salary()) {
max = e.salary(); highestPaid = e;}
} }
}
Coding Max Computationclass EmployeeDatabase {
Vector database = new Vector();Employee highestPaid;void computeMax() {
int max = 0;Enumeration enum = database.elements();while (enum.hasMoreElements()) {
Employee e = enum.nextElement();if (max < e.salary()) {
max = e.salary(); highestPaid = e;}
} }
}
Issues In Implementation
• Enumeration object allocated on heap• Increases heap memory usage• Increases garbage collection
frequency• Heap allocation is unnecessary
• Enumeration object allocated inside max
• Not accessible outside max • Should be able to use stack allocation
Key Concept
• Enumeration object is captured in max• Allocated inside computation of
method• Inaccessible to callers of method• Within method, object does not
escape to another thread• So object is dead when method returns• Can allocate captured objects on stack
How is Database Used?
void printStatistics() {BufferedReader r = new BufferedReader(
new InputStreamReader(System.in));EmployeeDatabase e = new EmployeeDatabase(r);e.computeMax();System.out.println(“max salary = “ + e.highestPaid);
}
Interesting Fact
void printStatistics() {BufferedReader r = new BufferedReader(
new InputStreamReader(System.in));EmployeeDatabase e = new EmployeeDatabase(r);e.computeMax();System.out.println(“max salary = “ + e.highestPaid);
}
• Only one thread accesses employee database
• But accesses are synchronized!Employee e = enum.nextElement();
Synchronization in nextElement
class VectorEnumerator implements Enumeration {
Vector vector;
int count;
Object nextElement() {
synchronized (vector) {if (count < vector.elementCount)
return vector.elementData[count++]; }
throw new NoSuchElementException();}
}
Synchronized Libraries
• nextElement is in the Java class library• Java is a multithreaded language• By default, libraries are synchronized• Result: lots of unnecessary
synchronization for objects that are accessed by only one thread
Eliminating Unnecessary Synchronization
• Captured objects are accessible to only one thread
• Can eliminate synchronization on captured objects
Basic Idea
• Use pointer and escape analysis to recognize captured objects
• Transform program to• Allocate captured objects on stack• Eliminate synchronization on
captured objects
Analysis Overview
• Interprocedural analysis• Compositional analysis • Driving Principle
• Explicitly represent potential interactions of method with its environment (callers and other threads)
Points-to Escape Graph in Example
vector elementData [ ]
this
enum
e
dotted = outside
solid = inside
void computeMax() {
int max = 0;
Enumeration enum = database.elements();
while (enum.hasMoreElements()) {
Employee e = enum.nextElement();
if (max < e.salary()) { max = e.salary(); highestPaid = e; }
}
}
database highestPaid
Definitions: node types
• NI = inside nodes
• represent objects created within the computation of the method
• one inside node for each object creation site; represents all objects created at site
• NO = outside nodes
• represent objects created outside of the computation of the method
Definitions: outside node types
NP = parameter nodes
represent objects passed as incoming parameters
NL = load nodes
one load node for each load statement in method
represents objects loaded from an escaped node
NCL = class nodes
node from which static variables are accessed
Points-to Escape Graph in Example
vector elementData [ ]
this
enum
e
dotted = outside
solid = inside
void computeMax() {
int max = 0;
Enumeration enum = database.elements();
while (enum.hasMoreElements()) {
Employee e = enum.nextElement();
if (max < e.salary()) { max = e.salary(); highestPaid = e; }
}
}
database highestPaid
Points-to Escape Graph in Example
red = escaped
white = captured
void computeMax() { int max = 0;Enumeration enum = database.elements();while (enum.hasMoreElements()) {
Employee e = enum.nextElement();if (max < e.salary()) { max = e.salary();
highestPaid = e; }}
} dotted = outside
solid = insidevector elementData [ ]
this
enum
e
database highestPaid
Escaped nodes
• Escaped nodes• parameter nodes• class nodes• thread nodes• nodes in return set• nodes reachable from other escaped
nodes• captured is the opposite of escaped
Dataflow Analysis
• Computes a points-to escape graph for each program point
• Points-to escape graph is a triple <I,O,e>• I - set of inside edges• O - set of outside edges• e - escape function
Dataflow Analysis
• Initial state:I : formals point to parameter
nodes,classes point to class nodes
O: Ø• Transfer functions:
I´ = (I – KillI ) U GenI
O´ = O U GenO
• Confluence operator is U
Intraprocedural Analysis
• Must define transfer functions for:• copy statement l = v
• load statement l1 = l2.f
• store statement l1.f = l2
• return statement return l• object creation site l = new cl
• method invocation l = l0.op(l1…lk)
copy statement l = v
KillI = edges(I, l)
GenI = {l} × succ(I, v)
I´ = (I – KillI ) GenI
l
v
Existing edges
copy statement l = v
KillI = edges(I, l)
GenI = {l} × succ(I, v)
I´ = (I – KillI ) GenI
Generated edges
l
v
load statement l1 = l2.f
SE = {n2 succ(I, l2) . escaped(n2)}
SI = {succ(I, n2,.f) . n2 succ(I, l2)}
case 1: l2 does not point to an escaped node (SE = Ø)
KillI = edges(I, l1)
GenI = {l1} × SI
l1
l2
Existing edges
f
load statement l1 = l2.f
SE = {n2 succ(I, l2) . escaped(n2)}
SI = {succ(I, n2,.f) . n2 succ(I, l2)}
case 1: l2 does not point to an escaped node (SE = Ø)
KillI = edges(I, l1)
GenI = {l1} × SI
Generated edges
l1
l2
f
load statement l1 = l2.f
case 2: l2 does point to an escaped node (SE Ø)
KillI = edges(I, l1)
GenI = {l1} × (SI {n})
GenO = (SE × {f}) × {n}
l1
l2
Existing edges
load statement l1 = l2.f
case 2: l2 does point to an escaped node (SE Ø)
KillI = edges(I, l1)
GenI = {l1} × (SI {n})
GenO = (SE × {f}) × {n}
Generated edges
l1
l2
f
store statement l1.f = l2
GenI = (succ(I, l1) × {f}) × succ(I, l2)
I´ = I GenI
l2
Existing edges
l1
store statement l1.f = l2
GenI = (succ(I, l1) × {f}) × succ(I, l2)
I´ = I GenI
Generated edges
l2
l1f
object creation site l = new cl
KillI = edges(I, l)
GenI = {<l, n>}
l
Existing edges
object creation site l = new cl
KillI = edges(I, l)
GenI = {<l, n>}
Generated edges
l
Method call
• Transfer function for method call:• Take points-to escape graph before
the call site• Retrieve the points-to escape graph
from analysis of callee• Map callee graph into caller graph
• Result is the points-to escape graph after the call site
Interprocedural Mapping
• Set up an abstract mapping between caller and callee• outside nodes in the callee may refer
to any number of inside nodes in the caller
• add all reachable inside edges from callee’s graph into caller’s graph
• outside edges from a node in the callee need to be added to the mapped caller node if it escapes
Interprocedural Mapping Examplevoid printStatistics() {
BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
EmployeeDatabase e = new EmployeeDatabase(r);e.computeMax();System.out.println(“max salary = “ + e.highestPaid);
}
Interprocedural Mapping Example
egraph before call site
elementData [ ]database
void printStatistics() {BufferedReader r = new BufferedReader(
new InputStreamReader(System.in));EmployeeDatabase e = new EmployeeDatabase(r);e.computeMax();System.out.println(“max salary = “ + e.highestPaid);
}
Interprocedural Mapping Example
callee graph
graph before call site
Enum object is not present because it was captured in the callee.
elementData [ ]this database
e elementData [ ]database
void printStatistics() {BufferedReader r = new BufferedReader(
new InputStreamReader(System.in));EmployeeDatabase e = new EmployeeDatabase(r);e.computeMax();System.out.println(“max salary = “ + e.highestPaid);
}
highestPaid
Step 1: Map formals to actuals
graph before call site
e elementData [ ]database
void printStatistics() {BufferedReader r = new BufferedReader(
new InputStreamReader(System.in));EmployeeDatabase e = new EmployeeDatabase(r);e.computeMax();System.out.println(“max salary = “ + e.highestPaid);
}
callee graph
elementData [ ]this database
highestPaid
Step 1: Map formals to actuals
graph before call site
e elementData [ ]database
void printStatistics() {BufferedReader r = new BufferedReader(
new InputStreamReader(System.in));EmployeeDatabase e = new EmployeeDatabase(r);e.computeMax();System.out.println(“max salary = “ + e.highestPaid);
}
callee graph
elementData [ ]
database
highestPaid
Step 2: Match callee outside edges against caller inside edges
graph before call site
e elementData [ ]database
void printStatistics() {BufferedReader r = new BufferedReader(
new InputStreamReader(System.in));EmployeeDatabase e = new EmployeeDatabase(r);e.computeMax();System.out.println(“max salary = “ + e.highestPaid);
}
elementData [ ]callee graph
database
highestPaid
Step 2: Match callee outside edges against caller inside edges
graph before call site
e elementData [ ]database
void printStatistics() {BufferedReader r = new BufferedReader(
new InputStreamReader(System.in));EmployeeDatabase e = new EmployeeDatabase(r);e.computeMax();System.out.println(“max salary = “ + e.highestPaid);
}
elementData
[ ]callee graph
Step 2: Match callee outside edges against caller inside edges
graph before call site
e elementData [ ]database
void printStatistics() {BufferedReader r = new BufferedReader(
new InputStreamReader(System.in));EmployeeDatabase e = new EmployeeDatabase(r);e.computeMax();System.out.println(“max salary = “ + e.highestPaid);
}
callee graph
elementData
[ ]
Step 2: Match callee outside edges against caller inside edgesvoid printStatistics() {
BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
EmployeeDatabase e = new EmployeeDatabase(r);e.computeMax();System.out.println(“max salary = “ + e.highestPaid);
}graph before call site
e elementData [ ]database
callee graph
[ ]highestPaid
Step 2: Match callee outside edges against caller inside edgesvoid printStatistics() {
BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
EmployeeDatabase e = new EmployeeDatabase(r);e.computeMax();System.out.println(“max salary = “ + e.highestPaid);
}graph before call site
e elementData [ ]database
callee graph
[ ]highestPaid
Step 2: Match callee outside edges against caller inside edgesvoid printStatistics() {
BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
EmployeeDatabase e = new EmployeeDatabase(r);e.computeMax();System.out.println(“max salary = “ + e.highestPaid);
}graph before call site
e elementData [ ]database
highestPaid
callee graph
Step 3: Add nodes and edges and update escape function
graph before call site
e elementData [ ]database
void printStatistics() {BufferedReader r = new BufferedReader(
new InputStreamReader(System.in));EmployeeDatabase e = new EmployeeDatabase(r);e.computeMax();System.out.println(“max salary = “ + e.highestPaid);
}
highestPaid
Step 3: Add nodes and edges and update escape function
final graph:
Escaped nodes and edges in callee may be recaptured in caller!
e elementData [ ]database
void printStatistics() {BufferedReader r = new BufferedReader(
new InputStreamReader(System.in));EmployeeDatabase e = new EmployeeDatabase(r);e.computeMax();System.out.println(“max salary = “ + e.highestPaid);
}
highestPaid
Life is not so Simple
• Dependences between phases• Mapping best framed as constraint
satisfaction problem• Solved using constraint satisfaction
Algorithm Features
• Partial program analysis• can analyze libraries independent of
callers• can analyze a method without
analyzing the methods it invokes• Appropriate for a dynamic compiler
• Support for partial program analysis• Analyze libraries offline and use
results
Stack Allocation of Captured Objects
• Objects that are captured can be allocated in stack frame of capturing method
Stack before
fp
e: null
enum:
max: 0 obj header
vect: null
index: 0
Stack Allocation of Captured Objects
• Objects that are captured can be allocated on the stack
fp
e: null
enum:
max: 0 obj header
vect: null
index: 0
Stack before
fp
e: null
max: 0obj
headervect: null
index: 0
Stack after
Stack Allocation of Captured Objects
• Stack allocation can extend lifetime of objects
• Allocations of arbitrary size are not transformed• Allocation sites inside loops• Arbitrary-sized arrays
Object captured within a caller
• Call path to the allocating method is specialized
• Add an extra parameter: location in the caller’s stack frame where to put the object
• Object allocation is changed to allocate the object at the given location, rather than on the heap
Specialization policy
• Distance in the call graph between capturing method and allocating method may be large
• Implemented solution: full specialization• Specialized versions of all methods on
call chain from capturing method to allocating method
• Does not seem to blow up in practice
Removing Synchronization on Captured Objects
• Identify lock-unlock pairs that can only operate on captured objects• Augment analysis with sets of nodes
for each lock-unlock pair• If all nodes in a set are captured, then
the lock-unlock pair can be removed
Experimental Results
• Implemented in the Jalapeño JVM• Analysis performed on the entire VM
• Including the analysis code itself!
Benchmark Lines ofcode
Class fi lesize (bytes)
javac - 87801
javacup 10574 157057javalex 8159 95229pbob 18370 253752J VM 70536 456494
Synch Operations Eliminated
36%
67%
48%
24%
0%
10%
20%
30%
40%
50%
60%
70%
80%
90%
100%
j avac j avacup j avalex pbob
Stack Allocated Objects
29%22%
95%
30%
0%
10%
20%
30%
40%
50%
60%
70%
80%
90%
100%
j avac j avacup j avalex pbob
Size of Stack Allocated Objects
25%20%
92%
30%
0%
10%
20%
30%
40%
50%
60%
70%
80%
90%
100%
j avac j avacup j avalex pbob
Related Work
• Pointer Analysis for Sequential Programs• Chatterjee, Ryder, Landi (POPL 99)• Sathyanathan & Lam (LCPC 96)• Steensgaard (POPL 96)• Wilson & Lam (PLDI 95)• Emami, Ghiya, Hendren (PLDI 94)• Choi, Burke, Carini (POPL 93)
Related Work
• Pointer Analysis for Multithreaded Programs• Rugina and Rinard (PLDI 99) (fork-
join parallelism, not compositional)• We have extended our points-to analysis
for multithreaded programs (irregular, thread-based concurrency, compositional)
• Escape Analysis• Blanchet (POPL 98)• Deutsch (POPL 90, POPL 97)• Park & Goldberg (PLDI 92)
Related Work
• Synchronization Optimizations• Diniz & Rinard (LCPC 96, POPL 97)• Plevyak, Zhang, Chien (POPL 95)• Aldrich, Chambers, Sirer, Eggers
(SAS99)• Blanchet (OOPSLA 99)• Bogda, Hoelzle (OOPSLA 99)• Choi, Gupta, Serrano, Sreedhar, Midkiff
(OOPSLA 99)
Conclusion
• Combined points-to and escape analysis• Interprocedural• Compositional - Inside and outside
nodes/edges• Implemented in Jalapeño• Encouraging experimental results