Title: Implementation and Evaluation of a Safe Runtime in Cyclone
1Implementation and Evaluation of a Safe Runtime
in Cyclone
Matthew Fluet Cornell University
Daniel Wang Princeton University
2Introduction
- 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)
3Introduction
- Long-term goal a complete web-application 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
4Outline
- A Scheme interpreter in Cyclone
- Why Scheme
- Key Features of Cyclone
- Core Scheme Interpreter
- Garbage Collector
- Performance Evaluation
- Conclusion
5Why 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
6Key Features of Cyclone
- Safe, C-like language
- Static type- and control-flow analysis
- Intended for systems programming
- Data representation
- Resource management
- Region-based memory management
- Static, lexical, dynamic, heap, unique,
7Simple Copying Collector
- From-space and To-space
- Forwarding pointers
8Simple Copying Collector
- From-space and To-space
- Natural correspondence with regions
- LIFO discipline of lexical regions insufficient
- Dynamic regions appear to be sufficient
- Forwarding pointers
9Dynamic Regions
- Non-nested lifetimes
- Manual creation and deallocation
- Represented by unique pointer (key)
- Unique pointer Capability
- Access the region
10Dynamic Regions
- Operations
- new create a fresh dynamic region
- Produces unique key
- open open a dynamic region for allocation
- Temporarily consumes key
- free deallocate a dynamic region
- Permanently consumes key
11GC and Dynamic Regions
- . . .
- // create the to-spaces key
- let NewDynamicRegion lttogt to_key new_ukey()
- state_tlttogt to_state
- // open the from-spaces key
- region from_r open_ukey(from_key)
- // open the to-spaces 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)
- . . .
12GC and Dynamic Regions
- . . .
- // create the to-spaces key
- let NewDynamicRegion lttogt to_key new_ukey()
- state_tlttogt to_state
- // open the from-spaces key
- region from_r open_ukey(from_key)
- // open the to-spaces 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)
- . . .
13GC and Dynamic Regions
- . . .
- // create the to-spaces key
- let NewDynamicRegion lttogt to_key new_ukey()
- state_tlttogt to_state
- // open the from-spaces key
- region from_r open_ukey(from_key)
- // open the to-spaces 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)
- . . .
14GC and Dynamic Regions
- . . .
- // create the to-spaces key
- let NewDynamicRegion lttogt to_key new_ukey()
- state_tlttogt to_state
- // open the from-spaces key
- region from_r open_ukey(from_key)
- // open the to-spaces 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)
- . . .
15GC and Dynamic Regions
- . . .
- // create the to-spaces key
- let NewDynamicRegion lttogt to_key new_ukey()
- state_tlttogt to_state
- // open the from-spaces key
- region from_r open_ukey(from_key)
- // open the to-spaces 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)
- . . .
16Forwarding Pointers
- What is the type of a forwarding pointer?
17Forwarding Pointers
- What is the type of a forwarding pointer?
- A pointer to a Value in To-space
18Forwarding 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
To-spaces To-space
19Forwarding 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
To-spaces To-space, whose forwarding pointer is
a pointer to a Value in To-spaces To-spaces
To-space, whose forwarding pointer is a pointer
to a Value in To-spaces To-spaces To-spaces
To-space, whose forwarding pointer is a pointer
to a Value in To-spaces To-spaces To-spaces
To-spaces To-space, whose forwarding pointer is
a pointer to a Value in To-spaces To-spaces
To-spaces To-spaces To-spaces To-space, whose
forwarding pointer is a pointer to a Value in
To-spaces To-spaces To-spaces To-spaces
To-spaces To-spaces To-space, whose forwarding
pointer is a pointer to a Value in To-spaces
To-spaces To-spaces To-spaces To-spaces
To-spaces To-spaces To-space, whose forwarding
pointer is a pointer to a Value in To-spaces
To-spaces To-spaces To-spaces To-spaces
To-spaces To-spaces To-spaces To-space, whose
forwarding pointer is a pointer to a Value in
To-spaces To-spaces To-spaces To-spaces
To-spaces To-spaces To-spaces To-spaces
To-spaces To-space, whose forwarding pointer is
a pointer to a Value in To-spaces To-spaces
To-spaces To-spaces To-spaces To-spaces
To-spaces To-spaces To-spaces To-spaces
To-space,
20Dynamic Region Sequences
- Introduce a new type constructor mapping region
names to region names - typedef _R next_rgnlt?Rgt
- Although the region names ? and next_rgnlt?gt are
related, the lifetimes of their corresponding
regions are not
21Dynamic Region Sequences
- Operations
- new, open, free as for dynamic regions
- next create next_rgnlt?gt from ?
22Dynamic Region Sequences
- Operations
- next create next_rgnlt?gt from ?
- Have an infinite supply of region names
- next will create a fresh dynamic region key
- Need a linear supply of keys
- Use Cyclones unique pointers
23Dynamic Region Sequences
- Operations
- next create next_rgnlt?gt from ?
- A dynamic region sequence is a pair
- key a dynamic region key
- gen a unique pointer
- Unique pointer Capability
- Produce the next_rgnlt?gt key and gen
- Consumed by next
24Dynamic Region Sequences
- Operations
- new create a fresh dynamic region sequence
- Produces unique key and gen
- next creates next dynamic region sequence
- Produces unique key and gen
- Permanently consumes gen
25GC and Dynamic Region Sequences
- gcstate_t doGC(gcstate_t gcs)
- // unpack the gc state
- let GCStateltrgt DRSeq from_key, from_gen,
from_state gcs - // generate the to-space
- let DRSeqto_key, to_gen next_drseq(from_gen)
- state_tltnext_rgnltrgtgt 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 GCStateDRSeqto_key, to_gen,
to_state - // free the from space
- free_ukey(from_key)
- return gcs
26GC and Dynamic Region Sequences
- gcstate_t doGC(gcstate_t gcs)
- // unpack the gc state
- let GCStateltrgt DRSeq from_key, from_gen,
from_state gcs - // generate the to-space
- let DRSeqto_key, to_gen next_drseq(from_gen)
- state_tltnext_rgnltrgtgt 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 GCStateDRSeqto_key, to_gen,
to_state - // free the from space
- free_ukey(from_key)
- return gcs
27GC and Dynamic Region Sequences
- gcstate_t doGC(gcstate_t gcs)
- // unpack the gc state
- let GCStateltrgt DRSeq from_key, from_gen,
from_state gcs - // generate the to-space
- let DRSeqto_key, to_gen next_drseq(from_gen)
- state_tltnext_rgnltrgtgt 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 GCStateDRSeqto_key, to_gen,
to_state - // free the from space
- free_ukey(from_key)
- return gcs
28GC and Dynamic Region Sequences
- gcstate_t doGC(gcstate_t gcs)
- // unpack the gc state
- let GCStateltrgt DRSeq from_key, from_gen,
from_state gcs - // generate the to-space
- let DRSeqto_key, to_gen next_drseq(from_gen)
- state_tltnext_rgnltrgtgt 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 GCStateDRSeqto_key, to_gen,
to_state - // free the from space
- free_ukey(from_key)
- return gcs
29GC and Dynamic Region Sequences
- gcstate_t doGC(gcstate_t gcs)
- // unpack the gc state
- let GCStateltrgt DRSeq from_key, from_gen,
from_state gcs - // generate the to-space
- let DRSeqto_key, to_gen next_drseq(from_gen)
- state_tltnext_rgnltrgtgt 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 GCStateDRSeqto_key, to_gen,
to_state - // free the from space
- free_ukey(from_key)
- return gcs
30GC 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
31Performance Evaluation
Interpreter Runtime
Cyclone (Safe GC) Safe Safe
Cyclone (BDW GC) Safe Unsafe
SISC (Sun JVM) Safe Unsafe
MzScheme (BDW GC) Unsafe Unsafe
32Performance Evaluation
33Performance Evaluation
34Size 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
35Conclusion
- 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