Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions crates/jit/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"] }
serde = { version = "1.0.94", features = ["derive"] }
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"
rustc-demangle = "0.1.16"
cpp_demangle = "0.3.2"
Expand All @@ -39,7 +39,7 @@ rustix = { version = "0.35.6", features = ["process"] }

[features]
jitdump = ['wasmtime-jit-debug']
vtune = ['ittapi-rs']
vtune = ['ittapi']

[badges]
maintenance = { status = "actively-developed" }
4 changes: 3 additions & 1 deletion crates/jit/src/profiling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ 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"]
mod vtune;
} else {
Expand Down
92 changes: 27 additions & 65 deletions crates/jit/src/profiling/vtune.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,30 @@

use crate::{CompiledModule, ProfilingAgent};
use anyhow::Result;
use core::ptr;
use ittapi_rs::*;
use std::ffi::CString;
use ittapi::jit::MethodLoadBuilder;
use std::sync::{atomic, Mutex};
use wasmtime_environ::EntityRef;

/// Interface for driving the ittapi for VTune support
pub struct VTuneAgent {
// Note that we use a mutex internally to serialize state updates
// since multiple threads may be sharing this agent.
// Note that we use a mutex internally to serialize state updates since multiple threads may be
// sharing this agent.
state: Mutex<State>,
}

/// Interface for driving vtune
#[derive(Clone, Debug, Default)]
struct State;
#[derive(Default)]
struct State {
vtune: ittapi::jit::Jit,
}

impl VTuneAgent {
/// Initialize a VTuneAgent.
pub fn new() -> Result<Self> {
Ok(VTuneAgent {
state: Mutex::new(State),
state: Mutex::new(State {
vtune: Default::default(),
}),
})
}
}
Expand All @@ -47,56 +49,21 @@ impl Drop for VTuneAgent {
}

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.
fn event_load(
&mut self,
method_id: u32,
module_name: &str,
method_name: &str,
addr: *const u8,
len: usize,
) -> () {
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,
);
}
fn notify_code(&mut self, module_name: &str, method_name: &str, addr: *const u8, len: usize) {
self.vtune
.load_method(
MethodLoadBuilder::new(method_name.to_owned(), addr, len)
.class_file_name(module_name.to_owned())
.source_file_name("<unknown wasm filename>".to_owned()),
)
.unwrap();
}

/// Shutdown module
fn event_shutdown(&mut self) -> () {
unsafe {
log::trace!("NotifyEvent shutdown (whole module)");
let _ret = iJIT_NotifyEvent(iJIT_jvm_event_iJVM_EVENT_TYPE_SHUTDOWN, ptr::null_mut());
}
fn event_shutdown(&mut self) {
// Ignore if something went wrong.
let _ = self.vtune.shutdown();
}
}

Expand All @@ -113,7 +80,7 @@ impl ProfilingAgent for VTuneAgent {
}

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.
static MODULE_ID: atomic::AtomicUsize = atomic::AtomicUsize::new(0);
let global_module_id = MODULE_ID.fetch_add(1, atomic::Ordering::SeqCst);
Expand All @@ -128,30 +95,26 @@ impl State {
for (idx, func) in module.finished_functions() {
let (addr, len) = unsafe { ((*func).as_ptr().cast::<u8>(), (*func).len()) };
let method_name = super::debug_name(module, idx);
let method_id = self.get_method_id();
log::trace!(
"new function ({}) {:?}::{:?} @ {:?}\n",
method_id,
"new function {:?}::{:?} @ {:?}\n",
module_name,
method_name,
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.
for (idx, func, len) in module.trampolines() {
let idx = idx.index();
let (addr, len) = (func as usize as *const u8, len);
let method_name = format!("wasm::trampoline[{}]", idx,);
let method_id = self.get_method_id();
log::trace!(
"new trampoline ({}) for exported signature {} @ {:?}\n",
method_id,
"new trampoline for exported signature {} @ {:?}\n",
idx,
addr
);
self.event_load(method_id, &module_name, &method_name, addr, len);
self.notify_code(&module_name, &method_name, addr, len);
}
}

Expand All @@ -163,7 +126,6 @@ impl State {
_pid: u32,
_tid: u32,
) {
let method_id = self.get_method_id();
self.event_load(method_id, "wasm trampoline for Func::new", name, addr, size);
self.notify_code("wasm trampoline for Func::new", name, addr, size);
}
}