ReviewOS

zig-utils/zig-js

GC: restore Promise cells to the 256-byte owned slab

#1026
Closed glennmichael123 opened this 9 days ago ·
9 days ago

Parent: #1024

Reproduction

Using zig-gc main at 0285ef8:

zig build test -Dtest-filter='Promise fits the 256-byte GC slab' -j1

fails deterministically on exact parent 022ceb1 and on the #1024 candidate:

expected 256, found 264

Current zig-gc defines cellAllocationBytes(T) as its 16-byte aligned header stride plus sizeof(T). Promise is 248 bytes, so its exact cell allocation is 264 bytes. GcCellBacking classifies that total into the next owned bucket: 512 bytes rather than the intended 256-byte class.

Scope

  • Recover at least eight payload bytes so Promise plus its collector header fits the 256-byte owned slab, while preserving tracing, relocation, rejection tracking, reaction publication, and thread safety; or explicitly rebaseline the 512-byte class with measured memory/throughput evidence.
  • Keep the allocation-class assertion. Do not fix this by deleting or weakening the test.
  • Verify the Promise, GC relocation, rejection-tracker, async, no-GIL, and TSan gates.

Evidence

  • exact parent and the #1024 candidate fail identically under the same real collector
  • the failure is independent of #1024's five changed source files
  • linked blocker discovered while completing #1024's real-collector full unit gate
9 days ago

Live reproduction correction before implementation: at zig-gc 0285ef8 the collector Header is 32 bytes, not 16. On current main the Promise payload is 232 bytes, so cellAllocationBytes(Promise) is 264 and selects the 512-byte owned class. The required payload bound is therefore 224 bytes. Packing the four lock-protected HostPromiseRejectionTracker flags into one byte reduces the payload to 224; the focused real-collector invariant now reports exactly 256 bytes. Behavioral, relocation, no-GIL, TSan, and conformance verification remains in progress.

9 days ago

Completed in c7827df and pushed directly to main. The four Promise rejection-tracker booleans now share one lock-protected byte. On zig-gc 0285ef8 this reduces the Promise payload from 232 to 224 bytes, cellAllocationBytes from 264 to exactly 256, and the owned allocation class from 512 to 256 bytes. The allocation-class test now pins the one-byte tracker state, the 224-byte payload ceiling, and exact 256-byte collector allocation. Verification: 33/33 Promise-focused tests pass with the real collector both normally and under unsuppressed ThreadSanitizer, including the two parallel_js Promise tests, requested moving compaction, relocation, rejection tracking, async jobs, reaction-list collection, and the slab invariant. Exact pre/post test262 output is byte-identical across test/built-ins/Promise (677/677), test/language/expressions (2759/2759), and test/language/statements/for-await-of (1234/1234): 4670 pass, 0 fail, 0 regressions.

Sign in to comment on this issue.