kyren / gc-arena

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

`FinalizeQueue` to monitor for about-to-be-freed values. #85

Closed kyren closed 7 months ago

kyren commented 7 months ago

Works a bit like https://docs.oracle.com/javase/8/docs/api/java/lang/ref/ReferenceQueue.html.

I believe I have nailed down all of the edge and corner case behavior of the FinalizeQueue in this PR, but there is admittedly a lot, and it's not all covered by comments or documentation.

One thing not covered by the comments is what precisely happens when one FinalizeQueue is placed into another. If a later constructed FinalizeQueue is registered into an earlier one and otherwise lost, then the later queue will receive any about-to-be-freed objects, and then the earlier queue will also receive any duplicate registered objects (because the later queue is not yet black so none of its children are either). In the other case, where an earlier constructed FinalizeQueue is placed into a later one, then the later queue receives any soon-to-be-freed objects but the earlier one does not.

This seems inconsistent to me but any other behavior I can come up with is just as strange. In the later-in-earlier situation, if objects weren't placed into the earlier queue, then the earlier queue would miss freed objects if the later queue wasn't resurrected. In the earlier-in-later situation, if the earlier queue received objects and was resurrected then it would have received objects incorrectly.

This is the most consistent behavior I could come up with, and the algorithm that the collector is doing is simple.