1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#![feature(extern_types, arbitrary_self_types)]
mod alloc;
mod gc_ptr;
mod list;
mod root;
mod state;
mod trace;
use std::pin::Pin;
use once_cell::sync::Lazy;
use crate::state::GcState;
pub use crate::gc_ptr::GcPtr;
pub use crate::root::Root;
pub use crate::trace::{NullTrace, Trace};
static GC: Lazy<GcState> = Lazy::new(|| GcState::default());
pub fn alloc_unmanaged<T: Trace>(data: T) -> GcPtr<T> {
GcPtr::new(data)
}
pub fn alloc<T: Trace>(data: T) -> GcPtr<T> {
let gc_ptr = alloc_unmanaged(data);
unsafe {
manage(gc_ptr);
}
gc_ptr
}
pub unsafe fn manage<T: Trace + ?Sized>(ptr: GcPtr<T>) {
with_gc(|gc| gc.manage(ptr))
}
pub fn count_managed_objects() -> usize {
with_gc(|gc| gc.objects().into_iter().count())
}
pub fn count_roots() -> usize {
with_gc(|gc| gc.count_roots())
}
fn set_root<T: Trace + ?Sized>(idx: usize, ptr: GcPtr<T>) {
with_gc(|gc| gc.set_root(idx, ptr))
}
fn pop_root(idx: usize) {
with_gc(|gc| gc.pop_root(idx))
}
fn with_gc<T, F: FnOnce(Pin<&GcState>) -> T>(f: F) -> T {
let gc: Pin<&GcState> = unsafe { Pin::new_unchecked(&GC) };
f(gc)
}
pub fn collect() {
with_gc(|gc| gc.collect())
}