Skip to content

Lock-free root fast paths for hygiene queries [-0.06%, below significance] - #65

Draft
xmakro wants to merge 1 commit into
perf/base-0713from
perf/hygiene-root-fastpaths
Draft

Lock-free root fast paths for hygiene queries [-0.06%, below significance]#65
xmakro wants to merge 1 commit into
perf/base-0713from
perf/hygiene-root-fastpaths

Conversation

@xmakro

@xmakro xmakro commented Jul 28, 2026

Copy link
Copy Markdown
Owner

outer_expn_is_descendant_of and normalize_to_macros_2_0/_macro_rules took the HygieneData lock (thread-local + RefCell, or a real mutex under the parallel front end) to compute answers that are statically known for the root syntax context — the common case for non-macro code, hit several times per name resolution.

Correctness argument, verified exhaustively: the root context's data is written once in HygieneData::new and never mutated afterwards. alloc_ctxt can never reserve index 0 (the vec starts with one element), update_dollar_crate_names writes only dollar_crate_name, and both the metadata and on-disk-cache decoders short-circuit raw_id == 0 before allocating. is_descendant_of(_, root) is unconditionally true — the existing sibling fast path checks ancestor == root before its cross-crate guard, so foreign expansions are correctly descendants.

Honest measurement: -0.06% geomean, zero cells clearing 0.25%. Real but below what a perf run would flag as significant. Submitted because it is provably equivalent and removes lock traffic that matters more under -Zthreads>1, not because the number justifies it on its own.

Known trade-off: a nested HygieneData::with bug would now abort only when the context happens to be non-root, rather than deterministically.

Measured in isolation against a clean base (ThinLTO stage2, glibc, instructions:u, full scenario, 5 crates x 3 profiles = 15 cells). This change was measured alone, not as part of a batch.

Reviewed adversarially before submission; findings that survived are reflected in the code and described above.

outer_expn_is_descendant_of and normalize_to_macros_2_0/_macro_rules
took the HygieneData lock to compute answers that are statically known
for the root syntax context, which is the case for the majority of
identifiers in non-macro code and is hit several times per name
resolution.

The root context's data is written once in HygieneData::new and never
mutated: alloc_ctxt can never reserve index 0, update_dollar_crate_names
touches only dollar_crate_name, and both metadata and on-disk-cache
decoding short-circuit raw id 0 before allocating.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant