# Selfcompile KPI heap baseline — heap_ptr_bytes from scripts/selfcompile_kpi.sh
# (bump-allocator high-water of one stage2 compile of the default input,
# lib/@vibe/compiler/tests/codegen_lexer_test.vibe, with a cold isolated
# VIBE_BUILD_CACHE_DIR). Byte-deterministic for a fixed (stage2, input) pair,
# so CI (ci.yml "Selfcompile KPI heap gate") fails when the current commit's
# stage2 exceeds this baseline by more than 10%.
#
# The number changes whenever the compiler itself changes. Rebaseline when an
# intentional compiler change moves it (either direction — ratchet DOWN after
# an allocation win so the gate protects it):
#   bash scripts/generations.sh build --out-dir /tmp/kpi_gen
#   bash scripts/selfcompile_kpi.sh /tmp/kpi_gen/stage2.wasm
#   # -> copy the reported heap_ptr_bytes over the number below
# and commit the new number together with the compiler change, noting the
# old -> new value (and why) in the PR.
#
# Format: comments/blank lines ignored; first remaining line is the baseline.
#
# 2026-08-01 rebaseline (795735660 -> 872054760, +9.6%) on #1282: the
# borrowed-arg0 ABI is enabled by default, which turns on three
# whole-program analyses per compile (compute_borrow_arg0_user_fns,
# compute_may_return_view_fns, ca_collect_nonident_arg0) plus the md
# shadow prepass -- their working arrays are the growth. Intentional;
# the previous baseline left only 0.4% headroom, so any incidental
# drift would have tripped the +10% gate.
#
# 2026-07-20 rebaseline (643835180 -> 708517684) on #1015's PR: mostly
# PRE-EXISTING drift accumulated across several same-day #897 vpkg-migration
# merges (#1023, #1024, #1028) landed on main before this PR branched --
# measured main alone (no #1015 changes) at 708325604, already over the old
# baseline's +10% gate (708218698) by itself. #1015's own diff adds only
# ~192KB on top of that (708517684 - 708325604, ~0.03%) -- negligible, and
# only after fixing a real, separate inefficiency found during this same
# investigation: the linear to_string(Bool) call-site fast path
# (codegen/expr/compile_call.vibe) evaluated `fname ==
# namespace_exported_name(...)` (a StringBuilder-allocating call) FIRST in
# an `&&` chain checked on every compiled ECall node in the whole program,
# not just to_string calls -- reordering the cheap/non-allocating checks
# first (short-circuit) cut that specific regression from ~32MB down to
# the ~192KB above. Verified via scripts/selfcompile_kpi.sh on stage2 built
# from origin/main directly (708325604) vs. this PR's stage2 (708517684).
#
# 2026-07-22 rebaseline (708517684 -> 781237540) on the self-tail-call
# optimization PR: adding codegen/common_base/self_tail_call.vibe (a new
# whole-program pre-pass, called from both codegen backends, that rewrites
# self-tail-recursive functions into a loop) grows this input's compile-time
# heap high-water by ~72.7MB (~10.3%), most of which is compiled-code size
# (the new pass itself, wired into both the linear and gc backends) rather
# than per-compile allocation from the pass's own logic: reordering its
# eligibility checks so the cheap ones (scalar-only params, then a tail-
# position-only self-call scan) run before the two whole-body scans saved
# only ~2KB, and a follow-up attempt to shrink rewritten functions' AST size
# (skip the temp-let indirection for literal recursive-call arguments) made
# no measurable difference either -- both confirm the cost is dominated by
# the new pass's own code size, not this input's specific call pattern.
# Verified via scripts/selfcompile_kpi.sh on this PR's stage2 (781237540,
# stage2==stage3 fixpoint holds) vs. origin/main directly (708517684).
#
# 2026-07-24 rebaseline (781237540 -> 927734404) on the self-hosted `vibe
# lsp` PR (#1077): entirely PRE-EXISTING drift on main, not caused by this
# PR. A/B in the same environment using already-built stage2 artifacts:
# main at 8c0b46e (the commit this PR branched from, #1062's fix) measures
# 927651172 -- already far over the 781237540 baseline's +10% gate on its
# own, before any lsp_server.vibe/cli_adapter.vibe changes exist. This
# PR's own stage2 (6e79413, adds lsp_server.vibe + cli_adapter.vibe wiring)
# measures the SAME 927651172 locally (byte-identical) -- this KPI's input
# (codegen_lexer_test.vibe, an ordinary single-file FS compile) never
# reaches lsp_server.vibe's code, so the new file's compiled-but-dormant
# functions cost this benchmark nothing measurable. The value below
# (927734404) is CI's own measurement on this PR's commit, used verbatim
# so the gate's baseline matches the environment that enforces it; the
# ~0.009% delta from the local 927651172 is ordinary CI/local path-length
# noise (embedded absolute paths), well within the +10% band either way.
# The actual drift's origin (some merge to main between the self-tail-call
# baseline and #1062) was not bisected further -- out of scope for the LSP
# PR that surfaced it, same as the 2026-07-20 precedent above.
#
# 2026-07-25 rebaseline (927734404 -> 762961228), ratchet DOWN: #1101
# (contract-desugar + vpkg-prefix memoization, #1100 levers 1+2) cut the
# cold selfcompile high-water by 96.1MB (-11.2%). Per the policy above, the
# baseline drops to the new measured value so the gate PROTECTS the win --
# a future change that reallocates past 762961228 * 1.10 (~839MB) fails CI
# instead of silently eating the headroom the old 927M baseline would have
# left. Measured via scripts/selfcompile_kpi.sh on main@3b0df58's stage2
# (built from the committed flat module source; stage2==stage3 fixpoint
# edbc5ea70ab9).
#
# 2026-07-25 rebaseline (762961228 -> 749375452), ratchet DOWN again: the
# Perceus plan allocation cut (#1100, swap-captured branch snapshots +
# algebraically-identical max merge) shaves another 13.6MB off the cold
# selfcompile high-water. RC outputs verified byte-identical on a 9-file
# corpus (old vs new stage2), so the number moved WITHOUT any plan change.
# Measured via scripts/selfcompile_kpi.sh (fixpoint d72264e044cc).
#
# 2026-07-25 rebaseline (749375452 -> 777321892), +27.9MB (+3.7%): two
# stacked causes. (a) ~26.8MB is #1102 (ADR-0076 Phase 3 suspend: first-class
# resume + yield bubbling), already on main before this PR rebased onto it —
# measured 750481596 on the pre-#1102 base vs 777321892 after the rebase with
# no ADR-0077 code change in between. (b) ~1.1MB (+0.15%) is ADR-0077's
# release-strip: the executable write path rebuilds the output module once
# (drop name section + filter exports, strip_executable_wasm), copying ~1MB
# of output bytes through the bump allocator — the price of the size win
# (KPI input's own output: 5.7KB samples -> ~0.8KB, dist CLI -14.9%).
# Measured via scripts/selfcompile_kpi.sh (fixpoint 45996397af0d).
#
# 2026-07-25 rebaseline (777321892 -> 778237676), +0.9MB (+0.12%): #1107
# Phase 4 funcref-table minimization. Codegen now records every closure-
# materialized table slot into CompileCtx.table_slots_used (one append-only
# array per compile) and rebuilds the element section from that set as
# run-compressed segments — the recorder pushes plus the slot-flag/rebuild
# arrays account for the delta. In exchange the element section registers
# only live slots (dist CLI: 2751 entries/5,446B -> 117 entries/265B), which
# also shrinks the DCE root set downstream optimizers must respect.
# Measured via scripts/selfcompile_kpi.sh (fixpoint 3eff1320dd14). Final
# number below re-measured after the same PR's #1095 assert fix and vibec
# componentizer addition (fixpoint 51d4762d2bbb): 778249892 (+12KB).
#
# 2026-07-25 rebaseline (778249892 -> 795726964), +17.5MB (+2.2%) on rebasing
# this PR onto main@9c628bf: A/B in the same environment attributes +15.0MB
# to MAIN'S OWN drift — origin/main alone (no PR changes) measures 793258108,
# i.e. #1108 (ADR-0076 追記31/32 owned-captures + closure-CPS ABI, +1290
# lines in inline_direct_perform.vibe) / #1110 — and +2.5MB (+0.31%) to this
# PR's diff on the new base (strip + slot recorder + elem rebuild, same
# levers as the entries above; the closure-CPS pass compiles more lambdas,
# so the recorder sees proportionally more traffic). Measured via
# scripts/selfcompile_kpi.sh (fixpoint 68abf20153e6). Re-measured after
# #1109-2 (vibec vfs face: compile_file_request entry + componentizer):
# 795735660 (+8.7KB, the new entry's compiled-but-dormant code), fixpoint
# 4672171fa5c6.
#
# 2026-08-01 rebaseline (872054760 -> 962235184, +10.3%) on #1321 (hash-index
# perf PR): two stacked causes, decomposed against CI's own deterministic
# measurements. (a) +71.7MB (+8.2%) is MAIN'S OWN drift accumulated since the
# #1282 rebaseline above — origin/main@fc6faaa1 alone measures 943769464
# (perf-metrics baseline column on #1321), already leaving only 1.8% of the
# +10% band before this PR existed (same situation as the 2026-07-24 #1077
# precedent). (b) +16.0MB (+1.70% over main) is this PR's diff: the #1259
# scan-to-hash-index conversions (mrv_fresh epoch tables, AliasIdx,
# ExportRenamePlan.rename_idx, DCE def-index/reachable set) buy a -10..-16%
# selfcompile CPU/wall win at the cost of index-table allocation the bump
# heap never returns. A first version of the PR cost +20.9MB; it was shaved
# to +16.0MB by keeping mrv_fresh's `bound` as a shared truncate-reset array
# (the collect_free_vars pattern) and DCE's per-def ref dedup as a linear
# scan — per-insert HashMap Some-cell churn, not table capacity, was the
# driver. Outputs verified byte-identical old-vs-new stage2 on a 9-input
# corpus. Measured via scripts/selfcompile_kpi.sh (stage2==stage3 fixpoint
# holds). Final number re-measured after rebasing onto main@ab66c1ae
# (#1326 fn-keyword + #1327 ADR-0089 step 4 await wiring): 962235184
# (+2.5MB of main-side compiler growth on the same PR diff).
#
# 2026-08-03 rebaseline (960136936 -> 1075701656, +12.04%) on #1397:
# persistent TypeEnv v2 replaces the former value-binding-only codec with a
# strict transport for every current TypeEnv/Type/TypeExpr variant, including
# trait methods, generic bounds, concrete/generic impls, and cached indexes.
# The growth is compiled codec/validation code plus canonical EnvCached index
# rebuilding during persistent publication. The serializer was also changed
# from recursive suffix concatenation to one shared StringBuilder so actual
# large-environment publication remains linear-copy rather than O(N^2).
# Measured locally from a fresh stage2==stage3 generation with an isolated cold
# cache via scripts/selfcompile_kpi.sh.
#
# 2026-08-01 rebaseline (962235184 -> 960136936), ratchet DOWN: fix for a
# missed `Array::truncate(bound, 0)` in compute_may_return_view_fns' walk
# loop -- #1321's heap-shave commit hoisted `bound` to a shared array but
# the per-walk reset was silently dropped by a bad mechanical edit, so the
# array accumulated every binder of every function across every fixpoint
# round. The per-call-head linear scan over that ever-growing array made
# the selfcompile ~9x slower in wall time (52.7s vs 6.2s on this input)
# while heap barely moved, so the heap gate could not catch it; the
# analysis stayed correct (stale cross-function binders only push toward
# view, the safe direction -- outputs byte-identical on the 9-input corpus
# before vs after this fix). The -2.1MB is the removed array growth.
#
# 2026-08-07 rebaseline (1167101072 -> 1005293432), ratchet DOWN by 13.86%:
# the non-RC (bump) lane's `array_new` default capacity drops from 8 slots to
# 2 (codegen/builtin_bodies/bodies_core_a1a2.vibe). The bump allocator never
# frees, so a cap-8 array header costs 76 bytes (12 + 8 slots x 8) whether or
# not anything is pushed, and `array_empty()` -- 1,953 call sites in the
# compiler source -- lands there for every empty AST field. Measured on this
# KPI input with a cold isolated cache: cap 8 = 1,167,101,072, cap 4 =
# 1,051,249,096, cap 2 = 1,005,293,432. Wall on the same input moved 6,943ms
# -> 5,311ms at the median but only 5,291ms -> 5,106ms at the min, i.e. the
# win is the tail (fewer memory.grow / page faults on a 1.2GB heap), not raw
# speed. Verified: stage2 == stage3 fixpoint, 537/537 unit-test files,
# size_ratchet all samples within +2%. The RC lane keeps capacity 8 -- its
# free list reuses blocks by size class, so the same reasoning does not carry
# over unmeasured.
#
# NOTE ON THE PREVIOUS NUMBER: main measured 1,167,101,072 against the
# 1,075,701,656 baseline below, i.e. +8.50% with 1.5% of the +10% band left,
# BEFORE this change -- pre-existing drift accumulated since the 2026-08-03
# #1397 rebaseline, the same pattern as the 2026-07-20 / 07-24 / 08-01
# entries above. This ratchet is measured against that real 1,167,101,072,
# not against the stale committed number.
1005293432
