Found by the regex performance lane (#11543).
The regex slow path reports its per-call scratch buffers to the GC as external allocations. For patterns needing more than 32 match registers (for example dotenv's line regex, which has 42), that phantom external pressure keeps hot loops in frequent full collections.
Measured: letting the per-thread match scratch grow beyond 32 registers gives dotenv/parse −31% and moment/parse_format −16% instructions. But peak RSS rises +27.6% / +13.4%, because once the phantom pressure is gone the young generation grows to its cap before collecting. So it was not shipped, under the "minimize RSS AND keep best compute" rule.
We want both wins. Directions:
- Stop counting short-lived, immediately-freed scratch as external GC pressure, or count it as transient so it doesn't drive full collections.
- Separately, look at the young-generation pacing that lets RSS climb to the cap when allocation pressure is low. An RSS-aware nursery cap or earlier minor GC would keep RSS flat with the faster regex path.
Measurements are on branch wip/perf-regex-matcher and in #11543's description.
Found by the regex performance lane (#11543).
The regex slow path reports its per-call scratch buffers to the GC as external allocations. For patterns needing more than 32 match registers (for example dotenv's line regex, which has 42), that phantom external pressure keeps hot loops in frequent full collections.
Measured: letting the per-thread match scratch grow beyond 32 registers gives dotenv/parse −31% and moment/parse_format −16% instructions. But peak RSS rises +27.6% / +13.4%, because once the phantom pressure is gone the young generation grows to its cap before collecting. So it was not shipped, under the "minimize RSS AND keep best compute" rule.
We want both wins. Directions:
Measurements are on branch
wip/perf-regex-matcherand in #11543's description.