
Designing a garbage collector in Rust - Manishearth
http://manishearth.github.io/blog/2015/09/01/designing-a-gc-in-rust/
======
tinco
This article is a great read! The article makes it seem as though once you had
a valid theoretical model implementation was actually easy, is that true? It
sounds so simple it might even be implemented in tens of lines of Rust, or is
there a lot of hidden complexity you skipped over in the article?

In your paragraph about rooting you mention how language support might enable
a better implementation (using llvms rooting), but the approach you took
sounds very solid. What is the disadvantage of the way you do it now?

Edit: just scrolled through the implementation, it really is as short as the
article made it seem, just a couple hundred lines! Now I'm really curious to
its performance compared for example with that of Java or Go.

~~~
Manishearth
> This article is a great read!

Thanks! Glad you enjoyed it!

> The article makes it seem as though once you had a valid theoretical model
> implementation was actually easy, is that true?

Rust's affine type system is a huge win here. It has a no-surprises approach
to handling data, so it's very easy to practically track roots and all.

So yeah; the implementation is not much more complex than the design above (I
don't think I skip any nontrivial part of the design in the post, though that
is purely by accident -- I intended to give a sketch of the design and the
whole design just happened to come out)

> What is the disadvantage of the way you do it now?

Think of manual rooting as akin to Rc or shared_ptr wrt cost; and the llvm
thing is Box/unique_ptr.

Just how the compiler inserts deterministic alloc/free calls with Box, the
compiler keeps track of stack based gcthings in llvm. All of the dynamic
checks above for rooting become unnecessary; instead at mark time you just
pick up the roots from the stack frames. (Note: I haven't looked into the llvm
feature; I don't know if it works this way).

Tracking roots is something a compiler is good at. Not so much a runtime.

Regarding Java and Go: I don't know; I haven't tried. But the applications are
different -- Java is pervasive, and Go is pervasive with value types and
escape analysis (also default concurrent). Rust-gc will probably be horrible
at pervasive GCing. Besides, the other two have compiler support so have it
much easier when they want to track roots. You can statically insert
unconditional calls to `roots.push(var)` if you own the compiler, but as a
library author you can have to keep track of many things at runtime to
determine if something is a root (which is why llvms solution looks promising
to me). In rust-gcs case, rooting status is stored by all the other existing
gcptrs, and the status is changed conditionally depending on their states and
interaction.

------
plgeek
You may find these two article interesting prior art, which I happen to be
very familiar with. :)

Implementation and performance evaluation of a safe runtime system in Cyclone
[http://scholar.google.com/citations?view_op=view_citation&hl...](http://scholar.google.com/citations?view_op=view_citation&hl=en&user=rlxeD9sAAAAJ&citation_for_view=rlxeD9sAAAAJ:IjCSPb-
OGe4C)

Type-preserving garbage collectors
[http://scholar.google.com/citations?view_op=view_citation&hl...](http://scholar.google.com/citations?view_op=view_citation&hl=en&user=rlxeD9sAAAAJ&citation_for_view=rlxeD9sAAAAJ:d1gkVwhDpl0C)

~~~
Manishearth
Thanks, these look quite interesting! I'll read them when I get time.

~~~
peterfirefly
See also chapter 7 of Morrisett's thesis:

[http://www.cs.cmu.edu/~rwh/theses/morrisett.pdf](http://www.cs.cmu.edu/~rwh/theses/morrisett.pdf)

------
vvanders
I'm not sure how I feel about GC in Rust.

One of the useful things with Rust's ownership model is it forces good
architectures. I feel like with a GC it's much easier to be "lazy" about who
owns something which seems very counter to what I've found interesting and
useful in Rust.

~~~
spicyj
> Cases where one needs to maintain a complicated, dynamic graph are where a
> GC becomes useful. Similarly, if one is writing an interpreter for a GCd
> language, having a GC in Rust would simplify things a lot. > > Not to say
> that one should pervasively use a GC in Rust. Similar to Rc<T>, it’s best to
> use regular ownership-based memory management as much as possible, and
> sprinkle Rc/Gc in places where your code needs it.

Hopefully people heed this advice. My guess is it will not be a problem
because most example code (and all of the docs) will not use Gc pervasively.

~~~
kibwen
Not only will the example code and docs never use Gc, there won't even be a Gc
implementation in the stdlib. There are just too many potential variants of Gc
(along with too little concrete demand) to ship any implementation by default.

