Created
December 3, 2015 04:49
-
-
Save izgzhen/91067b4222e3958c15a5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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