@@ -96,16 +96,29 @@ pub extern "C" fn rb_zjit_iseq_gen_entry_point(iseq: IseqPtr, _ec: EcPtr) -> *co
96
96
code_ptr
97
97
}
98
98
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.
100
101
fn 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 {
101
115
// Compile ISEQ into High-level IR
102
116
let function = match compile_iseq(iseq) {
103
117
Some(function) => function,
104
118
None => return std::ptr::null(),
105
119
};
106
120
107
121
// Compile the High-level IR
108
- let cb = ZJITState::get_code_block();
109
122
let (start_ptr, mut branch_iseqs) = match gen_function(cb, iseq, &function) {
110
123
Some((start_ptr, gc_offsets, jit)) => {
111
124
// Remember the block address to reuse it later
@@ -137,9 +150,6 @@ fn gen_iseq_entry_point(iseq: IseqPtr) -> *const u8 {
137
150
}
138
151
}
139
152
140
- // Always mark the code region executable if asm.compile() has been used
141
- cb.mark_all_executable();
142
-
143
153
// Return a JIT code address or a null pointer
144
154
start_ptr.map(|start_ptr| start_ptr.raw_ptr(cb)).unwrap_or(std::ptr::null())
145
155
}
0 commit comments