20040112-SPACE04.ppt

Download Report

Transcript 20040112-SPACE04.ppt

Implementation and
Evaluation of a Safe
Runtime in Cyclone
Matthew Fluet
Cornell University
Daniel Wang
Princeton University
Introduction

Web-based applications
• Written in high-level, safe languages
• C#, Java, Perl, PHP, Python, Tcl
• Automatic memory management

Application servers
• Written in unsafe languages
• Host applications via interpreters (written in C)
Introduction


Long-term goal: a complete webapplication server written in a safe
language
Short-term goal: a complete interpreter
written in a safe language
• Implementing the core of an interpreter is not
•
in itself a significant challenge
Implementing the runtime system is a
challenge
Outline

A Scheme interpreter in Cyclone

Performance Evaluation
Conclusion

• Why Scheme
• Key Features of Cyclone
• Core Scheme Interpreter
• Garbage Collector
Why Scheme?

Ease of implementation
• Core interpreter loop is only ~500 lines
• Rely on an external Scheme front-end to expand
the full Scheme language into a core Scheme
subset
• Features desirable for web programming
Key Features of Cyclone

Safe, C-like language

Intended for systems programming

Region-based memory management
• Static type- and control-flow analysis
• Data representation
• Resource management
• Static, lexical, dynamic, heap, unique, …
Simple Copying Collector

From-space and To-space

Forwarding pointers
Simple Copying Collector

From-space and To-space

Forwarding pointers
• Natural correspondence with regions
• LIFO discipline of lexical regions insufficient
• Dynamic regions appear to be sufficient
Dynamic Regions

Non-nested lifetimes
Manual creation and deallocation
Represented by unique pointer (key)

Unique pointer ≡ Capability


• Access the region
Dynamic Regions

