Load generated trampolines into jitdump when profiling (#3344)

* Load generated trampolines into jitdump when profiling

This commit updates the jitdump profiler to generate JIT profiling
records for generated trampolines in a wasm module in addition to the
functions already in a module. It's also updated to learn about
trampolines generated via `Func::new` and friends. These trampolines
were all not previously registered meaning that stack traces with these
pc values would be confusing to see in the profile output. While the
names aren't the best it should at least be more clear than before if a
function is hot!

* Fix more builds
This commit is contained in:
Alex Crichton
2021-09-21 13:05:31 -05:00
committed by GitHub
parent 38728c5746
commit 38463d11ed
8 changed files with 76 additions and 10 deletions

View File

@@ -20,4 +20,5 @@ impl JitDumpAgent {
impl ProfilingAgent for JitDumpAgent {
fn module_load(&self, _module: &CompiledModule, _dbg_image: Option<&[u8]>) {}
fn trampoline_load(&self, _file: &object::File<'_>) {}
}

View File

@@ -21,6 +21,7 @@ use std::ptr;
use std::sync::Mutex;
use std::{borrow, mem, process};
use target_lexicon::Architecture;
use wasmtime_environ::EntityRef;
use object::elf;
@@ -202,6 +203,9 @@ impl ProfilingAgent for JitDumpAgent {
fn module_load(&self, module: &CompiledModule, dbg_image: Option<&[u8]>) {
self.state.lock().unwrap().module_load(module, dbg_image);
}
fn trampoline_load(&self, file: &object::File<'_>) {
self.state.lock().unwrap().trampoline_load(file)
}
}
impl State {
@@ -280,7 +284,7 @@ impl State {
}
/// Sent when a method is compiled and loaded into memory by the VM.
pub fn module_load(&mut self, module: &CompiledModule, dbg_image: Option<&[u8]>) -> () {
pub fn module_load(&mut self, module: &CompiledModule, dbg_image: Option<&[u8]>) {
let pid = process::id();
let tid = pid; // ThreadId does appear to track underlying thread. Using PID.
@@ -299,6 +303,52 @@ impl State {
self.dump_code_load_record(&name, addr, len, timestamp, pid, tid);
}
}
for (idx, func, len) in module.trampolines() {
let (addr, len) = (func as usize as *const u8, len);
let timestamp = self.get_time_stamp();
let name = format!("wasm::trampoline[{}]", idx.index());
self.dump_code_load_record(&name, addr, len, timestamp, pid, tid);
}
}
fn trampoline_load(&mut self, image: &object::File<'_>) {
use object::{ObjectSection, ObjectSymbol, SectionKind, SymbolKind};
let pid = process::id();
let tid = pid;
let text_base = match image.sections().find(|s| s.kind() == SectionKind::Text) {
Some(section) => match section.data() {
Ok(data) => data.as_ptr() as usize,
Err(_) => return,
},
None => return,
};
for sym in image.symbols() {
if !sym.is_definition() {
continue;
}
if sym.kind() != SymbolKind::Text {
continue;
}
let address = sym.address();
let size = sym.size();
if address == 0 || size == 0 {
continue;
}
if let Ok(name) = sym.name() {
let addr = text_base + address as usize;
let timestamp = self.get_time_stamp();
self.dump_code_load_record(
&name,
addr as *const u8,
size as usize,
timestamp,
pid,
tid,
);
}
}
}
fn dump_code_load_record(
@@ -309,7 +359,7 @@ impl State {
timestamp: u64,
pid: u32,
tid: u32,
) -> () {
) {
let name_len = method_name.len() + 1;
let size_limit = mem::size_of::<CodeLoadRecord>();

View File

@@ -20,4 +20,5 @@ impl VTuneAgent {
impl ProfilingAgent for VTuneAgent {
fn module_load(&self, _module: &crate::CompiledModule, _dbg_image: Option<&[u8]>) {}
fn trampoline_load(&self, _file: &object::File<'_>) {}
}

View File

@@ -112,6 +112,9 @@ impl ProfilingAgent for VTuneAgent {
fn module_load(&self, module: &CompiledModule, dbg_image: Option<&[u8]>) {
self.state.lock().unwrap().module_load(module, dbg_image);
}
fn trampoline_load(&self, _file: &object::File<'_>) {
// TODO: needs an implementation
}
}
impl State {