Robust behavior when finalizers resurrect GC data (fixes #124) #184
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This is implemented through using a persistent bit that is set when a node's finalizer is run, and by running sweep() only on finalized nodes. During a GC cycle, the first mark() is used only to determine which nodes to finalize. The second mark() determines which nodes to reclaim.
Since the GC already did two mark phases, I thought it appropriate to keep a second mark phase for this implementation. It may be possible to defer reclamation until another GC cycle entirely, but that would require an equivalent to
needs_drop
for finalization to be efficient for empty finalizers, which appears to be non-trivial (or even impossible) without language support.I also added a test that resurrects a GC in a finalizer and passes miri with these changes. I'm not aware of an easy way to produce a segfault in this scenario.