Operations
•
new: create a fresh dynamic region
•
open: open a dynamic region for allocation
•
free: deallocate a dynamic region
• Produces unique key
• Temporarily consumes key
• Permanently consumes key
GC and Dynamic Regions
. . .
// create the to-space’s key
let NewDynamicRegion {<`to> to_key} = new_ukey();
state_t<`to> = to_state;
// open the from-space’s key
{ region from_r = open_ukey(from_key);
// open the to-space’s key
{ region to_r = open_ukey(to_key);
// copy the state and reachable data
to_state = copy_state(to_r, from_state);
// free the from-space
free_ukey(from_key);
. . .
} }
GC and Dynamic Regions
. . .
// create the to-space’s key
let NewDynamicRegion {<`to> to_key} = new_ukey();
state_t<`to> = to_state;
// open the from-space’s key
{ region from_r = open_ukey(from_key);
// open the to-space’s key
{ region to_r = open_ukey(to_key);
// copy the state and reachable data
to_state = copy_state(to_r, from_state);
// free the from-space
free_ukey(from_key);
. . .
} }
GC and Dynamic Regions
. . .
// create the to-space’s key
let NewDynamicRegion {<`to> to_key} = new_ukey();
state_t<`to> = to_state;
// open the from-space’s key
{ region from_r = open_ukey(from_key);
// open the to-space’s key
{ region to_r = open_ukey(to_key);
// copy the state and reachable data
to_state = copy_state(to_r, from_state);
// free the from-space
free_ukey(from_key);
. . .
} }
GC and Dynamic Regions
. . .
// create the to-space’s key
let NewDynamicRegion {<`to> to_key} = new_ukey();
state_t<`to> = to_state;
// open the from-space’s key
{ region from_r = open_ukey(from_key);
// open the to-space’s key
{ region to_r = open_ukey(to_key);
// copy the state and reachable data
to_state = copy_state(to_r, from_state);
// free the from-space
free_ukey(from_key);
. . .
} }
GC and Dynamic Regions
. . .
// create the to-space’s key
let NewDynamicRegion {<`to> to_key} = new_ukey();
state_t<`to> = to_state;
// open the from-space’s key
{ region from_r = open_ukey(from_key);
// open the to-space’s key
{ region to_r = open_ukey(to_key);
// copy the state and reachable data
to_state = copy_state(to_r, from_state);
// free the from-space
free_ukey(from_key);
. . .
} }
Forwarding Pointers

What is the type of a forwarding pointer?
Forwarding Pointers

What is the type of a forwarding pointer?

A pointer to a Value in To-space
Forwarding Pointers

What is the type of a forwarding pointer?

A pointer to a Value in To-space, whose
forwarding pointer is a pointer to a Value in Tospace’s To-space
Forwarding Pointers

What is the type of a forwarding pointer?

A pointer to a Value in To-space, whose
forwarding pointer is a pointer to a Value in Tospace’s To-space, whose forwarding pointer is a pointer to a
Value in To-space’s To-space’s To-space, whose forwarding
pointer is a pointer to a Value in To-space’s To-space’s To-space’s Tospace, whose forwarding pointer is a pointer to a Value in To-space’s To-space’s Tospace’s To-space’s To-space, whose forwarding pointer is a pointer to a Value in To-space’s Tospace’s To-space’s To-space’s To-space’s To-space, whose forwarding pointer is a pointer to a Value in To-space’s
To-space’s To-space’s To-space’s To-space’s To-space’s To-space, whose forwarding pointer is a pointer to a Value in To-space’s Tospace’s To-space’s To-space’s To-space’s To-space’s To-space’s To-space, whose forwarding pointer is a pointer to a Value in To-space’s To-space’s To-space’s To-space’s Tospace’s To-space’s To-space’s To-space’s To-space, whose forwarding pointer is a pointer to a Value in To-space’s To-space’s To-space’s To-space’s To-space’s
space’s To-space’s To-space’s To-space, …
To-space’s To-space’s To-space’s To-space’s To-space,
whose forwarding pointer is a pointer to a Value in To-space’s To-space’s To-space’s To-space’s To-space’s To-space’s To-space’s To-
Dynamic Region Sequences

Introduce a new type constructor
mapping region names to region names
typedef _::R next_rgn<ρ::R>

Although the region names ρ and
next_rgn<ρ> are related, the lifetimes
of their corresponding regions are not
Dynamic Region Sequences

Operations
•
•
new, open, free: as for dynamic regions
next: create next_rgn<ρ> from ρ
Dynamic Region Sequences



Operations
•
next: create next_rgn<ρ> from ρ
Have an infinite supply of region names
•
next will create a fresh dynamic region key
Need a linear supply of keys
• Use Cyclone’s unique pointers
Dynamic Region Sequences



Operations
•
next: create next_rgn<ρ> from ρ
A dynamic region sequence is a pair
•
•
key: a dynamic region key
gen: a unique pointer
Unique pointer ≡ Capability
• Produce the next_rgn<ρ> key and gen
• Consumed by next
Dynamic Region Sequences

Operations
•
new: create a fresh dynamic region sequence
•
next: creates next dynamic region sequence
• Produces unique key and gen
• Produces unique key and gen
• Permanently consumes gen
GC and Dynamic Region Sequences
gcstate_t doGC(gcstate_t gcs) {
// unpack the gc state
let GCState{<`r> DRSeq {from_key, from_gen}, from_state} = gcs;
// generate the to-space
let DRSeq{to_key, to_gen} = next_drseq(from_gen);
state_t<next_rgn<`r>> to_state;
// open the from-space
{ region from_r = open_ukey(from_key);
// open the to-space
{ region to_r = open_ukey(to_key);
// copy the state and reachable data
to_state = copy_state(to_r, from_state); }
// pack the new gc state
gcs = GCState{DRSeq{to_key, to_gen}, to_state}; }
// free the from space
free_ukey(from_key);
return gcs;
}
GC and Dynamic Region Sequences
gcstate_t doGC(gcstate_t gcs) {
// unpack the gc state
let GCState{<`r> DRSeq {from_key, from_gen}, from_state} = gcs;
// generate the to-space
let DRSeq{to_key, to_gen} = next_drseq(from_gen);
state_t<next_rgn<`r>> to_state;
// open the from-space
{ region from_r = open_ukey(from_key);
// open the to-space
{ region to_r = open_ukey(to_key);
// copy the state and reachable data
to_state = copy_state(to_r, from_state); }
// pack the new gc state
gcs = GCState{DRSeq{to_key, to_gen}, to_state}; }
// free the from space
free_ukey(from_key);
return gcs;
}
GC and Dynamic Region Sequences
gcstate_t doGC(gcstate_t gcs) {
// unpack the gc state
let GCState{<`r> DRSeq {from_key, from_gen}, from_state} = gcs;
// generate the to-space
let DRSeq{to_key, to_gen} = next_drseq(from_gen);
state_t<next_rgn<`r>> to_state;
// open the from-space
{ region from_r = open_ukey(from_key);
// open the to-space
{ region to_r = open_ukey(to_key);
// copy the state and reachable data
to_state = copy_state(to_r, from_state); }
// pack the new gc state
gcs = GCState{DRSeq{to_key, to_gen}, to_state}; }
// free the from space
free_ukey(from_key);
return gcs;
}
GC and Dynamic Region Sequences
gcstate_t doGC(gcstate_t gcs) {
// unpack the gc state
let GCState{<`r> DRSeq {from_key, from_gen}, from_state} = gcs;
// generate the to-space
let DRSeq{to_key, to_gen} = next_drseq(from_gen);
state_t<next_rgn<`r>> to_state;
// open the from-space
{ region from_r = open_ukey(from_key);
// open the to-space
{ region to_r = open_ukey(to_key);
// copy the state and reachable data
to_state = copy_state(to_r, from_state); }
// pack the new gc state
gcs = GCState{DRSeq{to_key, to_gen}, to_state}; }
// free the from space
free_ukey(from_key);
return gcs;
}
GC and Dynamic Region Sequences
gcstate_t doGC(gcstate_t gcs) {
// unpack the gc state
let GCState{<`r> DRSeq {from_key, from_gen}, from_state} = gcs;
// generate the to-space
let DRSeq{to_key, to_gen} = next_drseq(from_gen);
state_t<next_rgn<`r>> to_state;
// open the from-space
{ region from_r = open_ukey(from_key);
// open the to-space
{ region to_r = open_ukey(to_key);
// copy the state and reachable data
to_state = copy_state(to_r, from_state); }
// pack the new gc state
gcs = GCState{DRSeq{to_key, to_gen}, to_state}; }
// free the from space
free_ukey(from_key);
return gcs;
}
GC and Dynamic Region Sequences

Comparison with type-preserving GCs
• Interpreter can be written in a trampoline
•
style, rather than continuation passing style
Intuitive typing of forwarding pointers
Performance Evaluation
Cyclone
(Safe GC)
Cyclone
(BDW GC)
SISC
(Sun JVM)
MzScheme
(BDW GC)
Interpreter
Runtime
Safe
Safe
Safe
Unsafe
Safe
Unsafe
Unsafe
Unsafe
Performance Evaluation
Normalized Execution Times
2
1.5
Cyclone (Safe GC)
Cyclone (BDW GC)
SISC
MzScheme
1
0.5
0
tak
deriv
puzzle
fft
traverse
Performance Evaluation
Maximum Working Set
5000
Cyclone (Safe GC)
Cyclone (BDW GC)
SISC
MzScheme
4000
3000
2000
1000
er
se
tr
av
fft
zz
le
pu
riv
de
k
0
ta
Virtual Pages
6000
Size of Unsafe Code
Interpreter
(lines of code)
Runtime System
(lines of code)
Cyclone
(Safe GC)
0
1800
Cyclone
(BDW GC)
0
9000
SISC
(Sun JVM)
0
229,100
MzScheme
(BDW GC)
31,000
9000
Conclusion



Significantly reduce amount of unsafe
code needed to implement an interpreter
May incur a performance penalty for
extra degree of safety
Future Work
• Reduce performance penalty
• Per thread regions providing customization