790 likes | 942 Views
Pointer and Escape Analysis for (Multithreaded) Programs. Martin Rinard MIT Laboratory for Computer Science. Traditional Escape Analysis. Procedures Dynamically allocated objects Does an object escape the allocating procedure? Is the lifetime of object contained in lifetime of procedure?
E N D
Pointer and Escape Analysis for (Multithreaded) Programs Martin Rinard MIT Laboratory for Computer Science
Traditional Escape Analysis • Procedures • Dynamically allocated objects • Does an object escape the allocating procedure? • Is the lifetime of object contained in lifetime of procedure? • If so, can stack allocate object • Sequential programs
Modern Escape Analysis • Region of Program • Procedure • Thread • Group of Threads • Multiple-Entry Component • Dynamically allocated objects • Is object “captured” within region?
Uses of Escape Information • Negative Interaction Information • Past: Traditional Compiler Optimizations • Stack Allocation • Synchronization Elimination • Variety of Dynamic Check Eliminations
Foundation for Interaction Analyses • Systems built from groups of reconfigurable components • Important to understand interactions • Safety of composition • Transform to enhance fast reconfiguration, fault-tolerance, predictability, performance • Escape analysis focuses interaction analyses • Eliminates host of potential interactions • Cuts away large parts of program • Enables use of more powerful interaction analyses
Importance of Interaction Analysis • Need a global information about properties of potential component compositions • Interaction patterns • Inter-component dependences • Theme: see across component boundaries • Payoff • Information about behavior of potential composed systems • Customized implementations • Functionality-improving transformations • Reduce vulnerability to failures • Improve adaptation response times
Key Requirements • Rapid reconfiguration, adaptability, customization • Huge range of potential customized combinations • Envisioned large-scale transformations impractical to perform manually • Need to automate interaction analysis and subsequent transformations • Distributed systems inherently concurrent • Analyze multithreaded programs • Characterize and exploit interactions between threads
Outline • Combined Pointer and Escape Analysis • Sequential Programs • Multithreaded Programs • Implementation in Flex Compiler • Experimental Results
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
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 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
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
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 Existing edges l v
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 Existing edges l1 f l2
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
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
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
store statement l1.f = l2 GenI= (succ(I, l1) × {f}) × succ(I, l2) I´ = I GenI Existing edges l1 l2
store statement l1.f = l2 GenI= (succ(I, l1) × {f}) × succ(I, l2) I´ = I GenI Generated edges l1 f l2
object creation site l = new cl KillI= edges(I, l) GenI= {<l, n>} Existing edges l
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 a 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 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); }
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
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.
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
Step 2: Match edges to extend mapping 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
Step 3: Map nodes and edges to construct new graph graph after call site [ ] database elementData e highestPaid graph before call site [ ] database elementData e callee graph [ ] database elementData this highestPaid
Key Feature • Even if an object escapes one method • Often possible to recapture object in caller methods • Common in practice • Iterators • Objects that hold multiple return values
Life is not so Simple • Dependences between phases • Mapping best framed as constraint satisfaction problem • Solved using constraint satisfaction
Algorithm Features • Compositional • Analyze each method once • Obtain parameterized result • Reuse result at different call sites • Independent preanalysis of libraries • Partial • Can analyze method without analyzing methods it invokes • Useful if not all code available in analyzable form
Incrementalized Analysis • Compositional + Partial Enables Incrementalization • Choose object to attempt to capture • Analyze method containing allocation site • Track where object escapes • Specific call sites • Caller • Incrementally analyze only those parts • Usual Result • Significant reduction in analysis time • Almost all benefit of full analysis
Key Limitation (so far) • No analysis of interactions between threads • Objects that escape from allocating thread are NEVER recaptured • Solution: extend algorithm to analyze interactions between threads • Challenge: avoid analyzing all interleavings of statements from parallel threads
Interactions Between Threads Heap a b c d
Interactions Between Threads Heap a b c d White Thread Yellow Thread
Interactions Between Threads Heap a b c d White Thread Yellow Thread a.f = b;
Interactions Between Threads Heap a b c d t White Thread Yellow Thread a.f = b; t = a.f;
Interactions Between Threads Heap a b c d t White Thread Yellow Thread a.f = b; t = a.f; t.f = c;
Interactions Between Threads Heap a b c d p White Thread Yellow Thread a.f = b; p = b.f; t = a.f; t.f = c;
Interactions Between Threads Heap a b c d p White Thread Yellow Thread a.f = b; p = b.f; p.f = d; t = a.f; t.f = c;
Interactions Between Threads Heap a b c d White Thread Yellow Thread a.f = b; p = b.f; p.f = d; t = a.f; t.f = c;
Important Properties • Result Depends on Specific Interleaving • Analyze all Interleavings? • Iterate Across Threads to Fixed Point?
Important Properties • Result Depends on Specific Interleaving • Analyze all Interleavings? • Iterate Across Threads to Fixed Point? • Analyze Each Thread Once • Parameterized Analysis Result • Characterizes All Potential Interactions • Combine Analysis Results From Different Threads to Compute Actual Interactions • Compositional Analysis