diff options
| -rw-r--r-- | zjit/src/backend/arm64/mod.rs | 7 | ||||
| -rw-r--r-- | zjit/src/backend/lir.rs | 23 | ||||
| -rw-r--r-- | zjit/src/backend/x86_64/mod.rs | 7 |
3 files changed, 26 insertions, 11 deletions
diff --git a/zjit/src/backend/arm64/mod.rs b/zjit/src/backend/arm64/mod.rs index 6b1cebf15e..9e94fd0e49 100644 --- a/zjit/src/backend/arm64/mod.rs +++ b/zjit/src/backend/arm64/mod.rs @@ -974,11 +974,14 @@ impl Assembler { // The write_pos for the last Insn::PatchPoint, if any let mut last_patch_pos: Option<usize> = None; + // Install a panic hook to dump Assembler with insn_idx on dev builds + let (_hook, mut hook_insn_idx) = AssemblerPanicHook::new(self, 0); + // For each instruction let mut insn_idx: usize = 0; while let Some(insn) = self.insns.get(insn_idx) { - // Dump Assembler with insn_idx if --zjit-dump-lir=panic is given - let _hook = AssemblerPanicHook::new(self, insn_idx); + // Update insn_idx that is shown on panic + hook_insn_idx.as_mut().map(|idx| idx.lock().map(|mut idx| *idx = insn_idx).unwrap()); match insn { Insn::Comment(text) => { diff --git a/zjit/src/backend/lir.rs b/zjit/src/backend/lir.rs index 1e7a2c0cde..3d2cfb6786 100644 --- a/zjit/src/backend/lir.rs +++ b/zjit/src/backend/lir.rs @@ -3,7 +3,7 @@ use std::fmt; use std::mem::take; use std::panic; use std::rc::Rc; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use crate::codegen::local_size_and_idx_to_ep_offset; use crate::cruby::{Qundef, RUBY_OFFSET_CFP_PC, RUBY_OFFSET_CFP_SP, SIZEOF_VALUE_I32, vm_stack_canary}; use crate::hir::SideExitReason; @@ -2283,29 +2283,38 @@ pub struct AssemblerPanicHook { } impl AssemblerPanicHook { - pub fn new(asm: &Assembler, insn_idx: usize) -> Option<Arc<Self>> { - // Install a panic hook if --zjit-dump-lir=panic is specified. + /// Install a panic hook to dump Assembler with insn_idx on dev builds. + /// This returns shared references to the previous hook and insn_idx. + /// It takes insn_idx as an argument so that you can manually use it + /// on non-emit passes that keep mutating the Assembler to be dumped. + pub fn new(asm: &Assembler, insn_idx: usize) -> (Option<Arc<Self>>, Option<Arc<Mutex<usize>>>) { if dump_lir_option!(panic) { // Wrap prev_hook with Arc to share it among the new hook and Self to be dropped. let prev_hook = panic::take_hook(); let panic_hook_ref = Arc::new(Self { prev_hook }); let weak_hook = Arc::downgrade(&panic_hook_ref); + // Wrap insn_idx with Arc to share it among the new hook and the caller mutating it. + let insn_idx = Arc::new(Mutex::new(insn_idx)); + let insn_idx_ref = insn_idx.clone(); + // Install a new hook to dump Assembler with insn_idx let asm = asm.clone(); panic::set_hook(Box::new(move |panic_info| { if let Some(panic_hook) = weak_hook.upgrade() { - // Dump Assembler, highlighting the insn_idx line - Self::dump_asm(&asm, insn_idx); + if let Ok(insn_idx) = insn_idx_ref.lock() { + // Dump Assembler, highlighting the insn_idx line + Self::dump_asm(&asm, *insn_idx); + } // Call the previous panic hook (panic_hook.prev_hook)(panic_info); } })); - Some(panic_hook_ref) + (Some(panic_hook_ref), Some(insn_idx)) } else { - None + (None, None) } } diff --git a/zjit/src/backend/x86_64/mod.rs b/zjit/src/backend/x86_64/mod.rs index 78e2f663a5..eb0e703302 100644 --- a/zjit/src/backend/x86_64/mod.rs +++ b/zjit/src/backend/x86_64/mod.rs @@ -590,11 +590,14 @@ impl Assembler { // The write_pos for the last Insn::PatchPoint, if any let mut last_patch_pos: Option<usize> = None; + // Install a panic hook to dump Assembler with insn_idx on dev builds + let (_hook, mut hook_insn_idx) = AssemblerPanicHook::new(self, 0); + // For each instruction let mut insn_idx: usize = 0; while let Some(insn) = self.insns.get(insn_idx) { - // Dump Assembler with insn_idx if --zjit-dump-lir=panic is given - let _hook = AssemblerPanicHook::new(self, insn_idx); + // Update insn_idx that is shown on panic + hook_insn_idx.as_mut().map(|idx| idx.lock().map(|mut idx| *idx = insn_idx).unwrap()); match insn { Insn::Comment(text) => { |
