Title: Region Analysis and Transformation for Java Programs
1Region Analysis and Transformation for Java
Programs
- Sigmund Cherem and Radu Rugina
- Cornell University
International Symposium on Memory
Management October 25, 2004
2Introduction
- Our goal
- Take a Java program and automatically add region
support - Regions for Memory Management
- Grouping objects in memory
- Removing all objects in a region at once
- Benefits
- Data locality
- Efficient memory reclamation
- Alternative to garbage collection
- No run-time GC overhead
- Appealing for real-time programs
3Region analysis for Java
- Region inference
- Static compiler analysis and transformation
- Generate programs with region support
- Region analysis for Java
- Imperative language
- Pointer-based structures
- Object-oriented features
- Multithreading, exceptions
- Our system supports
- Non-lexically scoped regions
- Allows dangling references
4Region Compilation System
Java
Jreg
5Region Compilation System
I. Group objects into regions
I Points-to Analysis
Java
Jreg
6Region Compilation System
II. Determine region lifetimes
I Points-to Analysis
Java
Jreg
II Region Liveness Analysis
7Region Compilation System
III. Program transformation
I Points-to Analysis
III Region Translation
Java
Jreg
II Region Liveness Analysis
8Outline
- Region Compilation System
I Points-to Analysis
III Region Translation
Java
Jreg
II Region Liveness Analysis
9Points-to analysis
- Points-to analysis goals
- Group objects into regions
- Construct points-to graphs
- Characterize methods effects
- Accessed regions
- Regions with allocations
- Region points-to graphs
- Nodes represent regions
- Edges represent points-to relations
10Analysis algorithm
- Intra-procedural analysis
- Flow insensitive, unification-based Steensgaard
96 - One graph per method
- Inter-procedural analysis
- Context sensitive
- Whole program analysis
- Propagate across call sites
- Bind regions of formal parameters to actual
parameters - Include callees effects and unifications in
caller
11Example data-structure
data
head
next
data
next
data
class Object
class List Elem head
class Elem Object data Elem next
12Example data-structure
data
head
next
data
next
data
class Object
class List Elem head
class Elem Object data Elem next
13Regions points-to graphs
public List reverse() List list new
List() Element elem this.head while
(elem ! null) list.addFirst(elem.data)
elem elem.next return
list
next
data
head
2
3
1
elem.data
this
elem
next
data
head
4
5
list, ret
14Inter-procedural analysis
- Region aliasing
- Propagation of unifications at call sites
- Recursive structures
- Bounding the size of abstraction
- Incorporating Java types into regions
- Object oriented features
- Virtual calls
- Callee is not precisely known to caller
15Outline
- Region Compilation System
I Points-to Analysis
III Region Translation
Java
Jreg
II Region Liveness Analysis
16Region liveness analysis
- Region liveness analysis goals
- Determine program points when a region is needed
- Produce set of live regions per program point
- Definition of region lifetime
- The region is reachable from a live variable, and
- The program may access the region in the future
17Region liveness analysis
- Analysis technique
- Backwards dataflow analysis
- Keeps track of live variables and live regions
- Analysis uses computed points-to graphs for
- Region reachability
- Incorporate statements effects
LiveV (LiveV defV) ? useV LiveR (LiveR ?
useR) ? ReachR
18Another example
public void valueAt(List coeff, Complex x)
List rev coeffs.reverse()
Complex sum new Complex(0,0) while
(!rev.empty()) Complex coeff
(Complex)rev.remove(0) Complex
tmp sum.mul(x) sum
tmp.plus(coeff)
System.out.println(sum.re , sum.im)
19Another example
public void valueAt(List coeff, Complex x)
List rev coeffs.reverse()
Complex sum new Complex(0,0) while
(!rev.empty()) Complex coeff
(Complex)rev.remove(0) Complex
tmp sum.mul(x) sum
tmp.plus(coeff)
System.out.println(sum.re , sum.im)
next
data
head
coeffs
next
data
head
rev
rev
tmp
sum
x
tmp
new
20Region lifetime
public void valueAt(List coeff, Complex x)
List rev coeffs.reverse()
Complex sum new Complex(0,0) while
(!rev.empty()) Complex coeff
(Complex)rev.remove(0) Complex
tmp sum.mul(x) sum
tmp.plus(coeff)
System.out.println(sum.re , sum.im)
next
data
head
coeffs
next
data
head
rev
rev
tmp
sum
x
tmp
new
21Region lifetime
public void valueAt(List coeff, Complex x)
List rev coeffs.reverse()
Complex sum new Complex(0,0) while
(!rev.empty()) Complex coeff
(Complex)rev.remove(0) Complex
tmp sum.mul(x) sum
tmp.plus(coeff)
System.out.println(sum.re , sum.im)
next
data
head
coeffs
next
data
head
rev
rev
tmp
sum
x
tmp
new
22Region lifetime
public void valueAt(List coeff, Complex x)
List rev coeffs.reverse()
Complex sum new Complex(0,0) while
(!rev.empty()) Complex coeff
(Complex)rev.remove(0) Complex
tmp sum.mul(x) sum
tmp.plus(coeff)
System.out.println(sum.re , sum.im)
next
data
head
coeffs
next
data
head
rev
rev
tmp
sum
x
tmp
new
23Region lifetime
public void valueAt(List coeff, Complex x)
List rev coeffs.reverse()
Complex sum new Complex(0,0) while
(!rev.empty()) Complex coeff
(Complex)rev.remove(0) Complex
tmp sum.mul(x) sum
tmp.plus(coeff)
System.out.println(sum.re , sum.im)
next
data
head
coeffs
next
data
head
rev
rev
tmp
sum
x
tmp
new
24Region lifetime
public void valueAt(List coeff, Complex x)
List rev coeffs.reverse() Complex
sum new Complex(0,0) while
(!rev.empty()) Complex coeff
(Complex)rev.remove(0) Complex tmp
sum.mul(x) sum
tmp.plus(coeff)
System.out.println(sum.re , sum.im)
next
data
head
coeffs
next
data
head
rev
rev
tmp
sum
x
tmp
new
25Region lifetime
public void valueAt(List coeff, Complex x)
List rev coeffs.reverse() Complex
sum new Complex(0,0) while
(!rev.empty()) Complex coeff
(Complex)rev.remove(0) Complex tmp
sum.mul(x) sum
tmp.plus(coeff)
System.out.println(sum.re , sum.im)
next
data
head
coeffs
next
data
head
rev
rev
tmp
sum
x
tmp
new
26Outline
- Region Compilation System
I Points-to Analysis
III Region Translation
Input Program
Output Program
II Region Liveness Analysis
27Region translation
- Region translation goals
- Incorporate analysis results in the program
- Define regions according to points-to analysis
results - Create and remove regions using liveness results
- Allocate objects in the assigned regions
- Include region parameters at call sites
- Translation process
- Single pass through the program
28Create and remove regions
- Adding create and remove statements
- Use region liveness results
public void valueAt(List coeff, Complex x)
List rev coeffs.reverse()
Complex sum new Complex(0,0) while
(!rev.empty()) Complex coeff
(Complex)rev.remove(0) Complex
tmp sum.mul(x) sum
tmp.plus(coeff)
System.out.println(sum.re , sum.im)
next
data
head
coeffs
next
data
head
1
2
rev
rev
3
4
tmp
sum
x
tmp
new
29Create and remove regions
- Adding create and remove statements
- Use region liveness results
public void valueAt(List coeff, Complex x)
List rev coeffs.reverse()
Complex sum new Complex(0,0) while
(!rev.empty()) Complex coeff
(Complex)rev.remove(0) Complex
tmp sum.mul(x) sum
tmp.plus(coeff)
System.out.println(sum.re , sum.im)
next
data
head
coeffs
next
data
head
1
2
rev
rev
3
4
tmp
sum
x
tmp
new
30Create and remove regions
- Adding create and remove statements
- Use region liveness results
public void valueAt(List coeff, Complex x)
create r1 List rev coeffs.reverse()
Complex sum new Complex(0,0) while
(!rev.empty()) Complex coeff
(Complex)rev.remove(0) Complex
tmp sum.mul(x) sum
tmp.plus(coeff) remove r1
System.out.println(sum.re , sum.im)
next
data
head
coeffs
next
data
head
1
2
rev
rev
3
4
tmp
sum
x
tmp
new
31Create and remove regions
- Adding create and remove statements
- Use region liveness results
public void valueAt(List coeff, Complex x)
create r1 List rev coeffs.reverse()
Complex sum new Complex(0,0) while
(!rev.empty()) Complex coeff
(Complex)rev.remove(0) Complex
tmp sum.mul(x) sum
tmp.plus(coeff) remove r1
System.out.println(sum.re , sum.im)
next
data
head
coeffs
next
data
head
1
2
rev
rev
3
4
tmp
sum
x
tmp
new
32Create and remove regions
- Adding create and remove statements
- Use region liveness results
public void valueAt(List coeff, Complex x)
create r1 List rev coeffs.reverse()
Complex sum new Complex(0,0) while
(!rev.empty()) Complex coeff
(Complex)rev.remove(0) create r4
Complex tmp sum.mul(x) sum
tmp.plus(coeff) remove r4
remove r1 System.out.println(sum.re
, sum.im)
next
data
head
coeffs
next
data
head
1
2
rev
rev
3
4
tmp
sum
x
tmp
new
33Loop-carried dependencies
- Loop-carried liveness dependency
public void valueAt(List coeff, Complex x)
create r1 List rev coeffs.reverse()
Complex sum new Complex(0,0) while
(!rev.empty()) Complex coeff
(Complex)rev.remove(0) create r4
Complex tmp sum.mul(x)
sum tmp.plus(coeff) remove r4
remove r1 System.out.println(sum.r
e , sum.im)
next
data
head
coeffs
next
data
head
1
2
rev
rev
3
4
tmp
sum
x
tmp
new
34Loop-carried dependencies
- Loop-carried liveness dependency
public void valueAt(List coeff, Complex x)
create r1 List rev coeffs.reverse()
Complex sum new Complex(0,0) while
(!rev.empty()) Complex coeff
(Complex)rev.remove(0) create r4
Complex tmp sum.mul(x)
sum tmp.plus(coeff) remove r4
remove r1 System.out.println(sum.r
e , sum.im)
next
data
head
coeffs
next
data
head
1
2
rev
rev
3
4
tmp
sum
x
tmp
new
35Loop-carried dependencies
- Loop-carried liveness dependency
public void valueAt(List coeff, Complex x)
create r1 List rev coeffs.reverse()
create r3 Complex sum new Complex(0,0)
while (!rev.empty()) Complex
coeff (Complex)rev.remove(0) create
r4 Complex tmp sum.mul(x)
remove r3 create r3 sum
tmp.plus(coeff) remove r4
remove r1 System.out.println(sum.re
, sum.im) remove r3
next
data
head
coeffs
next
data
head
1
2
rev
rev
3
4
tmp
sum
x
tmp
new
36Update allocation sites
- Add regions at allocation sites
- Find corresponding region in points-to graph
public void valueAt(List coeff, Complex x)
create r1 List rev coeffs.reverse()
create r3 Complex sum new Complex(0,0)
while (!rev.empty()) Complex coeff
(Complex)rev.remove(0) create r4
Complex tmp sum.mul(x) remove r3
create r3 sum tmp.plus(coeff)
remove r4 remove r1
System.out.println(sum.re , sum.im)
remove r3
next
data
head
coeffs
next
data
head
1
2
rev
rev
3
4
tmp
sum
x
tmp
new
37Update allocation sites
- Add regions at allocation sites
- Find corresponding region in points-to graph
public void valueAt(List coeff, Complex x)
create r1 List rev coeffs.reverse()
create r3 Complex sum new Complex(0,0) in
r3 while (!rev.empty()) Complex
coeff (Complex)rev.remove(0) create
r4 Complex tmp sum.mul(x)
remove r3 create r3 sum
tmp.plus(coeff) remove r4
remove r1 System.out.println(sum.re
, sum.im) remove r3
next
data
head
coeffs
next
data
head
1
2
rev
rev
3
4
tmp
sum
x
tmp
new
38Update call sites
- Include call parameters
- Use subgraph rooted at actual parameters
public void valueAt(List coeff, Complex x)
create r1 List rev coeffs.reverse()
create r3 Complex sum new Complex(0,0) in
r3 while (!rev.empty()) Complex
coeff (Complex)rev.remove(0) create
r4 Complex tmp sum.mul(x)
remove r3 create r3 sum
tmp.plus(coeff) remove r4
remove r1 System.out.println(sum.re
, sum.im) remove r3
next
data
head
coeffs
next
data
head
1
2
rev
rev
3
4
tmp
sum
x
tmp
new
39Update call sites
- Include call parameters
- Use subgraph rooted at actual parameters
public void valueAt(List coeff, Complex x)
create r1 List rev coeffs.reverseltr1,r2gt()
create r3 Complex sum new
Complex(0,0) in r3 while (!rev.empty())
Complex coeff (Complex)rev.remove(0)
create r4 Complex tmp sum.mul(x)
remove r3 create r3 sum
tmp.plus(coeff) remove r4
remove r1 System.out.println(sum.re
, sum.im) remove r3
next
data
head
coeffs
next
data
head
1
2
rev
rev
3
4
tmp
sum
x
tmp
new
40Extensions
41Functionality extensions
- Multiple threads
- Region lifetime analysis is flow sensitive
- Unsafe for multithread programs
- Extensions
- Compiler and runtime cooperation
- Exceptions
- Fail to model exceptions lifetime
- Extensions
- Thrown objects are not reclaimed
- Region clean up while walking up the stack
42Liveness extensions
- Stack allocation
- Particular instance of region lifetime
- Match regions lifetime with methods lifetime
- Statically bound number and size of allocations
- Early removal of regions
- Span region creation and removal across methods
- Inter-procedural region liveness algorithm
43Experimental results
44Experimental results
- Implementation
- Soot infrastructure for region analysis
- Bytecode level transformation
- Extended bytecodes with region instructions
- Extended the Kaffe VM to run region bytecodes
- Support new opcodes
- Region runtime support
Jreg Compiler
.class (Java)
.class (Jreg)
Jreg VM (extends Kaffe)
Soot
45Experimental results
- Evaluation
- Olden benchmarks for Java
- Average size 861 Methods each program
- Average analysis time 3.5 sec
- Approximately 15 of total compilation time
46Memory watermark
Kbytes
47Memory watermark
Kbytes
48Related work
- Region Inference
- Functional languages Tofte/Talpin 1994,
Birkedal/Tofte/Vejlstrup 1996, Aiken/Fähndrich/Lev
ien 1995, Henglein/Makholm/Niss 2001 - Imperative languages Lattner/Adve 2002, Chin et
al. 2004 - Pointer analysis
- Unification-based analysis Steensgaard 1996,
Liang/Harrold 1999 - Escape analysis and stack allocation Blanchet
1999, Choi et al 1999, Whaley/Rinard 1999,
Bogda/Hoelzle 1999, Gay/Steensgaard 2000 - Region support
- Regions at runtime Quian/Hendren 2002,
Deters/Cytron 2002 - Language support Gay/Aiken 1998, 2001, Grossman
et al 2002, Christiansen/Velschow 1998, Boyapati
et al 2003
49Future work
- Bytecode region verifier
- Verifier support for region opcodes
- Provide memory safety certification
- Region optimizations
- Merging regions with similar lifetimes
- Combining and resetting sequential regions
- Extensions with shape analysis
- Individual object deallocation
- Subregions within regions
50Conclusions
- Transformation technique
- Input standard Java programs
- Output with explicit region support
- Concrete analyses
- Reasoning about objects in regions
- Analysis to determine precise region lifetimes
- Non-lexically scoped regions
- Dangling references
- Experimental results
- Significant memory savings for some applications
- Most data allocated in stack and short-lived
regions