Expand description
Request-scope arena-eligibility analysis (#463 slice 1).
Per-allocation-site classification: is this MakeRecord /
MakeTuple value safe to route through the active per-request
arena (EffectHandler::enter_request_scope), instead of the
global allocator?
§Relationship to escape::analyze_function (#464)
Same lattice, same worklist, same step rules — with one bit of
policy flipped: Op::Return is not an escape op here, because
the returned value goes to the caller’s stack and the caller is
in the same request scope as us. Everything else (Call,
CallClosure, TailCall, EffectCall, MakeClosure captures,
aggregate-as-field, worker-pool ops, Dup, …) stays a hatch under
the slice-1 intra-procedural conservative policy. The shared
machinery is escape::analyze_function_with_policy(_, Policy::RequestScope); this module wraps it and inverts the
per-site escapes bool into arena_eligible.
§Slice scope
Analysis only. No opcode lowering, no runtime behavior change, no
bytecode-format change. Slice 2 (AllocArenaRecord /
AllocArenaList / handle variants on Value) consults
build_arena_index at codegen time.
§Soundness contract
Inherits #464’s contract verbatim (docs/design/escape-analysis.md
§ “Soundness contract”):
- Over-approximation (
arena_eligible = falsewhen the value actually stays in-scope) costs a heap allocation — the status-quo baseline. Acceptable. - Under-approximation (
arena_eligible = truewhen the value actually escapes the request) would let an arena handle outlive its slab and is UB. Slice 2 must pair this analysis with an unconditional runtime fallback (same shape as #464’sAllocStackRecordheap fallback), so a missed hatch costs correctness only if the analysis is wrong and the fallback is omitted — never both.
§Out of scope for slice 1
- Inter-procedural escape (the scoping doc defers this until
inlining lands with #465 phase 1; any
Callis a hatch here). - Worker-handler lifetime split (
spawn_for_workerclone-handlers get a fresh empty arena stack — values handed to workers must never become arena handles). Already covered by the conservative hatches onCall/ParallelMap/SortByKey; slice 2 must keep that invariant when routing.
Structs§
- Arena
Report - Per-function arena-eligibility report. Mirrors
EscapeReport’s shape with the per-site bool inverted (arena_eligible = !escapes_under_request_scope) and renamed to reflect what downstream codegen will use it for. - Arena
Site
Functions§
- analyze_
function - Analyze one function. Cheap on functions with no aggregate sites (early-exits in the underlying pass).
- analyze_
program - Analyze every function. Functions with no aggregate sites are
omitted from the result, matching
escape::analyze_program. - build_
arena_ index - Convenience map keyed by
(fn_name, pc)for direct lookup during the slice-2 codegen pass. Mirrorsescape::build_escape_indexexactly so the codegen swap is structural.