You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
codegen: reconcile the root-spill threshold (#8623, 32M) with the RS4GC instruction budget (#8586, 1.57M) — budget-gap functions get refused instead of spilled #8679
Since a function's added instructions ≈ its relocation estimate, a function whose estimate lands in (1.57M, 32M) does not spill (estimate < 32M) yet overruns the budget (post-rewrite > 1.57M) → the budget assertion hard-refuses the whole module.
Concrete case
Compiling the Claude Code cli.js 2.1.112 bundle, __AnonShape_ec12be8bd7b0a2b9_constructor (a large closed-shape object-literal constructor) grew 34,009 → 2,280,128 instructions under RS4GC — above the 1.57M budget, below the 32M spill threshold — and was refused. It only compiled with PERRY_ROOT_SPILL_RELOCATIONS=1500000. (Estimate accuracy for this shape is fixed by #8678, which counts property/index stores; but even with an accurate ~2.25M estimate it still won't spill at the 32M default.)
Problem
Two #8583 mechanisms disagree on where a function is "too big for RS4GC":
DEFAULT_ROOT_SPILL_RELOCATIONS), measured at the point RS4GC's rewrite still finishes in bounded time.PERRY_LL_RS4GC_MAX_INSTRS), the point the-Os/-O3optimizer goes super-linear.Since a function's added instructions ≈ its relocation estimate, a function whose estimate lands in (1.57M, 32M) does not spill (estimate < 32M) yet overruns the budget (post-rewrite > 1.57M) → the budget assertion hard-refuses the whole module.
Concrete case
Compiling the Claude Code cli.js 2.1.112 bundle,
__AnonShape_ec12be8bd7b0a2b9_constructor(a large closed-shape object-literal constructor) grew 34,009 → 2,280,128 instructions under RS4GC — above the 1.57M budget, below the 32M spill threshold — and was refused. It only compiled withPERRY_ROOT_SPILL_RELOCATIONS=1500000. (Estimate accuracy for this shape is fixed by #8678, which counts property/index stores; but even with an accurate ~2.25M estimate it still won't spill at the 32M default.)Options
DEFAULT_ROOT_SPILL_RELOCATIONSat/belowPERRY_LL_RS4GC_MAX_INSTRSso anything that would overrun the budget spills first. (Note this revisits perf(codegen): raise root-spill default to the measured RS4GC fan-out cliff (#8620) #8623/codegen: #8589 root-spill default threshold (4M) too low — spills moderate-fan-out functions and slows their compile #8620: the "8M fans-out-fine" cases codegen: #8589 root-spill default threshold (4M) too low — spills moderate-fan-out functions and slows their compile #8620 measured would also overrun the 1.57M budget, so they should spill — RS4GC finishing ≠ the optimizer handling the result.)request_shadow_frame_spill()(roots to the shadow frame, RS4GC skips it) instead of refusing the module. This is the "fix: make compile output TypeScript-developer friendly #8421/fix(codegen): unbreak in-process RS4GC on inline asm and relocation-grown functions #8128 root-lowering choice, never refuse" principle applied to the budget, and it needs no threshold tuning at all.Option 2 is the durable fix. Found while getting the cli.js bundle to a working native binary (#8583).