Motivation
The shared-realm transition publication benchmark in #531 attributes a material part of per-edge synchronization to declarative Environment reads. Fresh tree-walker function activations are owned by one running mutator until a closure captures them, while the concurrent marker only reads their tables. Taking binding_lock for every identifier read therefore adds atomic traffic without protecting against a mutator writer.
Split from #532 so object descriptor synchronization and Environment ownership remain separately reviewable. Parent performance work: #531. Related shared-realm synchronization work: #478, #480.
Requirements
- Establish an explicit private-activation invariant for fresh tree-walker call environments and nested declarative scopes.
- Revoke private status before any closure can publish the environment or an ancestor to another mutator.
- Keep all binding writes synchronized with concurrent marking; only owner-mutator reads may elide the lock.
- Root, module, captured, VM, suspended, and otherwise shared environments remain on the locked path unless independently proven private.
- Preserve lexical lookup, aliases, TDZ, const/function-name metadata, direct eval, with, catch, per-iteration bindings, and closure semantics.
- Do not weaken GC relocation, concurrent marking, or no-GIL publication ordering.
Acceptance
- Focused tests prove zero Environment lock acquisitions for private reads and immediate locked fallback after capture.
- Shared closure and concurrent-GC tests pass under no-GIL and TSan.
- Full unit suite and relevant test262 scopes have zero regressions.
- Contention attribution records the before/after Environment lock counts under the #531 workload.
- Any public performance claim follows the checked-in benchmark-evidence workflow; counter reductions alone are diagnostic, not completion evidence.