feudal c automatic memory management with zero runtime overhead cs263 - spring 1999 scott mcpeak dan...

16
Feudal C Automatic memory management with zero runtime overhead CS263 - Spring 1999 Scott McPeak Dan Bonachea Carol Hurwitz C

Upload: gabriel-atkins

Post on 26-Dec-2015

216 views

Category:

Documents


0 download

TRANSCRIPT

Feudal C

Automatic memory management with zero runtime overhead

CS263 - Spring 1999

Scott McPeak Dan BonacheaCarol Hurwitz

C

Outline

• Introduction - Ownership and the Owner Tree

• Goals of Feudal C

• Syntax, Type Rules, and Operational Semantics

• Examples

• Memory Safety Theorem and Proof Outline

The Basic Idea• Designate some pointers as "owners"

– Obligation to delete the pointed-at object: no memory leaks

• The rest of the pointers are "serfs"– No deletion obligation (or capability)– Must stop pointing at an object before it is

deleted: no dangling pointers

• Use the type system– Enforce the distinction (type soundness)– Enforce properties of both kinds

Ownership and the Owner TreeGlobals

main()

foo()

bar()

bigArray

A B C

localObj

dl1 dl2 dl3 dl4

owner

serf

Flavors• Owners:

• Serfs:

• This project:– Prove memory safety of restricted versions

• No leaks

• No dangling references

– Simplify language

exclusive restricted normal

efficient flexible

restricted static dynamic full RC

efficient flexible

Goals of Feudal C

• Provide memory safety (no leaks, no dangling references) through static typing

• Promote clear design practices

• Enable passing memory out of a function

• Still have a language that’s useful

Language Syntax• Types

TypeAux ::= int | t owner * t TypeAux

Type ::= t | t serf * t TypeAux

• Typical Imperative Commands & Expressions– if-then-else – Assignment (copy & transfer)

– while – Arithmetic & Boolean Expressions (no side effects)

– new / delete – Function call & return

• Rules of Thumb (enforced by typing)– No serf pointers stored in the heap or returned from functions

– No owner pointers as parameters to functions

– Dereferencing serf pointers gets only serf pointers

• Limitations:– No Arrays – No “Legacy” Pointers

– No Records – No Function types or pointers

– No address-of operator – No Recursive Types (*)

Small Example

int owner* owner* allocSmallList(int val) {int owner* x; // variable declarations

int owner* owner* y;

x := new int; // allocate an integer on the heap

*x = val; // store val there

y := new int owner*; // create a pointer on the heap

*y := x; // this nullifies x

return y; // safely returns allocated space!

}

Partial Typing Rules

|- v1 : owner * |- v2 : owner *

|- F v1 := v2

Transfer Assign Command |- v : owner * serf *

|- *v : serf *

Serf Pointer Dereference

|- e : int |-F c1 |-F c2

|-F if e then c1 else c2

Conditional Command

|- x : serf * |- e : owner *

|-F x = e

Copy Assign Command

|- x : owner * |- e : serf *

|- F x = e

Note: This rule does not exist! f ( x1 : 1, ... , xn : n ) xn+1 : n+1, ... , xm : m c ; rc F

= x1 : 1, ... , xm : m

|-F c |- rc : ´ serf * 1 i n . i i´ owner *

|-F f

Function Definition

Partial Operational Semantics

n(x) = 0 ( hr newaddr ) dom( H )

1, ... , n | H | x := new ; c 1, ... , n [ ( ohr newaddr ) / x ] | H { ( ( hr newaddr ), 0 ) } | c

Allocation Command

f ( x1, ... , xm ) xm+1, ... , xp cbody Fop

1 i m . eval( ei, n, H ) vi m+1 i p . vi = 0

1, ... , n | H | x = f ( e1, ... , em ) ; c 1, ... , n, Frame ( { (x1, v1)... , (xp, vp) }, c , x ) | H | cbody

Function Call Command

y dom(n) . y x n(y) (ohr z)

val = n(x)

1, ... , n-1, n | H | return x 1, ... , n-1[ val / n.var ] | H | n.cmd

Function Return Command

Values = (ohr ) (shr ) 0 or 4 or (ohr 37) or (shr 5)

VarValueMap = P(Loc Values) VVM = { (x, 5), (y, (shr 17)) , (z, (ohr 17))}

Frame = VarValueMap Command Loc n = Frame(VVM, c, x)

Heap = P ((hr ) Values) H = { ((hr 16), 2), ((hr 30), (ohr 17)) }

States = Frame list Heap Command S = 1, ... , n | H | c

Framework

Memory Safety Roadmap

Lemma 1:Single owner,

no cycles

No Memory LeaksNo DanglingReferences

Memory SafetyT heorem

Lemma 2:No serfs

pointing down

Lemma 3:No serfs on heap

Used forinduction

ImpliedDirectly

Used forinduction

Used for induction

By Induction on Typing Rules andOperational Sem antics

By TypeS oundness

Single Owner, No Cycles Lemma

• Lemma 1: For every allocated element, there is exactly one owner pointing to it from the heap or from the stack, and there exist no cycles.

( hr n) dom(H). |owners((hr n))| = 1 and (hr n) TC ((hr n))

• Initial State:

< Frame( {(x,0)}, return y, y ) | | x = main(); return x >

Since the heap is empty the lemma is vacuously true for the base case

Single Owner, No Cycles Lemma

x (ohr 5)(ohr 7)

0

5

7

beforeafter

v

TC(x)

objaddr

targetaddr

x 0(ohr 7)

(ohr 5)

5

7

v

TC(x)

objaddr

targetaddr

*v := x

y dom(n) n(y) = (ohr objaddr)

eval( v, n, H ) (ohr targetaddr) H((hr targetaddr)) = 0

(hr targetaddr) TC( H, (hr objaddr) )

1, ... , n | H | *v := y ; c 1, ... , n [ 0 / y ] | H [ (ohr objaddr) / (hr targetaddr) ] | c

Transfer Assign Command

No Memory Leaks

• Defn: A memory leak is allocated memory which is not reachable from the stack, i.e., is not in the transitive closure of anything on the stack.

– Theorem: Feudal C is safe with respect to memory leaks.

• Initial state:– The heap is empty when the program begins, so they is no allocated memory, and hence no

memory leaks.

No Dangling References

x

y

(ohr 5)

(shr 7)

(ohr 7) (ohr 13) 0

5 7 13

Not allowed

x

y

0

0

beforeafter

n(x) = (ohr addr)

y dom(n) . y x n(y) = (shr z) (hr z) TC(H, (hr addr))

1, ... , n | H | delete ( x ) ; c 1, ... , n [ 0 / x ] | del ( H, (ohr addr) ) | c

DeAllocation Command

Conclusion

• Feudal C is memory safe

• The type system is a good place to put memory allocation information!