kyren / gc-arena

Incremental garbage collection from safe Rust
Creative Commons Zero v1.0 Universal
436 stars 36 forks source link

Gc, Lock, RefLock, GcLock, GcRefLock, what's the difference? #97

Closed glyh closed 2 months ago

glyh commented 2 months ago

I didn't find a proper place to ask this question. Sorry if it bothers.

kyren commented 2 months ago

GcLock<_> and GcRefLock<_> are aliases for Gc<Lock<_>> and Gc<RefLock<_>> that exist mostly for historical reasons, so I'm going to skip explaining those directly. I'm just going to explain Gc, Lock, and RefLock, which is what you need to understand.

Gc is easy to understand, it is THE pointer type for gc-arena, all garbage collected pointers are Gc. There is only the one pointer type now, but the situation used to be different, there used to be separate pointers for internally mutable data before we were able to separate Lock and RefLock from the pointer type (which is why we have the type aliases mentioned above). Nowadays there is only the one pointer type (and its Weak sibling technically, but I'm trying to keep things simple). Gc is like Rc or Arc, but it's garbage collected rather than being reference counted, so we call it Gc.

Lock and RefLock are things that you store inside data held by a Gc pointer. It's not essential to understand the details here, but the way the garbage collection system works, we must ensure that certain things happen whenever any garbage collected value is mutated (the jargon for this in descriptions of garbage collection systems is a "write barrier"). Lock and RefLock are special types which provide mutability and ensure that "write barriers" happen. Lock is our version of Cell, and RefLock is our version of RefCell. You usually can't store a Cell or a RefCell inside a Gc without unsafe code because we don't provide trait impls for Cell<_> and RefCell<_> that let you get into any trouble, so you have to use Lock and RefLock instead, and the methods we provide for interior mutability ensure that write barriers are invoked. (Technically, you can store Cell<_> and RefCell<_> inside a Gc only if their held types are 'static, since we can prove they hold no Gc pointers, but this is not important to understand what Lock and RefLock are.)

Hope this helps!

glyh commented 2 months ago

Thank you!