diff options
author | Takashi Kokubun <takashikkbn@gmail.com> | 2023-10-03 22:39:45 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-03 22:39:45 -0700 |
commit | 465bc682a2b4823899be19440b0fd3395c22a255 (patch) | |
tree | 7a914203e00496e6cfa75dea678cdb62a0173d6b /yjit | |
parent | 6d28f96986c46771f545ce0cdceac5b1fbf33338 (diff) | |
download | ruby-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.rs | 34 |
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 |