An open API service indexing awesome lists of open source software.

https://github.com/fitzgen/safe-gc

A garbage collection library for Rust with zero unsafe code
https://github.com/fitzgen/safe-gc

Last synced: about 1 year ago
JSON representation

A garbage collection library for Rust with zero unsafe code

Awesome Lists containing this project

README

          


safe-gc


A garbage collection library for Rust without any unsafe code



build status
Documentation Status


## About

`safe-gc` implements a garbage collection library for Rust with zero `unsafe`
code and zero dependencies. It even has a `forbid(unsafe_code)` directive at the
top!

Additional features:

* Allows constructing and collecting arbitrary heap graphs, including cycles. It
doesn't impose any ownership hierarchy, or anything like that, to the shapes
of references between GC-managed objects within the heap.

* Leverages Rust's ownership and borrowing in its API: if you have an `&mut
Heap`, you can get mutable access to objects in the heap. It doesn't, for
example, force everything in the heap into `RefCell`s, or only give out shared
references to GC-managed objects, or similar.

* Allows constructing multiple, separate GC heaps that can be independently
collected.

* Allows allocating any number of heterogeneous types within the heap. For
example, you can allocate both `Cons` and `Tree` objects within the
heap. Heaps are *not* constrained to only a single, uniform `T` type of GC
objects.

* Footgun-free GC object finalization with Rust's regular, old `Drop` trait. No
worries about accidentally deref'ing pointers to GC objects the collector has
already reclaimed or resurrecting objects it was about to reclaim.

`safe-gc` is not, however, a particularly high-performance garbage collector.

## Usage

* Define types managed by the GC.

* Define references from within one GC type to another GC type with `Gc`.

* Implement `Trace` for your GC-managed types.

* Create one or more `Heap`s.

* Allocate objects in your `Heap`s.

* Hold onto GC roots with `Root`.

* Let the garbage collector reclaim unreachable objects!

## Example

```rust
use safe_gc::{Collector, Gc, Heap, Trace};

// Define a GC-managed tree of `T` values.
struct Tree {
value: Gc,

// A cyclic parent pointer.
parent: Option>>,

// Left and right subtrees.
left: Option>>,
right: Option>>,
}

// Report each of the GC references within a `Tree` to the
// collector.
//
// See the `Trace` docs for more details.
impl Trace for Tree {
fn trace(&self, collector: &mut Collector) {
collector.edge(self.value);
if let Some(parent) = self.parent {
collector.edge(parent);
}
if let Some(left) = self.left {
collector.edge(left);
}
if let Some(right) = self.right {
collector.edge(right);
}
}
}

// Another GC type!
struct Cat {
cuteness: u32,
cat_tree: Option>>,
}

impl Trace for Cat {
fn trace(&self, collector: &mut Collector) {
if let Some(tree) = self.cat_tree {
collector.edge(tree);
}
}
}

// Create a new GC heap!
let mut heap = Heap::new();

// Allocate some objects in the heap!
let momo = heap.alloc(Cat {
cuteness: u32::MAX,
cat_tree: None,
});
let tree = heap.alloc(Tree {
value: momo.unrooted(),
parent: None,
left: None,
right: None,
});

// Create a bunch of garbage! Who cares!
for _ in 0..100 {
let _ = heap.alloc(Tree {
value: momo.unrooted(),
parent: None,
left: None,
right: None,
});
}

// Read data from objects in the heap!
let cuteness = heap[&momo].cuteness;
assert_eq!(cuteness, u32::MAX);

// Mutate objects in the heap!
heap[&momo].cat_tree = Some(tree.into());

// Garbage collections will happen automatically, as necessary, but you can also
// force a collection, if you want!
heap.gc();
```

## Why?

`safe-gc` is certainly a point in the design space of garbage-collection
libraries in Rust. One could even argue it is an interesting -- and maybe even
useful? -- point in the design space!

Also, it was fun!

At the very least, you don't have to wonder about the correctness of any
`unsafe` code in here, because there isn't any. As long as the Rust language and
its standard library are sound, this crate is too.