Problem
Empty child arrays reserve 16 element slots even though roughly 75% of document nodes are leaves and keep an empty array; the remaining nodes hold four children. This is repeated tens of millions of times in the cyclic workload.
Measured 2026-10-01 on macOS arm64, Perry main d40ed1a47019bcae547819ebb5756bcd96ba1057 (v0.5.1655), with matching compiler and runtime archives. This snapshot already includes #11645. These are diagnostic probes; no compiler/runtime fix was applied and the original comparison remains unchanged.
crates/perry-runtime/src/array/header_gc_slots.rs defines MIN_ARRAY_CAPACITY = 16; general allocation paths in array/alloc.rs apply capacity.max(MIN_ARRAY_CAPACITY). This is distinct from #11659's allocation-size ceiling/hole-tail/read-guard work and from historical allocation-speed issue #63.
Measured capacity waste
A separate diagnostic source adds six explicit full-GC census points, classifying tracked allocations at mark completion before sweep. With the revision cache populated:
- Approximately 5.16 MiB of reachable tracked heap data, including 10,920 DocNodes.
- Arrays account for approximately 1.50 MiB.
- 174,740 capacity slots versus 10,924 used slots; approximately 1.25 MiB of live-array storage is unused element capacity.
The diagnostic census changes GC scheduling and adds observer buffers; its RSS is not substituted for baseline RSS. No changed array allocator was benchmarked, so the capacity saving is an opportunity, not a measured CPU/RSS improvement.
Direction and acceptance
Explore zero/small initial element backing for empty/small arrays with normal growth. Preserve distinct mutable identities (do not share a mutable empty array), hole semantics, subclass/named-property handling, growth forwarding, and GC roots/barriers.
Re-run the cyclic workload linked below with unchanged source and checked output/parent/closure identities. Report live array bytes, capacity versus used slots, CPU and peak RSS; also measure growing-array workloads to detect reallocation regressions. Validate growth past initial capacity and retained parent-to-young-child edges under moving-GC stress.
Complete unchanged workload and method: #11743.
Evidence in the project-comparison workspace: demo/results/stress/perry-profile/summary.md, profile-manifest.json, cpu-summary.json, experiment-summary.json, experiments.json, gc-diagnostics.stderr, nursery-4-gc-diagnostics.stderr, census.jsonl, vmmap-*.txt, and the original/typed-receiver makeTree disassemblies. These paths are local artifacts, not publicly hosted links.
Problem
Empty child arrays reserve 16 element slots even though roughly 75% of document nodes are leaves and keep an empty array; the remaining nodes hold four children. This is repeated tens of millions of times in the cyclic workload.
Measured 2026-10-01 on macOS arm64, Perry main
d40ed1a47019bcae547819ebb5756bcd96ba1057(v0.5.1655), with matching compiler and runtime archives. This snapshot already includes #11645. These are diagnostic probes; no compiler/runtime fix was applied and the original comparison remains unchanged.crates/perry-runtime/src/array/header_gc_slots.rsdefinesMIN_ARRAY_CAPACITY = 16; general allocation paths inarray/alloc.rsapplycapacity.max(MIN_ARRAY_CAPACITY). This is distinct from #11659's allocation-size ceiling/hole-tail/read-guard work and from historical allocation-speed issue #63.Measured capacity waste
A separate diagnostic source adds six explicit full-GC census points, classifying tracked allocations at mark completion before sweep. With the revision cache populated:
The diagnostic census changes GC scheduling and adds observer buffers; its RSS is not substituted for baseline RSS. No changed array allocator was benchmarked, so the capacity saving is an opportunity, not a measured CPU/RSS improvement.
Direction and acceptance
Explore zero/small initial element backing for empty/small arrays with normal growth. Preserve distinct mutable identities (do not share a mutable empty array), hole semantics, subclass/named-property handling, growth forwarding, and GC roots/barriers.
Re-run the cyclic workload linked below with unchanged source and checked output/parent/closure identities. Report live array bytes, capacity versus used slots, CPU and peak RSS; also measure growing-array workloads to detect reallocation regressions. Validate growth past initial capacity and retained parent-to-young-child edges under moving-GC stress.
Complete unchanged workload and method: #11743.
Evidence in the project-comparison workspace:
demo/results/stress/perry-profile/summary.md,profile-manifest.json,cpu-summary.json,experiment-summary.json,experiments.json,gc-diagnostics.stderr,nursery-4-gc-diagnostics.stderr,census.jsonl,vmmap-*.txt, and the original/typed-receivermakeTreedisassemblies. These paths are local artifacts, not publicly hosted links.