Perf: per-function-scope candidacy in ArrayLocalPromotionAnalyzer#871
Merged
Conversation
The typed-array-local promotion (#857/#860) keyed candidacy/disqualification whole-program per lexeme: a clean push/index/length array was poisoned by an unrelated, escaping array of the SAME NAME elsewhere (a different function, or a different module in a bundle). Common array names (`arr`, `data`, `items`, `result`) therefore frequently failed to promote in real multi-module programs — the optimization only landed when the name happened to be globally unique. Key candidacy by (function scope, lexeme) instead: each Stmt.Function / Expr.ArrowFunction body is its own scope (module top level is scope 0), mirroring StringAccumulatorPromotionAnalyzer. Cross-scope references are captures, already handled by the IsVariableCaptured guard. Use-site emission is slot-type-keyed and thus inherently scope-correct, so promoting more arrays is safe. Effect (verified by IL): a clean `const xs = []` (push/index/length) now promotes to List<double> even when another function has an escaping `const xs` — previously both stayed boxed/$Array. No behavior change where names were already unique. This is the prerequisite step (1) for the array-methods typed-HOF-pipeline work (docs/plans/issue-861-array-methods-typed-pipeline.md): common array names must promote before HOF receivers can stay typed. Green on dotnet test (24 ArrayLocalPromotionTests incl. a new per-scope name-collision case, both modes) except the pre-existing stale/flaky Test262 baselines (drift is Array.isArray/proxy, present in interpreter mode too → unrelated to this compile-only change).
This was referenced Jun 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #856 (perf epic). Prerequisite for the array-methods typed-HOF-pipeline work.
Problem
The typed-array-local promotion (#857/#860) keyed candidacy whole-program per lexeme. A clean
push/[i]/.lengtharray was poisoned by an unrelated, escaping array of the same name elsewhere — another function, or another module in a bundle. So common array names (arr,data,items,result) routinely failed to promote in real multi-module programs; the optimization only landed when the name happened to be globally unique. (This is the same latent bug fixed for strings in #870 — surfaced there becausestringWork'sscollided withperf_hooks'sconst s.)Fix
Key candidacy/disqualification by (function scope, lexeme): each
Stmt.Function/Expr.ArrowFunctionbody is its own scope (module top level is scope 0), mirroringStringAccumulatorPromotionAnalyzer. Cross-scope references are captures, already handled by theIsVariableCapturedguard. Use-site emission is slot-type-keyed (so it's inherently scope-correct), which makes promoting more arrays safe.Effect (IL-verified)
A clean
const xs = [](push/index/length) now promotes toList<double>even when another function has an escapingconst xs— previously both stayed boxed/$Array. No change where names were already unique (e.g. count-primes'isPrime).Tests / validation
ArrayLocalPromotionTests: +1 per-scope name-collision case; 24/24 green (both modes), no regression in the existing cases.dotnet test: 13968 passed, 0 real regressions (the only failures are 2 tests that pass in isolation under parallel load, plus the documented stale Test262 baselines — drift isArray.isArray/proxy, present in interpreter mode too, i.e. unrelated to this compile-only change).--verifypasses on the promoted output.Context
Step 1 of
docs/plans/issue-861-array-methods-typed-pipeline.md(the last remaining benchmark gap, array-methods @ 2.79× Node). Common array names must promote before HOF receivers can be kept typed.