ReviewOS

zig-utils/zig-js

Runtime strings: batch sustained managed cell allocation

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

Parent: #473

Measured problem

After #1009, the frozen representative_json invocation still allocates 407,017 GC cells one at a time. Attribution shows these are the remaining managed string cells produced by JSON.stringify output and parsed string values; the object/array cells already use bounded batches.

Executed ReleaseFast/real-GC prototype against pushed #1009:

  • total invocation cells remain exactly 1,001,001;
  • slab-lock acquisitions fall 3,114,143 -> 2,330,774 (-25.2%);
  • single-allocation acquisitions fall 407,017 -> 6,633;
  • publication acquisitions fall 444,141 -> 68,781;
  • bounded batch acquisitions rise 37,124 -> 62,148.

The implementation is not JSON-specific. The active interpreter keeps a realm-matched, traced, relocatable reserve of valid empty StringCells. Allocations 1-16 remain exact single-cell allocations; sustained allocation 17 fills a bounded 16-cell batch. Unused cells remain valid managed empty strings until consumed, so collection and finalization are defined at every safepoint.

Three alternating exact-parent pairs, exact checksums and thermal state 0 throughout:

  • representative_json: 0.996430x instructions, 0.990986x CPU, 0.990697x wall;
  • variant: 0.999569x instructions, 1.000181x CPU, 1.000019x wall;
  • reviver-source: 0.989830x instructions, 0.919519x CPU, 0.911213x wall;
  • escaped strings: 0.998421x instructions, 0.991289x CPU, 0.991579x wall;
  • depth-4096 stringify control: 0.997193x instructions;
  • shallow-4096 stringify control: 0.999059x instructions.

Scope

  • Reuse Heap.createBatch(StringCell, .string, ...) only after sustained active-interpreter demand.
  • Keep arena/static strings and allocations without a matching active interpreter on the existing exact path.
  • Keep reserves realm-local even when sibling Contexts share one heap, preserving byte allocator/finalizer ownership.
  • Trace and relocate the unused suffix as ordinary interpreter roots.
  • Preserve immutable bytes/hash/aux initialization, OOM ordering, moving-GC safety, and no-GIL isolation.

Acceptance

  • Seven alternating exact-parent pairs retain gains with exact checksums and neutral JSON controls.
  • First-16/17th-allocation policy is pinned under real GC and TSan.
  • Reserve tracing and relocation are pinned and pass under real GC.
  • JSON test262 remains 165/165 with 165/165 required-VM agreement.
  • String-related test262 subtrees and focused StringCell/GC/OOM tests pass.
  • Shared/no-GIL managed-string TSan witnesses pass.
  • Commit lands directly on main with evidence linked here and in #473.
9 days ago

Landed directly on main as 934d306.

Final evidence

Seven alternating exact-parent ReleaseFast/real-GC pairs against pushed #1009, exact checksums and thermal state 0 -> 0 in all 112 invocations:

rowcandidate / parent instructionsCPUwallinstruction RSD parent/candidate
representative_json0.998566x0.999650x0.999694x0.390% / 0.523%
representative_json_variant0.996904x1.007694x1.008486x0.451% / 0.549%
representative_json_reviver_source1.004376x0.977480x0.977014x0.597% / 0.708%
escaped strings0.997534x0.996597x0.995770x0.100% / 0.095%
depth-4096 stringify control1.000083x1.004228x1.004495x0.041% / 0.234%
shallow-4096 stringify control0.999495x1.006490x1.007125x0.018% / 0.017%
cold plain-4096 output control0.999322x0.595745x0.575405x3.561% / 0.425%
cold Unicode-4096 output control0.999863x1.033210x1.028029x1.546% / 0.151%

The two frozen parse rows and escaped-string row retain lower deterministic work; reviver wall/CPU improve while its instruction delta remains within measured variance. Cold and structural controls are instruction-neutral.

Exact landed-source attribution on representative_json:

  • total cells: 1,001,001 -> 1,001,001;
  • slab-lock acquisitions: 3,114,143 -> 2,330,774 (-25.2%);
  • single-allocation acquisitions: 407,017 -> 6,633;
  • publication acquisitions: 444,141 -> 68,781;
  • bounded batch acquisitions: 37,124 -> 62,148.

Gates

  • First 16 allocations stay single; allocation 17 creates exactly one 16-cell batch and retains 15 valid rooted cells.
  • Threshold policy passes under Debug and TSan.
  • Reserve trace/relocation test passes under real GC.
  • Runtime StringCell finalization, moving UTF-16 index, and heap-limit OOM tests pass.
  • Shared no-GIL JSON.stringify witness passes under TSan.
  • JSON/OOM/GC units 34/34.
  • JSON test262 165/165 and required-VM agreement 165/165.
  • String-related test262: String 1,223/1,223; StringIteratorPrototype 7/7; language string types 24/24; string literals 73/73.
  • 50,000-level JSON probe passes in tree and VM modes.
  • Guarded build/test peaks remained 1.99-2.14 GB, below the 3 GB cap.
  • GitHub author/committer are glennmichael123 <gtorregosa@gmail.com> with no trailers.

Sign in to comment on this issue.