Presentation is loading. Please wait.

Presentation is loading. Please wait.

Compositional Pointer and Escape Analysis for Java Programs Martin Rinard Laboratory for Computer Science MIT John Whaley IBM Tokyo Research Laboratory.

Similar presentations


Presentation on theme: "Compositional Pointer and Escape Analysis for Java Programs Martin Rinard Laboratory for Computer Science MIT John Whaley IBM Tokyo Research Laboratory."— Presentation transcript:

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


Download ppt "Compositional Pointer and Escape Analysis for Java Programs Martin Rinard Laboratory for Computer Science MIT John Whaley IBM Tokyo Research Laboratory."

Similar presentations


Ads by Google