Skip to content

Phase 3 (#4) increment 1: precise transitive reachability (mark-phase core)#10

Open
usiegj00 wants to merge 1 commit into
masterfrom
phase3-precise-mark
Open

Phase 3 (#4) increment 1: precise transitive reachability (mark-phase core)#10
usiegj00 wants to merge 1 commit into
masterfrom
phase3-precise-mark

Conversation

@usiegj00

@usiegj00 usiegj00 commented Jun 5, 2026

Copy link
Copy Markdown

First increment of Phase 3 (#4, precise GC). Rather than land a full Immix collector at once (allocator + blocks/lines + sweep + fiber stacks — a multi-increment effort), this delivers the core of a precise GC's mark phase, built on the RTTI from #8/#9.

What

  • Crystal::RTTI.reachable_from(root) : Set(UInt64) — a precise transitive walk of the object graph from root via the RTTI reference layout, returning every reachable Crystal object's address. This is precise marking from a root; it also immediately serves retainer/leak analysis ("what's reachable from X?") on the default Boehm GC — the diagnosis the epic was built for.
  • Refactored each_outgoing_reference to delegate to a pointer-based core (each_outgoing_reference_at(base_ptr, type_id)), since a transitive walk holds raw Void* and can't cast to the abstract Reference.
  • reachable_from follows a yielded pointer only when its header is a valid type id (raw Array buffers / non-object pointers are leaves; Array elements are still reached via the buffer scan).

Verification

  • spec/compiler/codegen/rtti_spec.cr (red→green): transitive closure over a graph (excludes a node reachable only from the stack); reaching references through Array elements. 13 examples, 0 failures.
  • Format + ameba clean; rtti.cr parses under Crystal 1.0.0 (forward-compat checked proactively).

Scope

Behind -Drtti. The full Immix allocator / sweep / fiber-stack root scanning are subsequent increments on top of this proven precise-mark foundation. Fork-only; builds on merged #9.

… core)

Add `Crystal::RTTI.reachable_from(root) : Set(UInt64)` — a precise transitive
walk of the object graph from a root via the RTTI reference layout, returning
every reachable Crystal object's address. This is the core operation of a
precise GC's mark phase (the foundation for `-Dgc=immix`), and immediately a
retainer/leak-analysis tool ("what is reachable from X?") on the default Boehm
GC — directly serving the leak-diagnosis use case behind the epic.

- Refactor `each_outgoing_reference` to delegate to a pointer-based core
  (`each_outgoing_reference_at(base_ptr, type_id)`), since a transitive walk
  holds raw `Void*` pointers and cannot cast to the abstract `Reference`.
- `reachable_from` does an iterative DFS, following a yielded pointer only when
  its header is a valid type id (so raw Array buffers / non-object pointers are
  leaves; Array *elements* are still reached via the buffer scan).
- Specs (red→green): transitive closure over an object graph (excludes a node
  reachable only from the stack), and reaching references through Array elements.

Verified: rtti_spec 13/0; format + ameba clean; rtti.cr parses under Crystal
1.0.0 (forward-compat). Behind `-Drtti`; the full Immix allocator/sweep are
subsequent increments on this proven precise-mark foundation.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant