wasmtime/profiling_agent/
vtune.rs

1//! Adds support for profiling JIT-ed code using VTune. By default, VTune
2//! support is built in to Wasmtime (configure with the `vtune` feature flag).
3//! To enable it at runtime, use the `--profile=vtune` CLI flag.
4//!
5//! ### Profile
6//!
7//! ```ignore
8//! vtune -run-pass-thru=--no-altstack -v -collect hotspots target/debug/wasmtime --profile=vtune test.wasm
9//! ```
10//!
11//! Note: `vtune` is a command-line tool for VTune which must [be
12//! installed](https://www.intel.com/content/www/us/en/developer/tools/oneapi/vtune-profiler.html#standalone)
13//! for this to work.
14
15use crate::prelude::*;
16use crate::profiling_agent::ProfilingAgent;
17use ittapi::jit::MethodLoadBuilder;
18use std::sync::Mutex;
19
20/// Interface for driving the ittapi for VTune support
21struct VTuneAgent {
22    // Note that we use a mutex internally to serialize state updates since multiple threads may be
23    // sharing this agent.
24    state: Mutex<State>,
25}
26
27/// Interface for driving vtune
28#[derive(Default)]
29struct State {
30    vtune: ittapi::jit::Jit,
31}
32
33/// Initialize a VTuneAgent.
34pub fn new() -> Result<Box<dyn ProfilingAgent>> {
35    Ok(Box::new(VTuneAgent {
36        state: Mutex::new(State {
37            vtune: Default::default(),
38        }),
39    }))
40}
41
42impl Drop for VTuneAgent {
43    fn drop(&mut self) {
44        self.state.lock().unwrap().event_shutdown();
45    }
46}
47
48impl State {
49    /// Notify vtune about a newly tracked code region.
50    fn notify_code(&mut self, module_name: &str, method_name: &str, code: &[u8]) {
51        self.vtune
52            .load_method(
53                MethodLoadBuilder::new(method_name.to_owned(), code.as_ptr(), code.len())
54                    .class_file_name(module_name.to_owned())
55                    .source_file_name("<unknown wasm filename>".to_owned()),
56            )
57            .unwrap();
58    }
59
60    /// Shutdown module
61    fn event_shutdown(&mut self) {
62        // Ignore if something went wrong.
63        let _ = self.vtune.shutdown();
64    }
65}
66
67impl ProfilingAgent for VTuneAgent {
68    fn register_function(&self, name: &str, code: &[u8]) {
69        self.state.lock().unwrap().register_function(name, code);
70    }
71}
72
73impl State {
74    fn register_function(&mut self, name: &str, code: &[u8]) {
75        self.notify_code("wasmtime", name, code);
76    }
77}