Skip to content

Instantly share code, notes, and snippets.

@izgzhen
Created December 3, 2015 04:49
Show Gist options
  • Save izgzhen/91067b4222e3958c15a5 to your computer and use it in GitHub Desktop.
Save izgzhen/91067b4222e3958c15a5 to your computer and use it in GitHub Desktop.
use self::GcCell::*;
use self::Action::*;
use std::marker;
#[derive(Clone)]
enum GcCell<T: Trace + ?Sized + Clone> {
Data(T),
Forward(*mut GcCell<T>),
}
#[derive(Clone)]
struct GcHandle<T: Trace + ?Sized + Clone> {
ptr: *mut GcCell<T>,
}
unsafe trait Trace {
unsafe fn trace(&mut self, Action);
}
// Example of implementation
#[derive(Clone)]
struct LinkedList<T: Trace + Clone> {
data: T,
next: Option<GcHandle<T>>,
}
unsafe impl<T: Trace + Clone> Trace for LinkedList<T> {
unsafe fn trace(&mut self, action: Action) {
self.data.trace(action.clone());
match self.next {
None => {},
Some(ref mut handle) => {
match action {
Evacuate => { evacuate(handle.ptr) },
Scavenge => {
scavenge(handle)
}
}
}
}
}
}
fn allocate<T>(cell: T) -> *mut T {
// allocate cell in a new place
unimplemented!()
}
unsafe fn evacuate<T: Trace + Clone>(cell_ptr: *mut GcCell<T>) {
let cell = &mut *cell_ptr;
let cell_old: GcCell<T> = cell.clone();
match cell {
&mut Data(ref mut t) => {
t.trace(Evacuate);
let new_ptr: *mut GcCell<T> = allocate(cell_old);
*cell_ptr = Forward(new_ptr);
},
&mut Forward(_) => panic!("Forward in evacuate"),
}
}
unsafe fn scavenge<T: Trace + Clone>(handle: *mut GcHandle<T>) {
let cell = &mut *(*handle).ptr;
match cell {
&mut Data(ref mut t) => {
t.trace(Scavenge);
},
&mut Forward(addr) => {
(*handle).ptr = addr;
}
}
}
#[derive(Clone)]
enum Action {
Evacuate,
Scavenge,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment