Title: UniquenessInference for Individual Object Deallocation Sigmund Cherem and Radu Rugina
1Uniqueness-Inference for Individual Object
DeallocationSigmund Cherem and Radu Rugina
- International Symposium on Memory Management
- October, 2007
2What This Talk Is About
- Reasoning about heap using uniqueness
- Programmers use invariants to deal with heap
complexity - E.g. uniqueness, encapsulation
- Compiler can benefit from knowledge of these
invariants - Using uniqueness for compile-time memory
management - Transform Java to Jfree (Java free)
- Add effective and predictable memory reclamation
- Guarantee absence of memory errors
- Support for real-time systems
- Reduce run-time overhead
VMfree
Compiler
Java Program
Jfree Program
3Uniqueness Definitions
- A reference (variable or field) at program point
p is unique iff it is the only pointer to its
target - A reference is totally unique if it is unique at
all times - Too restrictive Java programs may have unique
references that are temporarily shared
unique
not unique
all unique
4Uniqueness Definitions
- A reference (variable or field) at program point
p is unique iff it is the only pointer to its
target - A reference is totally unique if it is unique at
all times - Too restrictive Java programs may have unique
references that are temporarily shared - A reference is weakly unique if it is unique at
least at method boundaries - Can model structures like lists and trees
unique
not unique
all unique
5Use of Uniqueness for MM
- Dead unique references can be reclaimed with free
statements
x new List() // x is unique dead
6Use of Uniqueness for MM
- Dead unique references can be reclaimed with free
statements
x new List() free(x) // x is unique dead
7Use of Uniqueness for MM
- Dead unique references can be reclaimed with free
statements
x new List() free(x) // x is unique dead
List Elem head // weakly unique
8Use of Uniqueness for MM
- Dead unique references can be reclaimed with free
statements
x new List() free(x.head) free(x) // x is
unique dead
List Elem head // weakly unique
9Use of Uniqueness for MM
- Dead unique references can be reclaimed with free
statements
- Unique fields can be reclaimed with destructors
x new List() free(x.head) free(x) // x is
unique dead
List Elem head // weakly unique
10Use of Uniqueness for MM
- Dead unique references can be reclaimed with free
statements
- Unique fields can be reclaimed with destructors
x new List() x.destroy() free(x) // x is
unique dead
List Elem head // weakly unique void
destroy()
free(head)
11Use of Uniqueness for MM
- Dead unique references can be reclaimed with free
statements
- Unique fields can be reclaimed with destructors
- Support for reclaiming recursive structures
x new List() x.destroy() free(x) // x is
unique dead
List Elem head // weakly unique void
destroy()
free(head)
12Use of Uniqueness for MM
- Dead unique references can be reclaimed with free
statements
- Unique fields can be reclaimed with destructors
- Support for reclaiming recursive structures
x new List() x.destroy() free(x) // x is
unique dead
Elem Elem next // weakly unique Object
data
List Elem head // weakly unique void
destroy()
free(head)
13Use of Uniqueness for MM
- Dead unique references can be reclaimed with free
statements
- Unique fields can be reclaimed with destructors
- Support for reclaiming recursive structures
x new List() x.destroy() free(x) // x is
unique dead
Elem Elem next // weakly unique Object
data void destroy() if (next !
null) next.destroy() free(next)
List Elem head // weakly unique void
destroy() if (head ! null)
head.destroy() free(head)
14System Design
Java Program
Uniqueness Inference
Transformation
Jfree Program
Method Summaries
15System Design
Java Program
Uniqueness Inference
Libraries
Compute Lightweight Summaries (CC 07)
Transformation
Jfree Program
Method Summaries
16System Design
Java Program
Uniqueness Inference
Transformation
Jfree Program
Method Summaries
17System Design
Local Must-alias Dataflow Analysis
Java Program
Local Abstraction
Constraints
Global Constraint System
Global Abstraction
Transformation
Jfree Program
Method Summaries
18System Design
Only Intra-procedural
Local Must-alias Dataflow Analysis
Java Program
Local Abstraction
Constraints
Global Constraint System
Whole-program but lightweight
Global Abstraction
Transformation
Jfree Program
Method Summaries
19Local Must-alias Dataflow Analysis
20Local Must-alias Dataflow Analysis
- Goal answer questions
- Where are fields and variables unique, and where
not? - Is a field or parameter shared at method
boundaries? - Is the uniqueness of two references correlated?
- Strategy
- Track objects manipulated (shape analysis)
- Must-aliases per program point
- Keep it intra-procedural (modularity)
- Initialization assume all external references
are unique - Method calls use summaries to model effects of
method calls
21Analysis Example
List void add(Object p) Elem e new
Elem() e.data p e.next
this.head this.head e
- Explore state of objects assuming all fields and
parameters are unique at method entry - Track objects allocated
- Track external objects potentially read in the
method
22p
add(Object p) Elem e new Elem()
e.data p e.next this.head this.head
e // locals are dead
head
e
23p
add(Object p) Elem e new Elem()
e.data p e.next this.head this.head
e // locals are dead
head
e
e
24p
add(Object p) Elem e new Elem()
e.data p e.next this.head this.head
e // locals are dead
head
e
e
e
25p
add(Object p) Elem e new Elem()
e.data p e.next this.head this.head
e // locals are dead
head
e
e
e
e
this
head
26p
add(Object p) Elem e new Elem()
e.data p e.next this.head this.head
e // locals are dead
head
e
e
e
e
this
head
head
27p
add(Object p) Elem e new Elem()
e.data p e.next this.head this.head
e // locals are dead
head
head
28p
add(Object p) Elem e new Elem()
e.data p e.next this.head this.head
e // locals are dead
head
head
29p
add(Object p) Elem e new Elem()
e.data p e.next this.head this.head
e // locals are dead
head
head
30p
add(Object p) Elem e new Elem()
e.data p e.next this.head this.head
e // locals are dead
head
o ? this
this
head
31p
add(Object p) Elem e new Elem()
e.data p e.next this.head this.head
e // locals are dead
head
o ? this
this
e
next
this
head
32p
add(Object p) Elem e new Elem()
e.data p e.next this.head this.head
e // locals are dead
head
o ? this
this
e
next
this
e
head
33p
add(Object p) Elem e new Elem()
e.data p e.next this.head this.head
e // locals are dead
head
o ? this
this
e
next
this
e
next
head
34p
add(Object p) Elem e new Elem()
e.data p e.next this.head this.head
e // locals are dead
head
o ? this
this
e
next
this
o ? this
e
next
head
35p
add(Object p) Elem e new Elem()
e.data p e.next this.head this.head
e // locals are dead
head
o ? this
this
e
next
this
o ? this
e
o ? this
next
head
36p
add(Object p) Elem e new Elem()
e.data p e.next this.head this.head
e // locals are dead
head
o ? this
this
e
next
this
o ? this
e
o ? this
next
head
head
37p
add(Object p) Elem e new Elem()
e.data p e.next this.head this.head
e // locals are dead
head
next
head
head
38p
add(Object p) Elem e new Elem()
e.data p e.next this.head this.head
e // locals are dead
head
p
next
head
head
39p
add(Object p) Elem e new Elem()
e.data p e.next this.head this.head
e // locals are dead
head
p
p
data
next
head
head
40p
add(Object p) Elem e new Elem()
e.data p e.next this.head this.head
e // locals are dead
head
p
p
data
p
p
next
head
head
41p
add(Object p) Elem e new Elem()
e.data p e.next this.head this.head
e // locals are dead
head
p
p
data
p
p
data
next
head
head
42p
head
data
next
head
head
43p
head
- Local Analysis Results
- Local Abstraction
data
next
head
head
44p
head
- Local Analysis Results
- Local Abstraction
p
e
p
e
data
o ? this
this
e
p
e
next
this
o ? this
p
e
this
e
head
o ? this
data
next
head
head
45p
head
- Local Analysis Results
- Local Abstraction
- Method Boundaries Constraints
- Sharing (0)
- Correlation (2)
data
next
head
head
46p
head
- Local Analysis Results
- Local Abstraction
- Method Boundaries Constraints
- Sharing (0)
- Correlation (2)
head
p
next
data
If head is shared at entry of method Then next is
also shared
If p is shared, so is data
data
next
head
head
47Global Constraint System
- Enforce references are truly unique at method
boundaries - Graph representation
- Nodes parameters, fields, and S (special shared
node) - Edges if source is shared, target is shared
- Examples
- f is shared by method exit
- Actual parameter ai is not dead (formal pi is
shared) - next unique at exit, assuming head was unique
- Constraint resolution simple graph reachability
- A reference is weakly unique if it is not
reachable from S
S
f
S
pi
head
next
48Collected Results
- Local Abstraction
- Set of object states per program point p
- May depend on the uniqueness of a field or
parameter - Global Abstraction
- Set of weakly unique parameters and fields
- These results are sufficient to answer uniqueness
queries - Example Is x unique at p?
- Yes when all object states at p containing x
- have no aliases (local abstraction)
- only depend on weakly unique references (global
abstraction)
49Transformation
50Transformation
- Add frees on unique references that become dead
- After statement
- On control flow edge
51Transformation
- Add frees on unique references that become dead
- After statement
- On control flow edge
x new List() if () x.hashCode() // x
is unique dead foo() // x is unique
dead x null
52Transformation
- Add frees on unique references that become dead
- After statement
- On control flow edge
if
x new List() if () x.hashCode() // x
is unique dead foo() // x is unique
dead x null
x.hashcode()
foo()
x null
53Transformation
- Add frees on unique references that become dead
- After statement
- On control flow edge
if
x new List() if () x.hashCode()
free(x)// x is unique dead foo() // x is
unique dead x null
x.hashcode()
free(x)
foo()
x null
54Transformation
- Add frees on unique references that become dead
- After statement
- On control flow edge
if
x new List() if () x.hashCode()
free(x)// x is unique dead
foo() free(x) ??? // x is unique dead x
null
x.hashcode()
free(x)
foo()
free(x)
x null
55Transformation
- Add frees on unique references that become dead
- After statement
- On control flow edge
if
x new List() if () x.hashCode()
free(x)// x is unique dead foo() else
free(x)// x is unique dead x null
x.hashcode()
free(x)
free(x)
foo()
x null
56Transformation
- Add frees on unique references that become dead
- After statement
- On control flow edge
57Transformation
- Add frees on unique references that become dead
- After statement
- On control flow edge
- Add destructors for weakly unique fields
- Add calls to destructors
- Warning destructor calls are not always safe
- Safe only when fields inductively touched by
destructors are truly unique (at the point of the
call)
58Transformation
- Add frees on unique references that become dead
- After statement
- On control flow edge
- Add destructors for weakly unique fields
- Add calls to destructors
- Warning destructor calls are not always safe
- Safe only when fields inductively touched by
destructors are truly unique (at the point of the
call) - Extend methods with uniqueness argument to
support context-sensitive transformation
(conditional uniqueness)
59Conditional Uniqueness
Id lookup (String s) Id v get(s) if (v
null) v new Id(s) put(s,
v) return v
60Conditional Uniqueness
lookup(example1)
String u new String(example2) lookup(u)
Id lookup (String s) Id v get(s) if (v
null) v new Id(s) put(s,
v) return v
61Conditional Uniqueness
lookup(example1)
String u new String(example2) lookup(u)
free(u) ???
Id lookup (String s) Id v get(s) if (v
null) v new Id(s) put(s,
v) return v
62Conditional Uniqueness
lookup(example1)
String u new String(example2) lookup(u)
Id lookup (String s) Id v get(s) if (v
null) v new Id(s) put(s,
v) else free(s) ??? return v
63Conditional Uniqueness
lookup(example1, false)
String u new String(example2) lookup(u,
true)
Id lookup (String s, boolean s_is_unique) Id
v get(s) if (v null) v new
Id(s) put(s, v) else if
(s_is_unique) free(s) return v
64Experimental Evaluation
65Settings and Compiling Statistics
- Implementation Infrastructure
- Jfree-UI Compiler System
- Soot infrastructure 2.2.2 Vallee-Rai et al. 99
- JfreeVM Runtime System
- JikesRVM 2.3.5 Alpern et al. 99
- MMTk Blackburn et al. 04
- Programs Analyzed
- SPECjvm98 (exclude mpegaudio) 2630 methods
- Analysis time (average per program) 7 sec
- Weakly unique fields (all) 22
- Libraries (java.lang, java.util, java.io) 5426
methods - Analysis time (total) 30 sec
- Weakly unique fields (all) 8
66Memory Freed
of total allocated memory
67Memory Freed
of total allocated memory
68Memory Freed
of total allocated memory
69Memory Freed
of total allocated memory
70Memory Freed
of total allocated memory
71Memory Freed
of total allocated memory
72Runtime Savings
5
Free MS MS
4
3
Time normalized w.r.t time of No MM
2
1.5
Geometric Mean in SPECjvm98
1.25
1
1
2
3
4
5
1.16
1.33
1.66
Memory Size normalized w.r.t. MS min heap
73Comparison to Previous Work
Java Bytecode
JFree SA ISMM06
Java Bytecode Free
VM Free
74Comparison to Previous Work
Java Bytecode
JFree SA ISMM06
660 s
Total analysis time (SPEC)
Java Bytecode Free
VM Free
75Comparison to Previous Work
Java Bytecode
JFree SA ISMM06
660 s
Total analysis time (SPEC)
Java Bytecode Free
Average memory savings
54
VM Free
76Comparison to Previous Work
Java Bytecode
JFree SA ISMM06
JFree UI (this talk)
660 s
Total analysis time (SPEC)
Java Bytecode Free
Average memory savings
54
VM Free
77Comparison to Previous Work
Java Bytecode
JFree SA ISMM06
JFree UI (this talk)
660 s
45 s
Total analysis time (SPEC)
Java Bytecode Free
Average memory savings
61
54
VM Free
78Related Work
- Compile-Time Memory Management
- Stack Allocation and Region-based MM
- Blanchet OOPLSA99, Choi et al. OOPSLA99, Whaley
and Rinard OOPSLA99, Bogda and Hoelzle
OOPSLA99, Gay/Steensgard CC00 - Tofte and Talpin POPL94, AFL PLDI95,
- Cherem and Rugina ISMM04, Chin et al. PLDI04
- Individual Object Deallocation
- Cherem and Rugina ISMM06, Guyer et al. PLDI06,
Shaham et al. SAS03 - Shape Analysis
- Sagiv et al. POPL99, Hackett and Rugina POPL05
- Linear Types and Unique references
- Language support Wadler 90, Minsky ECOOP96,
Hicks et al. ISMM04 (Cyclone), Boyland SPE01,
Adrich et al. OOPSLA02 (AliasJava) - Inference Cherem and Rugina CC07, Ma and Foster
OOPSLA07, Adrich et al. OOSPLA02
79Conclusions
- Uniqueness Inference Algorithm
- Exploits modular design of programmers
invariants - It allows temporary sharing (both stack and heap)
- Applications to program understanding and to MM
- Uniqueness based MM transformation
- Supports reclamation of recursive structures via
destructors - Experimental evaluation
- Analysis is modular and fast (10x improvement)
- 22 of application fields are unique
- 60 of memory can be reclaimed statically
- Transformed programs can run 31 faster for small
heaps