Found during the documentation-validation sweep (Aug 2026). This is the one item from that sweep that looks like a potential soundness problem rather than debt.
Verified facts
- GC state is thread-local:
codegen/src/runtime/gc.rs:38-57 (thread_local! HEAP_HEAD, GC_HEAP_LO, GC_HEAP_HI). Collection is per-thread (gc_collect_inner(), gc.rs:309) with no cross-thread rendezvous.
- Pointer validation checks the current thread's recorded heap range:
is_gc_payload at gc.rs:132 (addr >= lo && addr < hi against thread-local bounds).
- Green threads migrate between OS workers (work-stealing scheduler,
codegen/src/green/scheduler.rs, crossbeam deques + global injector), and channels hand raw object pointers between green threads (codegen/src/runtime/channel.rs).
- Safepoints exist (
aster_safepoint, codegen/src/runtime/error.rs:106; preemption at PREEMPT_THRESHOLD = 1024, scheduler.rs:29, checked at scheduler.rs:637) but are not used for any GC coordination.
- The old WALKTHROUGH.md claimed "stop-the-world GC across all workers coordinated via safepoints" and cited a test by name (
stop_the_world_gc_traces_stack_roots_from_multiple_suspended_tasks). That test does not exist anywhere in the repo (grep confirms), and no STW machinery was found. The design appears to have been planned but never built.
The question
If worker B holds the only live reference to an object allocated from worker A's heap — via channel hand-off, or because a green thread migrated after allocating — does worker A's collection free it out from under B? Relatedly, is_gc_payload's thread-local range check would seem to reject valid pointers into another thread's heap during tracing, causing under-tracing.
Asks
- A test that allocates on one worker, hands the object off via channel, forces collection on the allocating worker, and verifies the object survives and is still traced correctly.
- A design decision: cross-worker stop-the-world via the existing safepoint mechanism, per-object ownership transfer on hand-off, or a shared heap with synchronized collection.
Documentation
The per-thread heap design and precise tracing are documented in docs/src/content/docs/internals/codegen.mdx (GC section); the missing STW coordination is listed in docs/src/content/docs/reference/roadmap.mdx (Runtime).
Found during the documentation-validation sweep (Aug 2026). This is the one item from that sweep that looks like a potential soundness problem rather than debt.
Verified facts
codegen/src/runtime/gc.rs:38-57(thread_local!HEAP_HEAD,GC_HEAP_LO,GC_HEAP_HI). Collection is per-thread (gc_collect_inner(),gc.rs:309) with no cross-thread rendezvous.is_gc_payloadatgc.rs:132(addr >= lo && addr < hiagainst thread-local bounds).codegen/src/green/scheduler.rs, crossbeam deques + global injector), and channels hand raw object pointers between green threads (codegen/src/runtime/channel.rs).aster_safepoint,codegen/src/runtime/error.rs:106; preemption atPREEMPT_THRESHOLD = 1024,scheduler.rs:29, checked atscheduler.rs:637) but are not used for any GC coordination.stop_the_world_gc_traces_stack_roots_from_multiple_suspended_tasks). That test does not exist anywhere in the repo (grep confirms), and no STW machinery was found. The design appears to have been planned but never built.The question
If worker B holds the only live reference to an object allocated from worker A's heap — via channel hand-off, or because a green thread migrated after allocating — does worker A's collection free it out from under B? Relatedly,
is_gc_payload's thread-local range check would seem to reject valid pointers into another thread's heap during tracing, causing under-tracing.Asks
Documentation
The per-thread heap design and precise tracing are documented in
docs/src/content/docs/internals/codegen.mdx(GC section); the missing STW coordination is listed indocs/src/content/docs/reference/roadmap.mdx(Runtime).