Evidence
A 5-second 1 ms symbolized sample of current main e78ae6c4 on the bounded object_churn kernel attributes 434 of 3,810 top-of-stack samples (~11.4%) to Interpreter.checkRestricted. It is the third-largest entry after VM dispatch and nursery sweeping. The quick object-allocation loop repeats that non-inlined error/TLS path for every dense replacement even though ordinary arrays have restricted_to == 0.
The first experiment moved the full check before the fused slice, but the VM's current safepoint step budget admits only one 61-step allocation iteration per slice. That variant therefore did not reduce check frequency and was rejected after a 2/7-pair result (+0.72% median time).
Refined scope
- load
restricted_todirectly in the quick loop and skip the non-inlinedcheckRestricted/thread-ID path when the owner is zero; - retain the full ownership check and exact error-step accounting for restricted arrays;
- retain ordinary bytecode fallback for synchronized/escaped execution;
- preserve exact bytecode steps, OOM resumption state, dense-store barriers, and restricted-object failure behavior;
- do not change the shared JavaScript/JSC workload source.
Acceptance criteria
- Record and reject the ineffective slice-level hoist with exact A/B evidence.
- Focused VM coverage proves the quick allocation loop still runs and preserves exact results/steps.
- Restricted receivers still fail without mutating the dense element.
- A current-main vs candidate alternating A/B preserves checksum
1030552128and shows a repeatable directobject_churnwin. - A post-change profile removes
checkRestrictedfrom the unrestricted per-cell hot path. - Run the full unit and comparison-harness suites only after a measured win.
- Commit references this issue and is pushed as Chris without coauthors.