Establishing Local Temporal Heap Safety Properties with Applications to Compile-Time Memory...

Post on 19-Dec-2015

215 views 0 download

transcript

Establishing Local Temporal Heap Safety Properties with Applications to

Compile-Time Memory Management

Ran Shaham

Eran Yahav

Elliot Kolodner

Mooly Sagiv

Memory deallocation in a timely manner is a hard problem

• Premature deallocation Program errors

• Late deallocation Memory leaks Inefficient use of memory

(Old) Idea: Compile-Time GC

• The compiler can issue free when objects are no longer needed– Object may still be reachable– Potentially collects objects earlier than run-time

garbage collection• Low cost• Candidate for memory/cpu constrained

environments• Difficult for imperative heap-manipulating

programs– No static names for objects– Destructive updates (mutations) x.field=null

Results

• A framework for developing static algorithms for memory management– Compile-Time GC

• Free an unneeded object• Handle destructive updates

– GC assistance • Assign null to heap references• Reduces reachability heap graph• GC exploits information

Plan

• A motivating example program

• The heap safety automaton

• Concrete semantics for deallocating space

• Abstract semantics for deallocating space

• Assign Null

• Summary

A Linked List Example class L { // L is a singly linked list public L n; // next field public int val; // data field } class Main { // Creation and traversal of a singly-linked list public static void main(String args[]) { L x, y, t; [1] x = null; [2] while (...) { // list creation [3] y = new L(); [4] y.val = ...; [5] y.n = x; [6] x = y; } [7] y = x; [8] while (y != null) { // list traversal [9] System.out.print(y.val);[10] t = y.n;[11] y = t; } } }

A Linked List Example class L { // L is a singly linked list public L n; // next field public int val; // data field } class Main { // Creation and traversal of a singly-linked list public static void main(String args[]) { L x, y, t; [1] x = null; [2] while (...) { // list creation [3] y = new L(); [4] y.val = ...; [5] y.n = x; [6] x = y; } [7] y = x; [8] while (y != null) { // list traversal [9] System.out.print(y.val);[10] t = y.n;[11] y = t; } } }

xu1 u2 u3 u7u6

y

u4n nn n n n nu5

A Linked List Example class L { // L is a singly linked list public L n; // next field public int val; // data field } class Main { // Creation and traversal of a singly-linked list public static void main(String args[]) { L x, y, t; [1] x = null; [2] while (...) { // list creation [3] y = new L(); [4] y.val = ...; [5] y.n = x; [6] x = y; } [7] y = x; [8] while (y != null) { // list traversal [9] System.out.print(y.val);[10] t = y.n;[11] y = t; } } }

t

xu1 u2 u3 u7u6

y

u4n nn n n n nu5

A Linked List Example class L { // L is a singly linked list public L n; // next field public int val; // data field } class Main { // Creation and traversal of a singly-linked list public static void main(String args[]) { L x, y, t; [1] x = null; [2] while (...) { // list creation [3] y = new L(); [4] y.val = ...; [5] y.n = x; [6] x = y; } [7] y = x; [8] while (y != null) { // list traversal [9] System.out.print(y.val);[10] t = y.n;[11] y = t; } } }

t

xu1 u2 u3 u7u6

y

u4n nn n n n nu5

A Linked List Example class L { // L is a singly linked list public L n; // next field public int val; // data field } class Main { // Creation and traversal of a singly-linked list public static void main(String args[]) { L x, y, t; [1] x = null; [2] while (...) { // list creation [3] y = new L(); [4] y.val = ...; [5] y.n = x; [6] x = y; } [7] y = x; [8] while (y != null) { // list traversal [9] System.out.print(y.val);[10] t = y.n;[11] y = t; } } }

y t

xu1 u2 u3 u7u6u4

n nn n n n nu5

A Linked List Example class L { // L is a singly linked list public L n; // next field public int val; // data field } class Main { // Creation and traversal of a singly-linked list public static void main(String args[]) { L x, y, t; [1] x = null; [2] while (...) { // list creation [3] y = new L(); [4] y.val = ...; [5] y.n = x; [6] x = y; } [7] y = x; [8] while (y != null) { // list traversal [9] System.out.print(y.val);[10] t = y.n;[11] y = t; } } }

y t

xu1 u2 u3 u7u6u4

n nn n n n nu5

Free Unneeded Objects class L { // L is a singly linked list public L n; // next field public int val; // data field } class Main { // Creation and traversal of a singly-linked list public static void main(String args[]) { L x, y, t; [1] x = null; [2] while (...) { // list creation [3] y = new L(); [4] y.val = ...; [5] y.n = x; [6] x = y; } [7] y = x; [8] while (y != null) { // list traversal [9] System.out.print(y.val);[10] t = y.n; “free y;”[11] y = t; } } }

y t

xu1 u2 u3 u7u6u4

n nn n n n nu5

When can we free an object?

a = malloc(…) ;

b = a;

// free (a); ?

c = malloc (…);

if (b == c) printf(“unexpected equality”);

Cannot free an object if it has a reference with a future use!

When can free x be inserted after p?

pcannot free x

x references an object l

some reference to l is used

On all execution paths after p there are no uses of references to the object referenced by x

inserting free x after p is valid

Computing Free Information

• Forward (history) information– Heap paths– For free x after p

• Aliases of x after p

• Backward (future) information– Use of references– For free x after p

• Future use of aliases of x after p

• Integration of forward and backward heap information– Alternatives

• Integration of an operational semantics and a backward collecting semantics

• Automaton-based solution– Automaton states record “future” information

The Heap Safety Automaton

• Describes a local temporal heap safety property (a typestate property)– Holds on an execution path for an object– Independent of other objects– In an accepting state on an execution path for an

object

• Used for property verification– Automaton does not reach the “err” state– For all execution paths for all objects

free x after p automaton

pcannot free x

x references an object l

some reference to l is used

errinitial refp,x use

0

use refp,x

1

Automaton for an object l

A Concrete Semantics for Deallocating Space

• Program state– “Usual heap information”

• Variable values, Field Values

– Free x after p automaton state• For every object l

• Program statement effect– “Usual semantics”– Trigger automaton events

class L { // L is a singly linked list public L n; // next field public int val; // data field } class Main { // Creation and traversal of a singly-linked list public static void main(String args[]) { L x, y, t; [1] x = null; [2] while (...) { // list creation [3] y = new L(); [4] y.val = ...; [5] y.n = x; [6] x = y; } [7] y = x; [8] while (y != null) { // list traversal [9] System.out.print(y.val);[10] t = y.n;[11] y = t; } } }

Automaton for an object l

Free “y at 10” Automaton

errinitial ref10,y use

0

use ref10,y

1

xu1 u2 u3 u7u6

y

u4n nn n n n nu5

S[0] S[0] S[0] S[0]S[0] S[0]S[0]

class L { // L is a singly linked list public L n; // next field public int val; // data field } class Main { // Creation and traversal of a singly-linked list public static void main(String args[]) { L x, y, t; [1] x = null; [2] while (...) { // list creation [3] y = new L(); [4] y.val = ...; [5] y.n = x; [6] x = y; } [7] y = x; (use x) [8] while (y != null) { // list traversal [9] System.out.print(y.val);[10] t = y.n;[11] y = t; } } }

Automaton for an object l

Free “y at 10” Automaton

errinitial ref10,y use

0

use ref10,y

1

xu1 u2 u3 u7u6

y

u4n nn n n n nu5

S[0] S[0] S[0] S[0]S[0] S[0]S[0]

class L { // L is a singly linked list public L n; // next field public int val; // data field } class Main { // Creation and traversal of a singly-linked list public static void main(String args[]) { L x, y, t; [1] x = null; [2] while (...) { // list creation [3] y = new L(); [4] y.val = ...; [5] y.n = x; [6] x = y; } [7] y = x; [8] while (y != null) { // list traversal [9] System.out.print(y.val);[10] t = y.n;[11] y = t; } } }

Automaton for an object l

Free “y at 10” Automaton

errinitial ref10,y use

0

use ref10,y

1

y t

xu1 u2 u3 u7u6u4

n nn n n n nu5S[0] S[0] S[0] S[0]S[0] S[0]S[0]

class L { // L is a singly linked list public L n; // next field public int val; // data field } class Main { // Creation and traversal of a singly-linked list public static void main(String args[]) { L x, y, t; [1] x = null; [2] while (...) { // list creation [3] y = new L(); [4] y.val = ...; [5] y.n = x; [6] x = y; } [7] y = x; [8] while (y != null) { // list traversal [9] System.out.print(y.val);[10] t = y.n; (use y, use y.n, ref10,y)[11] y = t; } } }

Automaton for an object l

Free “y at 10” Automaton

errinitial ref10,y use

0

use ref10,y

1

y t

xu1 u2 u3 u7u6u4

n nn n n n nu5S[0] S[0] S[0] S[0]S[0] S[0]S[0]

class L { // L is a singly linked list public L n; // next field public int val; // data field } class Main { // Creation and traversal of a singly-linked list public static void main(String args[]) { L x, y, t; [1] x = null; [2] while (...) { // list creation [3] y = new L(); [4] y.val = ...; [5] y.n = x; [6] x = y; } [7] y = x; [8] while (y != null) { // list traversal [9] System.out.print(y.val);[10] t = y.n; (use y, use y.n, ref10,y)[11] y = t; } } }

Automaton for an object l

Free “y at 10” Automaton

errinitial ref10,y use

0

use ref10,y

1

y t

xu1 u2 u3 u7u6u4

n nn n n n nu5S[0] S[0] S[0] S[0]S[0] S[0]S[0]

class L { // L is a singly linked list public L n; // next field public int val; // data field } class Main { // Creation and traversal of a singly-linked list public static void main(String args[]) { L x, y, t; [1] x = null; [2] while (...) { // list creation [3] y = new L(); [4] y.val = ...; [5] y.n = x; [6] x = y; } [7] y = x; [8] while (y != null) { // list traversal [9] System.out.print(y.val);[10] t = y.n; (use y, use y.n, ref10,y)[11] y = t; } } }

Automaton for an object l

Free “y at 10” Automaton

errinitial ref10,y use

0

use ref10,y

1

y t

xu1 u2 u3 u7u6u4

n nn n n n nu5S[0] S[0] S[0] S[0]S[0] S[0]S[0]

class L { // L is a singly linked list public L n; // next field public int val; // data field } class Main { // Creation and traversal of a singly-linked list public static void main(String args[]) { L x, y, t; [1] x = null; [2] while (...) { // list creation [3] y = new L(); [4] y.val = ...; [5] y.n = x; [6] x = y; } [7] y = x; [8] while (y != null) { // list traversal [9] System.out.print(y.val);[10] t = y.n; (use y, use y.n, ref10,y)[11] y = t; } } }

Automaton for an object l

Free “y at 10” Automaton

errinitial ref10,y use

0

use ref10,y

1

y t

xu1 u2 u3 u7u6u4

n nn n n n nu5S[1] S[0] S[0] S[0]S[0] S[0]S[0]

class L { // L is a singly linked list public L n; // next field public int val; // data field } class Main { // Creation and traversal of a singly-linked list public static void main(String args[]) { L x, y, t; [1] x = null; [2] while (...) { // list creation [3] y = new L(); [4] y.val = ...; [5] y.n = x; [6] x = y; } [7] y = x; [8] while (y != null) { // list traversal [9] System.out.print(y.val);[10] t = y.n; (use y, use y.n, ref10,y)[11] y = t; } } }

Automaton for an object l

Free “y at 10” Automaton

errinitial ref10,y use

0

use ref10,y

1

y t

xu1 u2 u3 u7u6u4

n nn n n n nu5S[1] S[1] S[1] S[0]S[0] S[0]S[1]

Abstract Semantics for Deallocating Space –

Challenges• Infinite states

– Number of objects is unbounded

• Precise heap path information– Precise Association of

• an event• corresponding automaton state of a program object

• Our framework– Allows a rather precise heap abstraction– Abstraction refinement

• automaton state of each program object

Abstract Semantics for Deallocating Space

• Program state– Heap Abstraction

• Parametric Shape Analysis [SRW02]• Based on 3-valued logical structures

– Automaton States• Unary predicates s[q]• q ranges over automaton states

• Program statement effect– Shape analysis abstract transformers– Events associated with every statement update s[q]

• Property Verification– s[err] does not hold

Automaton for an object l

Free “y at 10” Automaton class L { // L is a singly linked list public L n; // next field public int val; // data field } class Main { // Creation and traversal of a singly-linked list public static void main(String args[]) { L x, y, t; [1] x = null; [2] while (...) { // list creation [3] y = new L(); [4] y.val = ...; [5] y.n = x; [6] x = y; } [7] y = x; [8] while (y != null) { // list traversal [9] System.out.print(y.val);[10] t = y.n;[11] y = t; } } }

errinitial ref10,y use

0

use ref10,y

1

x S[1]

y

S[0]n n n

S[1]

nt

S[0]n

n

S[0]

Automaton for an object l

Free “y at 10” Automaton class L { // L is a singly linked list public L n; // next field public int val; // data field } class Main { // Creation and traversal of a singly-linked list public static void main(String args[]) { L x, y, t; [1] x = null; [2] while (...) { // list creation [3] y = new L(); [4] y.val = ...; [5] y.n = x; [6] x = y; } [7] y = x; [8] while (y != null) { // list traversal [9] System.out.print(y.val);[10] t = y.n; (use y, use y.n, ref10,y)[11] y = t; } } }

errinitial ref10,y use

0

use ref10,y

1

x S[1]

y

S[0]n n n

S[1]

nt

S[0]n

n

S[0]

Automaton for an object l

Free “y at 10” Automaton class L { // L is a singly linked list public L n; // next field public int val; // data field } class Main { // Creation and traversal of a singly-linked list public static void main(String args[]) { L x, y, t; [1] x = null; [2] while (...) { // list creation [3] y = new L(); [4] y.val = ...; [5] y.n = x; [6] x = y; } [7] y = x; [8] while (y != null) { // list traversal [9] System.out.print(y.val);[10] t = y.n; (use y, use y.n, ref10,y)[11] y = t; } } }

errinitial ref10,y use

0

use ref10,y

1

x S[1]

y

S[0]n n n

S[1]

nt

S[0]n

n

S[0]

Automaton for an object l

Free “y at 10” Automaton class L { // L is a singly linked list public L n; // next field public int val; // data field } class Main { // Creation and traversal of a singly-linked list public static void main(String args[]) { L x, y, t; [1] x = null; [2] while (...) { // list creation [3] y = new L(); [4] y.val = ...; [5] y.n = x; [6] x = y; } [7] y = x; [8] while (y != null) { // list traversal [9] System.out.print(y.val);[10] t = y.n; (use y, use y.n, ref10,y)[11] y = t; } } }

errinitial ref10,y use

0

use ref10,y

1

x S[1]

y

S[0]n n n

S[1]

nt

S[0]n

n

S[0]

Automaton for an object l

Free “y at 10” Automaton class L { // L is a singly linked list public L n; // next field public int val; // data field } class Main { // Creation and traversal of a singly-linked list public static void main(String args[]) { L x, y, t; [1] x = null; [2] while (...) { // list creation [3] y = new L(); [4] y.val = ...; [5] y.n = x; [6] x = y; } [7] y = x; [8] while (y != null) { // list traversal [9] System.out.print(y.val);[10] t = y.n; (use y, use y.n, ref10,y)[11] y = t; } } }

errinitial ref10,y use

0

use ref10,y

1

x S[1]

y

S[1]n n n

S[1]

nt

S[0]n

n

S[0]

Assign Null

• Allows GC to collect more space– Reduces heap reachability

• Assign-Null automaton– Contains “back-edges”

When can x.f = null be inserted after p?

pp’

x.f cannot be assigned null

On all execution paths after p, x.f is not used before redefinition

inserting x.f = null after p is valid

field f of object l is not assigned

field f of object l is used

x references an object l

pp’field f of object l

is not assigned

field f of object l is used

errinitial refp,x usef0

usef,deff refp,x

1

deff

x.f cannot be assigned null

x references an object l

When can x.f = null be inserted after p?

pp’field f of object l

is not assigned

field f of object l is used

errinitial refp,x usef0

usef,deff refp,x

1

deff

x.f cannot be assigned null

x references an object l

When can x.f = null be inserted after p?

pp’field f of object l

is not assigned

field f of object l is used

errinitial refp,x usef0

usef,deff refp,x

1

deff

x.f cannot be assigned null

x references an object l

When can x.f = null be inserted after p?

pp’field f of object l

is not assigned

field f of object l is used

errinitial refp,x usef0

usef,deff refp,x

1

deff

x.f cannot be assigned null

x references an object l

When can x.f = null be inserted after p?

pp’field f of object l

is not assigned

field f of object l is used

errinitial refp,x usef0

usef,deff refp,x

1

deff

x.f cannot be assigned null

x references an object l

When can x.f = null be inserted after p?

Prototype Implementation

• Analysis of Java/JavaCard programs

• Precise– Points-to is not enough

• Even when it is flow-sensitive, field-sensitive with unbounded context [Emami et al. – PLDI 94]

• Scalability issues– Interprocedural shape analysis

Related Work

• Memory Management– Compile-Time GC

• Mostly for functional languages

– Escape Analysis• Limited to objects not escaping their allocating method

– Region-based memory management• Usually requires programmer awareness

• Software verification of safety properties– Bandera, ESP, SLAM

• Precision• Application domain

Summary

• Statically identify a subset of unneeded objects • Free

– Free an unneeded object– Similar to compile-time GC studied for functional languages

• We need to handle destructive updates

• Assign null – Assign null to heap references– Reduces reachability heap graph– GC exploits information

• Identify potential errors– Issue a warning when a potentially needed object is reclaimed

• False alarms may arise

• A framework– Formulate compile-time memory management as a verification

problem