pub mod gc;
pub mod trace;
pub mod heap;
mod heap_entry;
#[cfg(test)]
mod tests {
use crate::gc::Gc;
use super::*;
#[derive(Debug)]
struct Node {
next: Option<Gc<Node>>,
}
impl Node {
fn new(next: Option<Gc<Node>>) -> Self {
Self { next }
}
}
unsafe impl trace::Trace for Node {
fn mark_children(&self) {
if let Some(next) = &self.next {
Gc::mark_children(next);
}
}
}
#[test]
fn test_basic_list() {
let mut heap = heap::Heap::default();
let reachable = heap.manage(Node::new(None));
let root = heap.manage(Node::new(Some(reachable)));
let _unreachable = heap.manage(Node::new(None));
assert!(heap.add_root(root));
assert_eq!(heap.object_count(), 3);
assert_eq!(heap.collect(), 1);
assert_eq!(heap.object_count(), 2);
assert!(heap.remove_root(root));
assert_eq!(heap.collect(), 2);
}
#[test]
fn test_unmanaged_root() {
let mut heap = heap::Heap::default();
let managed = heap.manage(Node::new(None));
let unmanaged = Box::pin(Node::new(Some(managed)));
unsafe { assert!(heap.add_unmanaged_root(unmanaged.as_ref())); }
assert_eq!(heap.object_count(), 1);
assert_eq!(heap.collect(), 0);
assert!(heap.remove_unmanaged_root(unmanaged.as_ref()));
assert_eq!(heap.collect(), 1);
assert_eq!(heap.object_count(), 0);
}
}