4 ms·
To expand on GPs point, I believe it implies that implementing a GC type for the Rust itself within its constraints (and even LLVM is not perfect, if we skip to
by neonsunset 2y ago
To expand on GPs point, I believe it implies that implementing a GC type for the Rust itself within its constraints (and even LLVM is not perfect, if we skip to LLVM-IR) is bound to be worse than in a language with bespoke precise+tracing+moving garbage collector which always requires deep compiler integration for "VM" to have exact information of where gcrefs are located at every safepoint (including registers!), be able to collect objects as soon as they are no longer referenced and not when they go out of scope later, determine whether write (or, worse, read) barriers are required or can be omitted and have the ability to suspend the execution to update the object references upon moving them to a different generation/heap/etc.
All GC implementations in Rust that I've seen so far relied on much more heavy handed techniques like having GC<T> to be a double indirection, pushing references to threadlocal queue, have GC pointers to be fat to pass around metadata inline, etc. They have been closer to modified RC with corresponding cost.
- binary132 2y agoI read it as something like “GC plus safety checks is costlier than just GC”
- adrian17 2y ago> All GC implementations in Rust that I've seen so far relied on much more heavy handed techniques like having GC<T> to be a double indirection, pushing references to threadlocal queue, have GC pointers to be fat to pass around metadata inline, etc. They have been closer to modified RC with corresponding cost. For reference, the gc-arena crate discussed in the blog post has no double indirection and no fat pointers (except for DSTs). Passing and reading the references is free, while assigning references to GC objects requires a write barrier, like in C#. The library is single-threaded, so there's no thread local state (and no global state). But you're right that since the library is not _that_ invasive or integrated with the language runtime / allocators, you don't get things like cheap allocations, barrier omitting or generations. And most notably, without stack scanning you can't do collection while in a GC-aware scope - in particular, you can't automatically run GC if you run out of memory during an allocation. Piccolo (Lua VM) solves this by being stackless and repeatedly jumping out of the GC scope, while Ruffle (Flash/AS2/AS3 VM) bites the bullet and only runs collection between frames and hopes that it'll never hit OOM within a single frame.