From ff77473acbd6d807430bb9a188205f3ed6c9cf22 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Thu, 17 Jul 2025 11:39:03 -0700 Subject: [PATCH] ZJIT: Mark the code region executable on partial failures (#13937) --- zjit/src/codegen.rs | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/zjit/src/codegen.rs b/zjit/src/codegen.rs index f67757038e..50d8f4d448 100644 --- a/zjit/src/codegen.rs +++ b/zjit/src/codegen.rs @@ -96,8 +96,22 @@ pub extern "C" fn rb_zjit_iseq_gen_entry_point(iseq: IseqPtr, _ec: EcPtr) -> *co code_ptr } -/// Compile an entry point for a given ISEQ +/// See [gen_iseq_entry_point_body]. This wrapper is to make sure cb.mark_all_executable() +/// is called even if gen_iseq_entry_point_body() partially fails and returns a null pointer. fn gen_iseq_entry_point(iseq: IseqPtr) -> *const u8 { + let cb = ZJITState::get_code_block(); + let code_ptr = gen_iseq_entry_point_body(cb, iseq); + + // Always mark the code region executable if asm.compile() has been used. + // We need to do this even if code_ptr is null because, even if gen_entry() + // or gen_iseq() fails, gen_function() has used asm.compile(). + cb.mark_all_executable(); + + code_ptr +} + +/// Compile an entry point for a given ISEQ +fn gen_iseq_entry_point_body(cb: &mut CodeBlock, iseq: IseqPtr) -> *const u8 { // Compile ISEQ into High-level IR let function = match compile_iseq(iseq) { Some(function) => function, @@ -105,7 +119,6 @@ fn gen_iseq_entry_point(iseq: IseqPtr) -> *const u8 { }; // Compile the High-level IR - let cb = ZJITState::get_code_block(); let (start_ptr, mut branch_iseqs) = match gen_function(cb, iseq, &function) { Some((start_ptr, gc_offsets, jit)) => { // Remember the block address to reuse it later @@ -137,9 +150,6 @@ fn gen_iseq_entry_point(iseq: IseqPtr) -> *const u8 { } } - // Always mark the code region executable if asm.compile() has been used - cb.mark_all_executable(); - // Return a JIT code address or a null pointer start_ptr.map(|start_ptr| start_ptr.raw_ptr(cb)).unwrap_or(std::ptr::null()) }