Two uses of the construction-only facts outside the collector
(backend/immutability.ts):
- Publication guards: a store into the constructor's own `this` that lies
before the constructor's escape point, in a constructor no ancestor of
which lets `this` escape and that is never invoked directly on an
existing object, cannot target a published object. It loses its
rc == SIZE_MAX guard and no longer seeds may-throw, so constructors that
could only throw through guards lose their pending checks at every `new`.
Storing `this` into one of its own fields does not expose it.
- Borrowed reads: `x.f` holding an object, record, array or string is
borrowed as a call argument, receiver or stable alias when `f` is
construction-only and `x` is itself borrowable (unchanged local,
borrowed parameter, or such a projection): nothing can replace and
release it while `x` lives. Not inside constructors, which may still
write their own fields. Module constants (immutable, not TDZ-checked,
assigned at most once) are borrowable too.
No object is frozen or marked at run time; publication errors, store order
and reflection are unchanged.
tsc-ts (e469e33), static: published-field guards 6,528 -> 4,462,
sc_release calls 146,056 -> 129,756, sc_retain calls 26,215 -> 22,123,
scr_arr_release 29,865 -> 25,617, binary 23.68 -> 22.96 MB (both commits).
Self-check single-threaded, executed: guards 96.1M -> 60.8M, retains
273.5M -> 247.2M, releases 340.3M -> 314.0M.
Linux sandbox, interleaved medians, both commits against
perf/alloc-hugepages:
single-threaded (6 runs) base new change
Excalidraw 8.62 s 8.34 s -3.2%
Playwright 7.83 s 7.71 s -1.5%
tsc-ts self-check 4.36 s 4.22 s -3.0%
tRPC 1.63 s 1.58 s -3.1%
TypeORM 6.68 s 6.50 s -2.5%
--checkers 8 (10 runs): -2.3% .. +0.7% (neutral)
Runtime suite (--layouts=4 --runs=16): geomean -1.9%; ast-interp -4.4%,
validate-errors -3.8%, regex-logs -1.7% faster, template-render +1.4%
slower, the rest neutral; sizes unchanged.