Skip to content

Commit f5ec572

Browse files
committed
ZJIT: Remove NoEPEscape patch points after invalidation
Previously, rb_zjit_invalidate_no_ep_escape used .get() to look up patch points, leaving them in the map after patching. This caused every subsequent eval call to re-patch the same PatchPoints, each requiring mprotect syscalls to toggle W^X permissions. In railsbench, this dominated CPU time with thousands of redundant mprotect calls. Change .get() to .remove() so patch points are removed after being patched, matching the pattern used by CME invalidation.
1 parent c784bfc commit f5ec572

File tree

1 file changed

+1
-1
lines changed

1 file changed

+1
-1
lines changed

zjit/src/invariants.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ pub extern "C" fn rb_zjit_invalidate_no_ep_escape(iseq: IseqPtr) {
212212
invariants.ep_escape_iseqs.insert(iseq);
213213

214214
// If the ISEQ has been compiled assuming it doesn't escape EP, invalidate the JIT code.
215-
if let Some(patch_points) = invariants.no_ep_escape_iseq_patch_points.get(&iseq) {
215+
if let Some(patch_points) = invariants.no_ep_escape_iseq_patch_points.remove(&iseq) {
216216
debug!("EP is escaped: {}", iseq_name(iseq));
217217

218218
// Invalidate the patch points for this ISEQ

0 commit comments

Comments
 (0)