Skip to content

Commit ade4558

Browse files
tekknolagiXrXr
andauthored
ZJIT: Catch more failed recursive compilations (ruby#14042)
Untangle the logic a bit and specifically: * catch `gen_entry` failures * don't set `start_ptr` until all recursive calls succeed Co-authored-by: Alan Wu <[email protected]>
1 parent 039f413 commit ade4558

File tree

1 file changed

+30
-22
lines changed

1 file changed

+30
-22
lines changed

zjit/src/codegen.rs

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -121,39 +121,46 @@ fn gen_iseq_entry_point_body(cb: &mut CodeBlock, iseq: IseqPtr) -> *const u8 {
121121
};
122122

123123
// Compile the High-level IR
124-
let (start_ptr, mut branch_iseqs) = match gen_function(cb, iseq, &function) {
125-
Some((start_ptr, gc_offsets, jit)) => {
126-
// Remember the block address to reuse it later
127-
let payload = get_or_create_iseq_payload(iseq);
128-
payload.start_ptr = Some(start_ptr);
129-
append_gc_offsets(iseq, &gc_offsets);
130-
131-
// Compile an entry point to the JIT code
132-
(gen_entry(cb, iseq, &function, start_ptr), jit.branch_iseqs)
133-
},
134-
None => (None, vec![]),
124+
let Some((start_ptr, gc_offsets, jit)) = gen_function(cb, iseq, &function) else {
125+
debug!("Failed to compile iseq: gen_function failed: {}", iseq_get_location(iseq, 0));
126+
return std::ptr::null();
135127
};
136128

129+
// Compile an entry point to the JIT code
130+
let Some(entry_ptr) = gen_entry(cb, iseq, &function, start_ptr) else {
131+
debug!("Failed to compile iseq: gen_entry failed: {}", iseq_get_location(iseq, 0));
132+
return std::ptr::null();
133+
};
134+
135+
let mut branch_iseqs = jit.branch_iseqs;
136+
137137
// Recursively compile callee ISEQs
138+
let caller_iseq = iseq;
138139
while let Some((branch, iseq)) = branch_iseqs.pop() {
139140
// Disable profiling. This will be the last use of the profiling information for the ISEQ.
140141
unsafe { rb_zjit_profile_disable(iseq); }
141142

142143
// Compile the ISEQ
143-
if let Some((callee_ptr, callee_branch_iseqs)) = gen_iseq(cb, iseq) {
144-
let callee_addr = callee_ptr.raw_ptr(cb);
145-
branch.regenerate(cb, |asm| {
146-
asm.ccall(callee_addr, vec![]);
147-
});
148-
branch_iseqs.extend(callee_branch_iseqs);
149-
} else {
144+
let Some((callee_ptr, callee_branch_iseqs)) = gen_iseq(cb, iseq) else {
150145
// Failed to compile the callee. Bail out of compiling this graph of ISEQs.
146+
debug!("Failed to compile iseq: could not compile callee: {} -> {}",
147+
iseq_get_location(caller_iseq, 0), iseq_get_location(iseq, 0));
151148
return std::ptr::null();
152-
}
149+
};
150+
let callee_addr = callee_ptr.raw_ptr(cb);
151+
branch.regenerate(cb, |asm| {
152+
asm.ccall(callee_addr, vec![]);
153+
});
154+
branch_iseqs.extend(callee_branch_iseqs);
153155
}
154156

155-
// Return a JIT code address or a null pointer
156-
start_ptr.map(|start_ptr| start_ptr.raw_ptr(cb)).unwrap_or(std::ptr::null())
157+
// Remember the block address to reuse it later
158+
let payload = get_or_create_iseq_payload(iseq);
159+
payload.start_ptr = Some(start_ptr);
160+
append_gc_offsets(iseq, &gc_offsets);
161+
162+
// Return a JIT code address
163+
entry_ptr.raw_ptr(cb)
157164
}
158165

159166
/// Write an entry to the perf map in /tmp
@@ -1177,7 +1184,8 @@ fn compile_iseq(iseq: IseqPtr) -> Option<Function> {
11771184
let mut function = match iseq_to_hir(iseq) {
11781185
Ok(function) => function,
11791186
Err(err) => {
1180-
debug!("ZJIT: iseq_to_hir: {err:?}");
1187+
let name = crate::cruby::iseq_get_location(iseq, 0);
1188+
debug!("ZJIT: iseq_to_hir: {err:?}: {name}");
11811189
return None;
11821190
}
11831191
};

0 commit comments

Comments
 (0)