Skip to content

Perf: shard allocation metadata by registered mutator #28

Description

@chrisbbreuer

Downstream: zig-utils/zig-js#97
Related: #15, #25, #26, #27

Evidence

On zig-js's shared-realm object_churn row, #26's test-and-test-and-set allocation lock reduced the exact eight-lane median from 1,319.888 ms to 1,164.047 ms (-11.8%). A post-change sample shows allocation wait is now deliberate handoff/yield; libc allocation and backing chunk growth are negligible.

The remaining serialized work under alloc_lock is global metadata publication: prepend every batch into Heap.all, initialize/index every header, update live/byte/nursery counters, and append born-concurrent cells. Increasing batch size (#25), tuning the lock (#26), and replacing the lock with one global pending-stack CAS plus an active-publisher gate (#27) have all been measured. #27 passed the full normal and TSan suite but regressed exact downstream 4/8-lane medians by 17.0%/12.6%, demonstrating that moving the convoy to one global CAS word is not sufficient.

Design direction

Add explicitly registered, stable per-mutator allocation metadata shards. A mutator should privately publish its allocated batches to its own chain/counters without touching a heap-wide write hotspot. Collection, finish/abort, and teardown may fold or walk registered shards only under an existing world-stopped/quiescent ownership boundary.

This is an ownership change, not another lock-spin experiment:

  • shard registration/unregistration must be serialized and cannot race allocation, collection, or heap teardown;
  • a thread exit must transfer or leave discoverable every published cell before its shard storage can disappear;
  • collectors must visit all shard chains exactly once and preserve the authoritative live-cell walk;
  • concurrent marking must preserve born-grey/born-concurrent behavior without tracing half-initialized payloads;
  • nursery prefix/accounting, payload classification, sweeping/unlinking, OOM recovery, and finalization order must remain exact;
  • bindings that do not opt in retain the current create/createBatch behavior.

Acceptance criteria

  • Add a generic opt-in shard API with documented lifetime and quiescence requirements; keep the existing unsharded API source-compatible.
  • Prove with multi-mutator tests that private publication does not acquire or CAS a heap-wide word per batch.
  • Preserve exact all-cell/live-byte/young-byte accounting across shard registration, thread exit, minor/full collection, abort, and heap teardown.
  • Preserve born-grey and born-concurrent safety under parallel marking; pass normal and suppression-free TSan transition tests.
  • Keep wild/stale/interior pointer classification and owned-slab header validation safe.
  • Pass the full zig-gc normal and TSan suites, then the focused zig-js semantic/GC/no-GIL gate.
  • On an order-balanced exact-parent zig-js object_churn A/B, do not regress 1/2 lanes and materially improve both 4 and 8 lanes; reject the implementation otherwise.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions