use crate::profiling::ProfilingAgent;
use anyhow::Result;
use std::process;
use std::sync::Mutex;
use target_lexicon::Architecture;
use wasmtime_jit_debug::perf_jitdump::*;
use object::elf;
struct JitDumpAgent {
pid: u32,
}
static JITDUMP_FILE: Mutex<Option<JitDumpFile>> = Mutex::new(None);
pub fn new() -> Result<Box<dyn ProfilingAgent>> {
let mut jitdump_file = JITDUMP_FILE.lock().unwrap();
if jitdump_file.is_none() {
let filename = format!("./jit-{}.dump", process::id());
let e_machine = match target_lexicon::HOST.architecture {
Architecture::X86_64 => elf::EM_X86_64 as u32,
Architecture::X86_32(_) => elf::EM_386 as u32,
Architecture::Arm(_) => elf::EM_ARM as u32,
Architecture::Aarch64(_) => elf::EM_AARCH64 as u32,
Architecture::S390x => elf::EM_S390 as u32,
_ => unimplemented!("unrecognized architecture"),
};
*jitdump_file = Some(JitDumpFile::new(filename, e_machine)?);
}
Ok(Box::new(JitDumpAgent {
pid: std::process::id(),
}))
}
impl ProfilingAgent for JitDumpAgent {
fn register_function(&self, name: &str, addr: *const u8, size: usize) {
let mut jitdump_file = JITDUMP_FILE.lock().unwrap();
let jitdump_file = jitdump_file.as_mut().unwrap();
let timestamp = jitdump_file.get_time_stamp();
#[allow(trivial_numeric_casts)]
let tid = rustix::thread::gettid().as_raw_nonzero().get() as u32;
if let Err(err) =
jitdump_file.dump_code_load_record(&name, addr, size, timestamp, self.pid, tid)
{
println!("Jitdump: write_code_load_failed_record failed: {:?}\n", err);
}
}
}