Download presentation
Presentation is loading. Please wait.
1
Compositional Pointer and Escape Analysis for Java Programs Martin Rinard Laboratory for Computer Science MIT John Whaley IBM Tokyo Research Laboratory
2
Analysis Points-to information Escape information Optimizations Stack allocation Synchronization elimination
3
Outline Example Analysis Algorithm Optimizations Experimental Results Conclusion
4
Employee Database Example Read in database of employee records Extract statistics like max salary
5
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
6
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
7
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
8
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
9
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
10
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
11
Coding Max Computation class 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; }
12
Coding Max Computation class 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; }
13
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
14
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
15
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); }
16
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();
17
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(); }
18
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
19
Eliminating Unnecessary Synchronization Captured objects are accessible to only one thread Can eliminate synchronization on captured objects
20
Basic Idea Use pointer and escape analysis to recognize captured objects Transform program to Allocate captured objects on stack Eliminate synchronization on captured objects
21
Analysis Overview Interprocedural analysis Compositional analysis Driving Principle Explicitly represent potential interactions of method with its environment (callers and other threads)
22
Points-to Escape Graph in Example vectorelementData [ ] 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
23
Definitions: node types N I = 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 N O = outside nodes represent objects created outside of the computation of the method
24
Definitions: outside node types N P = parameter nodes represent objects passed as incoming parameters N L = load nodes one load node for each load statement in method represents objects loaded from an escaped node N CL = class nodes node from which static variables are accessed
25
Points-to Escape Graph in Example vectorelementData [ ] 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
26
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 = inside vectorelementData [ ] this enum e database highestPaid
27
Escaped nodes parameter nodes class nodes thread nodes nodes in return set nodes reachable from other escaped nodes captured is the opposite of escaped
28
Dataflow Analysis Computes a points-to escape graph for each program point Points-to escape graph is a triple I - set of inside edges O - set of outside edges e - escape function
29
Dataflow Analysis Initial state: I :formals point to parameter nodes, classes point to class nodes O: Ø Transfer functions: I´ = (I – Kill I ) U Gen I O´ = O U Gen O Confluence operator is U
30
Intraprocedural Analysis Must define transfer functions for: copy statement l = v load statement l 1 = l 2.f store statement l 1.f = l 2 return statement return l object creation site l = new cl method invocation l = l 0.op(l 1 …l k )
31
copy statement l = v Kill I = edges(I, l ) Gen I = { l } × succ(I, v ) I´ = (I – Kill I ) Gen I l v Existing edges
32
copy statement l = v Kill I = edges(I, l ) Gen I = { l } × succ(I, v ) I´ = (I – Kill I ) Gen I Generated edges l v
33
load statement l 1 = l 2.f S E = {n 2 succ(I, l 2 ). escaped(n 2 )} S I = {succ(I, n 2,.f ). n 2 succ(I, l 2 )} case 1: l 2 does not point to an escaped node (S E = Ø ) Kill I = edges(I, l 1 ) Gen I = { l 1 } × S I l1l1 l2l2 Existing edges f
34
load statement l 1 = l 2.f S E = {n 2 succ(I, l 2 ). escaped(n 2 )} S I = {succ(I, n 2,.f ). n 2 succ(I, l 2 )} case 1: l 2 does not point to an escaped node (S E = Ø ) Kill I = edges(I, l 1 ) Gen I = { l 1 } × S I Generated edges l1l1 l2l2 f
35
load statement l 1 = l 2.f case 2: l 2 does point to an escaped node (S E Ø ) Kill I = edges(I, l 1 ) Gen I = { l 1 } × (S I {n}) Gen O = (S E × {f}) × {n} l1l1 l2l2 Existing edges
36
load statement l 1 = l 2.f case 2: l 2 does point to an escaped node (S E Ø ) Kill I = edges(I, l 1 ) Gen I = { l 1 } × (S I {n}) Gen O = (S E × {f}) × {n} Generated edges l1l1 l2l2 f
37
store statement l 1.f = l 2 Gen I = (succ(I, l 1 ) × { f }) × succ(I, l 2 ) I´ = I Gen I l2l2 Existing edges l1l1
38
store statement l 1.f = l 2 Gen I = (succ(I, l 1 ) × { f }) × succ(I, l 2 ) I´ = I Gen I Generated edges l2l2 l1l1 f
39
object creation site l = new cl Kill I = edges(I, l ) Gen I = { } l Existing edges
40
object creation site l = new cl Kill I = edges(I, l ) Gen I = { } Generated edges l
41
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
42
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
43
Interprocedural Mapping Example void printStatistics() { BufferedReader r = new BufferedReader( new InputStreamReader(System.in)); EmployeeDatabase e = new EmployeeDatabase(r); e.computeMax(); System.out.println(“max salary = “ + e.highestPaid); }
44
Interprocedural Mapping Example e graph 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); }
45
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
46
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
47
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
48
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
49
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
50
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 [ ]
51
Step 2: Match callee outside edges against caller inside edges void 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
52
Step 2: Match callee outside edges against caller inside edges void 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
53
Step 2: Match callee outside edges against caller inside edges void 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
54
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
55
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
56
Life is not so Simple Dependences between phases Mapping best framed as constraint satisfaction problem Solved using constraint satisfaction
57
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
58
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
59
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: 0 obj header vect: null index: 0 Stack after
60
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
61
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
62
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
63
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
64
Experimental Results Implemented in the Jalapeño JVM Analysis performed on the entire VM Including the analysis code itself!
65
Synch Operations Eliminated
66
Stack Allocated Objects
67
Size of Stack Allocated Objects
68
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)
69
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)
70
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)
71
Conclusion Combined points-to and escape analysis Interprocedural Compositional - Inside and outside nodes/edges Implemented in Jalapeño Encouraging experimental results
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.