summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--zjit/src/backend/arm64/mod.rs7
-rw-r--r--zjit/src/backend/lir.rs23
-rw-r--r--zjit/src/backend/x86_64/mod.rs7
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) => {