bsr 0.11.0

Tracing garbage collector for Amsel
Documentation
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);
    }
}