ReviewOS

zig-utils/zig-js

GC: keep embedded realm-root writes off managed-owner lookup

#597
Closed chris opened this 9 days ago ·
9 days ago

Parent: #479 Related: #476, #478

Evidence

A current-main production cold-lifecycle profile used the real bench-comparison-zig-js independent_cold boundary with the process-wide libc allocator and precise GC. In a five-second sample, Heap.headerForPayload was the dominant active leaf at 1,951 top-of-stack samples. The recurring stack is Environment.put / Environment.assign -> tolerant barrierThunk -> headerForPayload slow fallback.

The realm-root Environment is embedded in Context and explicitly has gc_managed = false, but its write barrier currently passes that unmanaged address as though it might be a managed owner. Each binding write first classifies the exact managed child and then misses the embedded owner in the slab/index before scanning live cells. The ownerless compatibility barrier already implements the required semantics: remember the exact young target for nursery collection and shade it during incremental marking.

Scope

  • Route only non-GC-managed Environment value stores through the existing ownerless barrier.
  • Keep exact managed Environment owners on writeBarrierFromManaged.
  • Add a focused witness that records null ownership for embedded roots and exact ownership for managed environments.
  • Measure exact-parent production cold lifecycle, allocation/GC attribution, and unchanged checksums.

Correctness constraints

  • Do not disable or defer any barrier.
  • Embedded realm roots must still retain young children and shade children stored after root tracing.
  • Managed environment old-to-young edges must retain exact-owner remembered-set behavior.
  • Preserve moving GC, concurrent marking, no-GIL, OOM, and teardown behavior.

Acceptance

  • Exact-parent cold-lifecycle medians improve with identical checksums.
  • Focused nursery/incremental-root tests and TSan pass.
  • Full units and relevant test262 scope have no regressions.
9 days ago

Landed in 8e211b2f.

The Context-embedded realm Environment now uses the existing ownerless barrier: young children are retained as remembered targets and incremental marking shades late children, without attempting to classify the external Context address as a GC payload. Managed Environment cells retain the exact owner-aware barrier.

Exact parent c544df8e evidence:

  • 21 alternating production independent_cold samples: median 27.878 ms -> 13.114 ms (-52.96%), checksum 1 unchanged.
  • Configuration slab ownership acquisitions: 13,770 -> 2,370 (-11,400), exactly 1,900 root writes times six size classes. Allocation, execution, shape, and GC-cell counters are identical.
  • Fixed five-second current-binary samples: Heap.headerForPayload falls from 1,951 to 17 top-of-stack samples and is no longer dominant.
  • test262: global-code 42/42, statements/let 145/145, statements/const 136/136 before and after.
  • Full units: 1,712 passed, 1 platform skip, 0 failed, 0 leaked.
  • Focused hook-ownership, late incremental-root publication, multi-age nursery, and TSan witnesses pass.

No barrier was disabled or deferred; the change selects the correct existing barrier contract for an external root.

9 days ago

Completed by 8e211b2f; exact-parent performance and collector-safety evidence are recorded above.

Sign in to comment on this issue.