@@ -96,16 +96,29 @@ pub extern "C" fn rb_zjit_iseq_gen_entry_point(iseq: IseqPtr, _ec: EcPtr) -> *co
9696 code_ptr
9797}
9898
99- /// Compile an entry point for a given ISEQ
99+ /// See [gen_iseq_entry_point_body]. This wrapper is to make sure cb.mark_all_executable()
100+ /// is called even if gen_iseq_entry_point_body() partially fails and returns a null pointer.
100101fn gen_iseq_entry_point ( iseq : IseqPtr ) -> * const u8 {
102+ let cb = ZJITState :: get_code_block ( ) ;
103+ let code_ptr = gen_iseq_entry_point_body ( cb, iseq) ;
104+
105+ // Always mark the code region executable if asm.compile() has been used.
106+ // We need to do this even if code_ptr is null because, even if gen_entry()
107+ // or gen_iseq() fails, gen_function() has used asm.compile().
108+ cb. mark_all_executable ( ) ;
109+
110+ code_ptr
111+ }
112+
113+ /// Compile an entry point for a given ISEQ
114+ fn gen_iseq_entry_point_body ( cb : & mut CodeBlock , iseq : IseqPtr ) -> * const u8 {
101115 // Compile ISEQ into High-level IR
102116 let function = match compile_iseq ( iseq) {
103117 Some ( function) => function,
104118 None => return std:: ptr:: null ( ) ,
105119 } ;
106120
107121 // Compile the High-level IR
108- let cb = ZJITState :: get_code_block ( ) ;
109122 let ( start_ptr, mut branch_iseqs) = match gen_function ( cb, iseq, & function) {
110123 Some ( ( start_ptr, gc_offsets, jit) ) => {
111124 // Remember the block address to reuse it later
@@ -137,9 +150,6 @@ fn gen_iseq_entry_point(iseq: IseqPtr) -> *const u8 {
137150 }
138151 }
139152
140- // Always mark the code region executable if asm.compile() has been used
141- cb. mark_all_executable ( ) ;
142-
143153 // Return a JIT code address or a null pointer
144154 start_ptr. map ( |start_ptr| start_ptr. raw_ptr ( cb) ) . unwrap_or ( std:: ptr:: null ( ) )
145155}
0 commit comments