aboutsummaryrefslogtreecommitdiffstats
path: root/yjit
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2023-10-03 22:39:45 -0700
committerGitHub <noreply@github.com>2023-10-03 22:39:45 -0700
commit465bc682a2b4823899be19440b0fd3395c22a255 (patch)
tree7a914203e00496e6cfa75dea678cdb62a0173d6b /yjit
parent6d28f96986c46771f545ce0cdceac5b1fbf33338 (diff)
downloadruby-465bc682a2b4823899be19440b0fd3395c22a255.tar.gz
YJIT: Call mprotect after entry stub failure (#8582)
Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
Diffstat (limited to 'yjit')
-rw-r--r--yjit/src/core.rs34
1 files changed, 16 insertions, 18 deletions
diff --git a/yjit/src/core.rs b/yjit/src/core.rs
index fea48c1b87..a5943fb393 100644
--- a/yjit/src/core.rs
+++ b/yjit/src/core.rs
@@ -2286,7 +2286,7 @@ fn entry_stub_hit_body(entry_ptr: *const c_void, ec: EcPtr) -> Option<*const u8>
let pending_entry = gen_entry_chain_guard(&mut asm, ocb, iseq, insn_idx)?;
asm.compile(cb, Some(ocb));
- // Try to find an existing compiled version of this block
+ // Find or compile a block version
let blockid = BlockId { iseq, idx: insn_idx };
let mut ctx = Context::default();
ctx.stack_size = stack_size;
@@ -2296,33 +2296,31 @@ fn entry_stub_hit_body(entry_ptr: *const c_void, ec: EcPtr) -> Option<*const u8>
let mut asm = Assembler::new();
asm.jmp(unsafe { blockref.as_ref() }.start_addr.into());
asm.compile(cb, Some(ocb));
- blockref
+ Some(blockref)
}
// If this block hasn't yet been compiled, generate blocks after the entry guard.
- None => match gen_block_series(blockid, &ctx, ec, cb, ocb) {
- Some(blockref) => blockref,
- None => { // No space
- // Trigger code GC. This entry point will be recompiled later.
- cb.code_gc(ocb);
- return None;
- }
- }
+ None => gen_block_series(blockid, &ctx, ec, cb, ocb),
};
- // Regenerate the previous entry
- assert!(!entry_ptr.is_null());
- let entryref = NonNull::<Entry>::new(entry_ptr as *mut Entry).expect("Entry should not be null");
- regenerate_entry(cb, &entryref, next_entry);
+ // Commit or retry the entry
+ if blockref.is_some() {
+ // Regenerate the previous entry
+ let entryref = NonNull::<Entry>::new(entry_ptr as *mut Entry).expect("Entry should not be null");
+ regenerate_entry(cb, &entryref, next_entry);
- // Write an entry to the heap and push it to the ISEQ
- let pending_entry = Rc::try_unwrap(pending_entry).ok().expect("PendingEntry should be unique");
- get_or_create_iseq_payload(iseq).entries.push(pending_entry.into_entry());
+ // Write an entry to the heap and push it to the ISEQ
+ let pending_entry = Rc::try_unwrap(pending_entry).ok().expect("PendingEntry should be unique");
+ get_or_create_iseq_payload(iseq).entries.push(pending_entry.into_entry());
+ } else { // No space
+ // Trigger code GC. This entry point will be recompiled later.
+ cb.code_gc(ocb);
+ }
cb.mark_all_executable();
ocb.unwrap().mark_all_executable();
// Let the stub jump to the block
- Some(unsafe { blockref.as_ref() }.start_addr.raw_ptr())
+ blockref.map(|block| unsafe { block.as_ref() }.start_addr.raw_ptr())
}
/// Generate a stub that calls entry_stub_hit