1 / 71

Compositional Pointer and Escape Analysis for Java Programs

Explore compositional pointer and escape analysis for Java programs, optimization strategies, experimental results, and more using examples like Employee Database. Understand issues in implementation and ways to eliminate unnecessary synchronizations. Learn about captured objects and stack allocation to enhance program efficiency.

rosaliah
Download Presentation

Compositional Pointer and Escape Analysis for Java Programs

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


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

  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. Vector John Doe Ben Bit Jane Roe $45,000 $30,000 $55,000 Employee Database Example • Read in database of employee records • Extract statistics like max salary Name Salary

  6. Computing Max Salary • Traverse Records to Find Max Salary Vector Name John Doe Ben Bit Jane Roe Salary $45,000 $30,000 $55,000 max = $0

  7. Computing Max Salary • Traverse Records to Find Max Salary Vector Name John Doe Ben Bit Jane Roe Salary $45,000 $30,000 $55,000 max = $45,000 who = John Doe

  8. Computing Max Salary • Traverse Records to Find Max Salary Vector Name John Doe Ben Bit Jane Roe Salary $45,000 $30,000 $55,000 max = $45,000 who = John Doe

  9. Computing Max Salary • Traverse Records to Find Max Salary Vector Name John Doe Ben Bit Jane Roe Salary $45,000 $30,000 $55,000 max = $55,000 who = Jane Roe

  10. Computing Max Salary • Traverse Records to Find Max Salary Vector Name John Doe Ben Bit Jane Roe Salary $45,000 $30,000 $55,000 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 capturedin 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 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 [ ] vector elementData solid = inside enum database highestPaid this e

  23. 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

  24. 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

  25. Points-to Escape Graph in Example 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 [ ] vector elementData solid = inside enum database highestPaid this e

  26. Points-to Escape Graph in Example 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 [ ] vector elementData solid = inside enum database highestPaid red = escaped white = captured this e

  27. 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

  28. 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

  29. 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

  30. 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)

  31. copy statement l = v KillI= edges(I, l) GenI= {l} × succ(I, v) I´ = (I – KillI)  GenI Existing edges l v

  32. copy statement l = v KillI= edges(I, l) GenI= {l} × succ(I, v) I´ = (I – KillI)  GenI Generated edges l v

  33. 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 Existing edges l1 f l2

  34. 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 f l2

  35. 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} Existing edges l1 l2

  36. 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 f l2

  37. store statement l1.f = l2 GenI= (succ(I, l1) × {f}) × succ(I, l2) I´ = I  GenI Existing edges l1 l2

  38. store statement l1.f = l2 GenI= (succ(I, l1) × {f}) × succ(I, l2) I´ = I  GenI Generated edges l1 f l2

  39. object creation site l = new cl KillI= edges(I, l) GenI= {<l, n>} Existing edges l

  40. object creation site l = new cl KillI= edges(I, l) GenI= {<l, n>} 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 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 [ ] database elementData e

  45. 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); } graph before call site [ ] database elementData e callee graph [ ] database elementData this highestPaid Enum object is not present because it was captured in the callee.

  46. Step 1: Map formals to actuals 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 [ ] database elementData e callee graph [ ] database elementData this highestPaid

  47. Step 1: Map formals to actuals 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 [ ] database elementData e highestPaid database callee graph [ ] elementData

  48. 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 [ ] database elementData e highestPaid database callee graph [ ] elementData

  49. 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 [ ] database elementData e elementData callee graph [ ]

  50. 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 [ ] database elementData e elementData callee graph [ ]

More Related