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
15 use crate::prelude::*;
16 use crate::profiling_agent::ProfilingAgent;
17 use ittapi::jit::MethodLoadBuilder;
18 use std::sync::Mutex;
19
20 /// Interface for driving the ittapi for VTune support
21 struct 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)]
29 struct State {
30 vtune: ittapi::jit::Jit,
31 }
32
33 /// Initialize a VTuneAgent.
new() -> Result<Box<dyn ProfilingAgent>>34 pub fn new() -> Result<Box<dyn ProfilingAgent>> {
35 Ok(Box::new(VTuneAgent {
36 state: Mutex::new(State {
37 vtune: Default::default(),
38 }),
39 }))
40 }
41
42 impl Drop for VTuneAgent {
drop(&mut self)43 fn drop(&mut self) {
44 self.state.lock().unwrap().event_shutdown();
45 }
46 }
47
48 impl State {
49 /// Notify vtune about a newly tracked code region.
notify_code(&mut self, module_name: &str, method_name: &str, code: &[u8])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
event_shutdown(&mut self)61 fn event_shutdown(&mut self) {
62 // Ignore if something went wrong.
63 let _ = self.vtune.shutdown();
64 }
65 }
66
67 impl ProfilingAgent for VTuneAgent {
register_function(&self, name: &str, code: &[u8])68 fn register_function(&self, name: &str, code: &[u8]) {
69 self.state.lock().unwrap().register_function(name, code);
70 }
71 }
72
73 impl State {
register_function(&mut self, name: &str, code: &[u8])74 fn register_function(&mut self, name: &str, code: &[u8]) {
75 self.notify_code("wasmtime", name, code);
76 }
77 }
78