Browse Source

Upgrade to the high-level `ittapi` v0.3.0 crate (#4003)

* Upgrade to the high-level ittapi v0.3.0 crate

* Add exclusion for windows mingw
pull/4474/head
Benjamin Bouvier 2 years ago
committed by GitHub
parent
commit
f0337c9c76
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 19
      Cargo.lock
  2. 4
      crates/jit/Cargo.toml
  3. 4
      crates/jit/src/profiling.rs
  4. 92
      crates/jit/src/profiling/vtune.rs

19
Cargo.lock

@ -1485,10 +1485,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
[[package]] [[package]]
name = "ittapi-rs" name = "ittapi"
version = "0.2.0" version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "663fe0550070071ff59e981864a9cd3ee1c869ed0a088140d9ac4dc05ea6b1a1"
dependencies = [
"anyhow",
"ittapi-sys",
"log",
]
[[package]]
name = "ittapi-sys"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f712648a1ad72fbfb7adc2772c331e8d90f022f8cf30cbabefba2878dd3172b0" checksum = "e21911b7183f38c71d75ab478a527f314e28db51027037ece2e5511ed9410703"
dependencies = [ dependencies = [
"cc", "cc",
] ]
@ -3571,7 +3582,7 @@ dependencies = [
"cfg-if", "cfg-if",
"cpp_demangle", "cpp_demangle",
"gimli", "gimli",
"ittapi-rs", "ittapi",
"log", "log",
"object", "object",
"rustc-demangle", "rustc-demangle",

4
crates/jit/Cargo.toml

@ -22,7 +22,7 @@ gimli = { version = "0.26.0", default-features = false, features = ["std", "read
object = { version = "0.29.0", default-features = false, features = ["std", "read_core", "elf"] } object = { version = "0.29.0", default-features = false, features = ["std", "read_core", "elf"] }
serde = { version = "1.0.94", features = ["derive"] } serde = { version = "1.0.94", features = ["derive"] }
addr2line = { version = "0.17.0", default-features = false } addr2line = { version = "0.17.0", default-features = false }
ittapi-rs = { version = "0.2.0", optional = true } ittapi = { version = "0.3.0", optional = true }
bincode = "1.2.1" bincode = "1.2.1"
rustc-demangle = "0.1.16" rustc-demangle = "0.1.16"
cpp_demangle = "0.3.2" cpp_demangle = "0.3.2"
@ -39,7 +39,7 @@ rustix = { version = "0.35.6", features = ["process"] }
[features] [features]
jitdump = ['wasmtime-jit-debug'] jitdump = ['wasmtime-jit-debug']
vtune = ['ittapi-rs'] vtune = ['ittapi']
[badges] [badges]
maintenance = { status = "actively-developed" } maintenance = { status = "actively-developed" }

4
crates/jit/src/profiling.rs

@ -12,7 +12,9 @@ cfg_if::cfg_if! {
} }
cfg_if::cfg_if! { cfg_if::cfg_if! {
if #[cfg(all(feature = "vtune", target_arch = "x86_64"))] { // Note: VTune support is disabled on windows mingw because the ittapi crate doesn't compile
// there; see also https://github.com/bytecodealliance/wasmtime/pull/4003 for rationale.
if #[cfg(all(feature = "vtune", target_arch = "x86_64", not(all(target_os = "windows", target_env = "gnu"))))] {
#[path = "profiling/vtune.rs"] #[path = "profiling/vtune.rs"]
mod vtune; mod vtune;
} else { } else {

92
crates/jit/src/profiling/vtune.rs

@ -14,28 +14,30 @@
use crate::{CompiledModule, ProfilingAgent}; use crate::{CompiledModule, ProfilingAgent};
use anyhow::Result; use anyhow::Result;
use core::ptr; use ittapi::jit::MethodLoadBuilder;
use ittapi_rs::*;
use std::ffi::CString;
use std::sync::{atomic, Mutex}; use std::sync::{atomic, Mutex};
use wasmtime_environ::EntityRef; use wasmtime_environ::EntityRef;
/// Interface for driving the ittapi for VTune support /// Interface for driving the ittapi for VTune support
pub struct VTuneAgent { pub struct VTuneAgent {
// Note that we use a mutex internally to serialize state updates // Note that we use a mutex internally to serialize state updates since multiple threads may be
// since multiple threads may be sharing this agent. // sharing this agent.
state: Mutex<State>, state: Mutex<State>,
} }
/// Interface for driving vtune /// Interface for driving vtune
#[derive(Clone, Debug, Default)] #[derive(Default)]
struct State; struct State {
vtune: ittapi::jit::Jit,
}
impl VTuneAgent { impl VTuneAgent {
/// Initialize a VTuneAgent. /// Initialize a VTuneAgent.
pub fn new() -> Result<Self> { pub fn new() -> Result<Self> {
Ok(VTuneAgent { Ok(VTuneAgent {
state: Mutex::new(State), state: Mutex::new(State {
vtune: Default::default(),
}),
}) })
} }
} }
@ -47,56 +49,21 @@ impl Drop for VTuneAgent {
} }
impl State { impl State {
/// Return a method ID for use with the ittapi.
fn get_method_id(&self) -> u32 {
unsafe { iJIT_GetNewMethodID() }
}
/// Notify vtune about a newly tracked code region. /// Notify vtune about a newly tracked code region.
fn event_load( fn notify_code(&mut self, module_name: &str, method_name: &str, addr: *const u8, len: usize) {
&mut self, self.vtune
method_id: u32, .load_method(
module_name: &str, MethodLoadBuilder::new(method_name.to_owned(), addr, len)
method_name: &str, .class_file_name(module_name.to_owned())
addr: *const u8, .source_file_name("<unknown wasm filename>".to_owned()),
len: usize, )
) -> () { .unwrap();
let mut jmethod = _iJIT_Method_Load {
method_id,
method_name: CString::new(method_name)
.expect("CString::new failed")
.into_raw(),
method_load_address: addr as *mut ::std::os::raw::c_void,
method_size: len as u32,
line_number_size: 0,
line_number_table: ptr::null_mut(),
class_id: 0,
class_file_name: CString::new(module_name)
.expect("CString::new failed")
.into_raw(),
source_file_name: CString::new("<unknown wasm filename>")
.expect("CString::new failed")
.into_raw(),
};
let jmethod_ptr = &mut jmethod as *mut _ as *mut _;
unsafe {
log::trace!(
"NotifyEvent: method load (single method with id {})",
method_id
);
let _ret = iJIT_NotifyEvent(
iJIT_jvm_event_iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED,
jmethod_ptr as *mut ::std::os::raw::c_void,
);
}
} }
/// Shutdown module /// Shutdown module
fn event_shutdown(&mut self) -> () { fn event_shutdown(&mut self) {
unsafe { // Ignore if something went wrong.
log::trace!("NotifyEvent shutdown (whole module)"); let _ = self.vtune.shutdown();
let _ret = iJIT_NotifyEvent(iJIT_jvm_event_iJVM_EVENT_TYPE_SHUTDOWN, ptr::null_mut());
}
} }
} }
@ -113,7 +80,7 @@ impl ProfilingAgent for VTuneAgent {
} }
impl State { impl State {
fn module_load(&mut self, module: &CompiledModule, _dbg_image: Option<&[u8]>) -> () { fn module_load(&mut self, module: &CompiledModule, _dbg_image: Option<&[u8]>) {
// Global counter for module ids. // Global counter for module ids.
static MODULE_ID: atomic::AtomicUsize = atomic::AtomicUsize::new(0); static MODULE_ID: atomic::AtomicUsize = atomic::AtomicUsize::new(0);
let global_module_id = MODULE_ID.fetch_add(1, atomic::Ordering::SeqCst); let global_module_id = MODULE_ID.fetch_add(1, atomic::Ordering::SeqCst);
@ -128,15 +95,13 @@ impl State {
for (idx, func) in module.finished_functions() { for (idx, func) in module.finished_functions() {
let (addr, len) = unsafe { ((*func).as_ptr().cast::<u8>(), (*func).len()) }; let (addr, len) = unsafe { ((*func).as_ptr().cast::<u8>(), (*func).len()) };
let method_name = super::debug_name(module, idx); let method_name = super::debug_name(module, idx);
let method_id = self.get_method_id();
log::trace!( log::trace!(
"new function ({}) {:?}::{:?} @ {:?}\n", "new function {:?}::{:?} @ {:?}\n",
method_id,
module_name, module_name,
method_name, method_name,
addr addr
); );
self.event_load(method_id, &module_name, &method_name, addr, len); self.notify_code(&module_name, &method_name, addr, len);
} }
// Note: these are the trampolines into exported functions. // Note: these are the trampolines into exported functions.
@ -144,14 +109,12 @@ impl State {
let idx = idx.index(); let idx = idx.index();
let (addr, len) = (func as usize as *const u8, len); let (addr, len) = (func as usize as *const u8, len);
let method_name = format!("wasm::trampoline[{}]", idx,); let method_name = format!("wasm::trampoline[{}]", idx,);
let method_id = self.get_method_id();
log::trace!( log::trace!(
"new trampoline ({}) for exported signature {} @ {:?}\n", "new trampoline for exported signature {} @ {:?}\n",
method_id,
idx, idx,
addr addr
); );
self.event_load(method_id, &module_name, &method_name, addr, len); self.notify_code(&module_name, &method_name, addr, len);
} }
} }
@ -163,7 +126,6 @@ impl State {
_pid: u32, _pid: u32,
_tid: u32, _tid: u32,
) { ) {
let method_id = self.get_method_id(); self.notify_code("wasm trampoline for Func::new", name, addr, size);
self.event_load(method_id, "wasm trampoline for Func::new", name, addr, size);
} }
} }

Loading…
Cancel
Save