Argh. This is not the message I meant to send. I got a bit too clever
with my mail client. Anyway, here is a somewhat more full response.

This is a very good point that you raise. We have to be aware of the
impact of our decisions on garbage collection; for whatever reason, it
seems to be one of those language features that is completely
non-orthogonal to everything else.

The problem you raise is not specific to `Cell` (which I think will go
away, unless it becomes the replacement for `@mut`). It seems to me
that we cannot safely handle write barriers for any type that has
internal mutation. For example, `RcMut`.

Basically, to handle write barriers, we need to maintain the invariant
that all mutable slots which contain a managed ponter are ultimately
owned by the stack or by some other managed pointer. This implies that
one cannot have an `RcMut` that contains an `@T` pointer, though an
`Rc` is ok.

Interestingly, as we have discussed before, even something like
`Rc<@T>` introduces another challenge: the `@T` becomes a root. When
walking the set of roots, then, the garbage collector must be able to
traverse arbitrary user-defined smart pointers. This is solvable by
having a trait that dereferences the smart pointer; we need such a
trait anyway, if the smart pointer is to play nicely with autoderef,
but there will be a bit of cleverness required to write everything up
nicely.

All of this leads me to wonder if smart pointers that contain managed
data is just a bad combination. Suppose we have a trait Unmanaged, then
we can define the smart pointer trait as something like:

    trait SmartPointer<T:Unmanaged> {
        fn deref<'a>(&'a self) -> &'a T;
    }

and thus ensure that smart pointers are never used to store managed
data, or at least make it harder. This avoids the need for the GC to
traverse smart pointers at all and means that (if we stick with
`@mut`, rather `Cell`) we can still handle write barriers.

On the other hand, I also wonder if we shouldn't just accept that
Rust's GC will be somewhat handicapped and cannot fully support
incremental nor genreational techniques. We can still use generational
techniques for immutable data. Given that GC is task-local, and that
it is optional, this is perhaps acceptable.

On the other other hand, I have to read and digest the thesis that
Graydon sent. At least based on the summary, it does seem that the
"mostly copying" technique addresses the issue. The thesis seems to
use the MMU for write guards.


Niko

On Wed, Jul 10, 2013 at 04:07:51PM -0400, Niko Matsakis wrote:
> Still chewing on this. Two questions below and one preliminary thought
> below.
> 
> On Wed, Jul 10, 2013 at 11:32:08AM -0700, Patrick Walton wrote:
> > This does mean that we need to make sure that all contents of `@mut`
> > are Freeze; otherwise, we won't trip the barrier.
> 
> This seems stricter than necessary. You don't want unsafe mutation a
> la Cell, but `@mut` should be ok.
> 
> > For generational GC, we must ensure that objects in the nursery
> > pointed to by the tenured generation are either added to a remembered
> > set or tenured. This is harder in Rust because we have to know both
> > the generation of the referrer and the referent simultaneously. I
> > believe that conservatively tenuring all objects that are mutated
> > would be overconservative and defeat much of the purpose of GGC.
> 
> I don't get this. My understanding of how GGC works is that whenever a
> tenured object is mutated, you flag it into a set. Then when you scan
> the nursery, you scan only this set to uncover new roots. This
> requires a write barrier. As you explained above, write barriers are
> fairly straightforward with `@mut`, but quite challenging if you
> replace `@mut` with Cell.
> 
> Preliminary thought:
> 
> I think we should either replace `@mut` with `Cell` or remove
> `Cell`. Near as I can tell, `Cell` today exists primarily to
> work-around limitations that all have better solutions in the works.
> 
> Moving from `@mut` to `Cell` is a more flexible and orthogonal system,
> in that you can define the granularity of the write barriers and you
> have have `Gc<Cell<T>>` and `Rc<Cell<T>>` rather than each kind of
> opinter requiring a `Foo` and `FooMut` variant, all of which repeat
> basically the same logic.
> 
> However, moving from `@mut` to `Cell` does seem to rule out write
> barriers, and hence will limit the ability to write maximally
> efficient garbage collectors. This may be ok, but it's definitely the
> kind of decision you want to make with your eyes open, so I'm glad you
> pointed this out!
> 
> 
> 
> 
> Niko
> 
> _______________________________________________
> Rust-dev mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/rust-dev
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to