ReviewOS

zig-utils/zig-js

Perf: add a dense GC slab class for ordinary objects

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

Parent: #62 Related: #53, #76

Problem

Object is currently 624 bytes and its zig-gc allocation is 672 bytes including the collector header. GcCellBacking has only 512- and 1024-byte classes around that size, so the dominant ordinary-object cell wastes 352 bytes (34.4%) and object churn moves/recycles 1024 bytes of slab capacity for each 672-byte allocation. The post-#76 profile remains dominated by allocation, nursery sweeping/freeing, object initialization, and memory movement.

Scope

  • Add a 768-byte aligned cell-slab class between 512 and 1024 bytes.
  • Use the existing large chunk geometry for the 768/1024/2048 classes so object-heavy contexts retain low chunk/index overhead.
  • Generalize fixed-size bucket initializers rather than hand-maintaining seven literals.
  • Update direct allocator tests and bucket-profile documentation.
  • Preserve exact ownership, free-list reuse, trimming, bulk teardown, heap-budget accounting, and parallel bucket locking.
  • Compare against fb6f8d8 in alternating fresh processes with exact checksums; revert if neutral.

Acceptance

  • Object cells select the 768-byte class and the empty-context bucket profile proves it.
  • Focused GC-cell-backing and object-churn GC tests pass.
  • Candidate wins a majority of pinned pairs with a meaningful median reduction.
  • Full unit/harness validation runs once only after a measured win.
  • Commit references this issue and is pushed to main as Chris without coauthors.
9 days ago

Rejected after controlled A/B against fb6f8d88; no code retained.

The 768-byte slab did reduce ordinary Object cell capacity from 1024 to 768 bytes, and the GC profile confirmed the expected mapping (slot=768, 3 chunks, 1536 capacity, 1047 issued). The focused backing suite also passed 18/18 with zero leaks.

However, seven alternating process pairs of single object_churn 100 3 were consistently slower:

  • pair wins: 0/7
  • all-sample median: 239.180459 -> 262.946750 ms (+9.94% time)
  • median of process medians: 239.180459 -> 262.655416 ms (+9.81% time)
  • checksums: exact for all 42 samples

The extra class therefore costs more in the hot allocator/ownership paths than its reduced internal fragmentation saves for this workload. The working tree has been fully reverted. Future work under #62 should target fewer allocation/sweep operations or a materially smaller Object, not an additional linear-search bucket.

Sign in to comment on this issue.