Skip to content

Commit 76eb4ad

Browse files
Merge #40
40: Start fleshing out README r=ltratt a=jacob-hughes There is still much to be added and improved upon, but this is a start. Co-authored-by: Jake Hughes <jh@jakehughes.uk>
2 parents f9a310b + 1441d02 commit 76eb4ad

File tree

1 file changed

+97
-5
lines changed

1 file changed

+97
-5
lines changed

README.md

Lines changed: 97 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,110 @@
11
# libgc
22

3-
libgc is a garbage collector for Rust. It works by providing a garbage-collected
4-
`Gc<T>` smart pointer in the style of `Rc<T>`.
3+
[![Bors enabled](https://bors.tech/images/badge_small.svg)](https://bors.tech)
54

6-
# Structure
5+
_libgc_ is a garbage collection library for Rust. It can be used as a standalone
6+
library, but it is highly recommended that programs are compiled with the
7+
companion [rustc fork](https://github.com/softdevteam/rustgc), which offers
8+
language support for much better performance.
9+
10+
_libgc_ is in active development - there will be bugs!
11+
12+
## Example
13+
14+
_libgc_ provides a smart pointer, `Gc<T>`, which can be used to make garbage
15+
collected values. An example, with the necessary global allocator setup, looks
16+
as follows:
17+
18+
```rust
19+
use libgc::{Gc, GcAllocator};
20+
21+
#[global_allocator]
22+
static ALLOCATOR: GcAllocator = GcAllocator;
23+
24+
25+
fn foo() -> Gc<Vec<usize>> {
26+
let foo = Gc::new(vec![1,2,3]);
27+
let a = foo; // GC pointers are copyable
28+
let b = foo;
29+
30+
foo
31+
}
32+
33+
fn main() {
34+
let gc = foo();
35+
}
36+
```
37+
38+
## Overview
39+
40+
If you want to write code with shared ownership in Rust, `Rc` makes this
41+
possible. Unfortunately, managing cyclic data structures with reference counting
42+
is hard: weak pointers are needed to break strong cycles and thus prevent memory
43+
leaks. In programs where these sorts of structures are common,
44+
garbage collection is a natural fit.
45+
46+
_libgc_ is not a replacement to the single ownership model - it is intended to
47+
complement it by providing a garbage collected alternative for values which
48+
might be too difficult to manage with `Rc`. Values must opt-in to using
49+
garbage collection with the `Gc::new(x)` constructor. This tells _libgc_ to heap
50+
allocate `x`, and GC it for you when you're done with it. `Gc` can be thought of
51+
as a special `Box` type, where `x`'s lifetime is unknown at compile-time.
52+
Periodically, the garbage collector will interrupt the program (known as
53+
"stopping the world") to see which `Gc` values are still in use, and drop those
54+
which aren't.
55+
56+
Garbage collection involves scanning parts of the stack and heap to look for
57+
live references to `Gc` values. This means that _libgc_ must be aware of all heap
58+
allocated values, even those which aren't `Gc`. To do this, _libgc_ has its own
59+
allocator, `GcAllocator`, which must be set as the global allocator when using
60+
_libgc_.
61+
62+
```rust
63+
use libgc::GcAllocator;
64+
65+
#[global_allocator]
66+
static ALLOCATOR: GcAllocator = GcAllocator;
67+
```
68+
69+
### Finalization
70+
71+
A `Gc` can be used to manage values which have a `drop` method. Like all tracing
72+
garbage collectors, _libgc_ can not provide any guarantees about exactly when a
73+
'dead' value is dropped. Instead, once _libgc_ has determined that a value is
74+
unreachable, its `drop` method is added to a drop queue, which is ran on a
75+
parallel finalization thread at some point in the future. The order of
76+
finalization is intentionally undefined to allow _libgc_ to run `drop` methods on
77+
values which contain cycles of `Gc`.
78+
79+
:warning: You must not dereference a field of type `Gc<T>` inside `Drop::drop`.
80+
Doing so is unsound and can lead to dangling pointers. TODO: Add a lint for this
81+
and explain why in further details.
82+
83+
## Implementation
84+
85+
__libgc__ is implemented using the [Boehm-Demers-Weiser
86+
collector](https://github.com/https://github.com/ivmai/bdwgc). It is a
87+
conservative, stop-the-world, parallel, mark-sweep collector.
88+
89+
TODO: Expand
90+
91+
## Known Issues
92+
93+
* Single-threaded support only.
94+
* No Drop Lint to prevent unsound dereferencing of `Gc` typed fields.
95+
96+
## Using libgc with rustgc
797

898
There are two repositories which make up the gc infrastructure:
999

10100
* **libgc** the main library which provides the `Gc<T>` smart pointer and its
11101
API.
12102
* **rustgc** a fork of rustc with GC-aware optimisations. This can be used to
13-
compile user programs which use `libgc`, giving them better GC
103+
compile user programs which use libgc, giving them better GC
14104
performance. Use of rustgc is not mandated, but it enables further
15-
optimisations for programs which use `libgc`.
105+
optimisations for programs which use libgc.
16106

17107
This seperation between libgc and rustgc exists so that a stripped-down form of
18108
garbage collection can be used without compiler support.
109+
110+
TODO: Explain rustgc and it's optimizations.

0 commit comments

Comments
 (0)