Merge wasmtime-jit and wasmtime-profiling (#3247)

* Merge `wasmtime-jit` and `wasmtime-profiling`

This commit merges the `wasmtime-profiling` crate into the
`wasmtime-jit` crate. It wasn't really buying a ton being a separate
crate and an upcoming refactoring I'd like to do is to remove the
`FinishedFunctions` structure. To enable the profilers to work as they
used to this commit changes them to pass `CompiledModule` as the
argument, but this only works if the profiling trait can see the
`CompiledModule` type.

* Fix a length calculation
This commit is contained in:
Alex Crichton
2021-08-26 16:22:11 -05:00
committed by GitHub
parent 0771abf210
commit d74cc33856
13 changed files with 72 additions and 161 deletions

23
Cargo.lock generated
View File

@@ -3572,7 +3572,6 @@ dependencies = [
"wasmtime-environ",
"wasmtime-fiber",
"wasmtime-jit",
"wasmtime-profiling",
"wasmtime-runtime",
"wasmtime-wasi",
"wat",
@@ -3777,16 +3776,18 @@ dependencies = [
"anyhow",
"cfg-if 1.0.0",
"gimli",
"ittapi-rs",
"libc",
"log",
"more-asserts",
"object",
"region",
"scroll",
"serde",
"target-lexicon",
"thiserror",
"wasmparser",
"wasmtime-environ",
"wasmtime-profiling",
"wasmtime-runtime",
"winapi",
]
@@ -3805,24 +3806,6 @@ dependencies = [
"wasmtime-environ",
]
[[package]]
name = "wasmtime-profiling"
version = "0.29.0"
dependencies = [
"anyhow",
"cfg-if 1.0.0",
"gimli",
"ittapi-rs",
"lazy_static",
"libc",
"object",
"scroll",
"serde",
"target-lexicon",
"wasmtime-environ",
"wasmtime-runtime",
]
[[package]]
name = "wasmtime-runtime"
version = "0.29.0"

View File

@@ -13,7 +13,6 @@ edition = "2018"
[dependencies]
wasmtime-environ = { path = "../environ", version = "0.29.0" }
wasmtime-runtime = { path = "../runtime", version = "0.29.0" }
wasmtime-profiling = { path = "../profiling", version = "0.29.0" }
region = "2.2.0"
thiserror = "1.0.4"
target-lexicon = { version = "0.12.0", default-features = false }
@@ -26,13 +25,16 @@ gimli = { version = "0.25.0", default-features = false, features = ["std", "read
object = { version = "0.26.0", default-features = false, features = ["std", "read_core", "elf"] }
serde = { version = "1.0.94", features = ["derive"] }
addr2line = { version = "0.16.0", default-features = false }
libc = { version = "0.2.60", default-features = false, optional = true }
scroll = { version = "0.10.1", features = ["derive"], optional = true }
ittapi-rs = { version = "0.1.5", optional = true }
[target.'cfg(target_os = "windows")'.dependencies]
winapi = { version = "0.3.8", features = ["winnt", "impl-default"] }
[features]
jitdump = ["wasmtime-profiling/jitdump"]
vtune = ["wasmtime-profiling/vtune"]
jitdump = ['libc', 'scroll']
vtune = ['ittapi-rs']
[badges]
maintenance = { status = "actively-developed" }

View File

@@ -6,6 +6,7 @@
use crate::code_memory::CodeMemory;
use crate::debug::create_gdbjit_image;
use crate::link::link_module;
use crate::ProfilingAgent;
use anyhow::{anyhow, Context, Result};
use object::read::File;
use object::write::{Object, StandardSegment};
@@ -19,7 +20,6 @@ use wasmtime_environ::{
ModuleSignature, ModuleTranslation, ModuleTypeIndex, PrimaryMap, SignatureIndex,
StackMapInformation, Tunables, WasmFuncType,
};
use wasmtime_profiling::ProfilingAgent;
use wasmtime_runtime::{GdbJitImageRegistration, InstantiationError, VMFunctionBody, VMTrampoline};
/// An error condition while setting up a wasm instance, be it validation,
@@ -211,18 +211,6 @@ impl CompiledModule {
)))
})?;
// Register GDB JIT images; initialize profiler and load the wasm module.
let dbg_jit_registration = if artifacts.native_debug_info_present {
let bytes = create_gdbjit_image(artifacts.obj.to_vec(), code_range)
.map_err(SetupError::DebugInfo)?;
profiler.module_load(&artifacts.module, &finished_functions, Some(&bytes));
let reg = GdbJitImageRegistration::register(bytes);
Some(reg)
} else {
profiler.module_load(&artifacts.module, &finished_functions, None);
None
};
let finished_functions = FinishedFunctions(finished_functions);
let start = code_range.0 as usize;
let end = start + code_range.1;
@@ -232,17 +220,43 @@ impl CompiledModule {
.ok_or_else(|| anyhow!("failed to find internal data section for wasm module"))?;
let wasm_data = subslice_range(data.data()?, &artifacts.obj);
Ok(Arc::new(Self {
let mut ret = Self {
artifacts,
wasm_data,
code: Arc::new(ModuleCode {
range: (start, end),
code_memory,
dbg_jit_registration,
dbg_jit_registration: None,
}),
finished_functions,
trampolines,
}))
};
ret.register_debug_and_profiling(profiler)?;
Ok(Arc::new(ret))
}
fn register_debug_and_profiling(&mut self, profiler: &dyn ProfilingAgent) -> Result<()> {
// Register GDB JIT images; initialize profiler and load the wasm module.
let dbg_jit_registration = if self.artifacts.native_debug_info_present {
let bytes = create_gdbjit_image(
self.artifacts.obj.to_vec(),
(
self.code.range.0 as *const u8,
self.code.range.1 - self.code.range.0,
),
)
.map_err(SetupError::DebugInfo)?;
profiler.module_load(self, Some(&bytes));
let reg = GdbJitImageRegistration::register(bytes);
Some(reg)
} else {
profiler.module_load(self, None);
None
};
Arc::get_mut(&mut self.code).unwrap().dbg_jit_registration = dbg_jit_registration;
Ok(())
}
/// Extracts `CompilationArtifacts` from the compiled module.

View File

@@ -24,6 +24,7 @@ mod code_memory;
mod debug;
mod instantiate;
mod link;
mod profiling;
mod unwind;
pub use crate::code_memory::CodeMemory;
@@ -31,6 +32,7 @@ pub use crate::instantiate::{
CompilationArtifacts, CompiledModule, ModuleCode, SetupError, SymbolizeContext, TypeTables,
};
pub use crate::link::link_module;
pub use profiling::*;
/// Version number of this crate.
pub const VERSION: &str = env!("CARGO_PKG_VERSION");

View File

@@ -1,40 +1,35 @@
use crate::CompiledModule;
use std::error::Error;
use std::fmt;
use wasmtime_environ::{DefinedFuncIndex, EntityRef, Module, PrimaryMap};
use wasmtime_runtime::VMFunctionBody;
use wasmtime_environ::{DefinedFuncIndex, EntityRef, Module};
cfg_if::cfg_if! {
if #[cfg(all(feature = "jitdump", target_os = "linux"))] {
#[path = "jitdump_linux.rs"]
#[path = "profiling/jitdump_linux.rs"]
mod jitdump;
} else {
#[path = "jitdump_disabled.rs"]
#[path = "profiling/jitdump_disabled.rs"]
mod jitdump;
}
}
cfg_if::cfg_if! {
if #[cfg(all(feature = "vtune", target_os = "linux"))] {
#[path = "vtune_linux.rs"]
#[path = "profiling/vtune_linux.rs"]
mod vtune;
} else {
#[path = "vtune_disabled.rs"]
#[path = "profiling/vtune_disabled.rs"]
mod vtune;
}
}
pub use crate::jitdump::JitDumpAgent;
pub use crate::vtune::VTuneAgent;
pub use jitdump::JitDumpAgent;
pub use vtune::VTuneAgent;
/// Common interface for profiling tools.
pub trait ProfilingAgent: Send + Sync + 'static {
/// Notify the profiler of a new module loaded into memory
fn module_load(
&self,
module: &Module,
functions: &PrimaryMap<DefinedFuncIndex, *mut [VMFunctionBody]>,
dbg_image: Option<&[u8]>,
) -> ();
fn module_load(&self, module: &CompiledModule, dbg_image: Option<&[u8]>) -> ();
}
/// Default agent for unsupported profiling build.
@@ -59,13 +54,7 @@ impl Error for NullProfilerAgentError {
}
impl ProfilingAgent for NullProfilerAgent {
fn module_load(
&self,
_module: &Module,
_functions: &PrimaryMap<DefinedFuncIndex, *mut [VMFunctionBody]>,
_dbg_image: Option<&[u8]>,
) -> () {
}
fn module_load(&self, _module: &CompiledModule, _dbg_image: Option<&[u8]>) -> () {}
}
#[allow(dead_code)]

View File

@@ -1,7 +1,5 @@
use crate::ProfilingAgent;
use crate::{CompiledModule, ProfilingAgent};
use anyhow::{bail, Result};
use wasmtime_environ::{DefinedFuncIndex, Module, PrimaryMap};
use wasmtime_runtime::VMFunctionBody;
/// Interface for driving the creation of jitdump files
#[derive(Debug)]
@@ -21,11 +19,5 @@ impl JitDumpAgent {
}
impl ProfilingAgent for JitDumpAgent {
fn module_load(
&self,
_module: &Module,
_functions: &PrimaryMap<DefinedFuncIndex, *mut [VMFunctionBody]>,
_dbg_image: Option<&[u8]>,
) {
}
fn module_load(&self, _module: &CompiledModule, _dbg_image: Option<&[u8]>) {}
}

View File

@@ -11,7 +11,7 @@
//! sudo perf report -i perf.jit.data -F+period,srcline
//! Note: For descriptive results, the WASM file being executed should contain dwarf debug data
use crate::ProfilingAgent;
use crate::{CompiledModule, ProfilingAgent};
use anyhow::Result;
use object::{Object, ObjectSection};
use scroll::{IOwrite, SizeWith, NATIVE};
@@ -25,8 +25,6 @@ use std::ptr;
use std::sync::Mutex;
use std::{borrow, mem, process};
use target_lexicon::Architecture;
use wasmtime_environ::{DefinedFuncIndex, Module, PrimaryMap};
use wasmtime_runtime::VMFunctionBody;
use object::elf;
@@ -200,16 +198,8 @@ impl JitDumpAgent {
}
impl ProfilingAgent for JitDumpAgent {
fn module_load(
&self,
module: &Module,
functions: &PrimaryMap<DefinedFuncIndex, *mut [VMFunctionBody]>,
dbg_image: Option<&[u8]>,
) {
self.state
.lock()
.unwrap()
.module_load(module, functions, dbg_image);
fn module_load(&self, module: &CompiledModule, dbg_image: Option<&[u8]>) {
self.state.lock().unwrap().module_load(module, dbg_image);
}
}
@@ -295,16 +285,11 @@ impl State {
}
/// Sent when a method is compiled and loaded into memory by the VM.
pub fn module_load(
&mut self,
module: &Module,
functions: &PrimaryMap<DefinedFuncIndex, *mut [VMFunctionBody]>,
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.
for (idx, func) in functions.iter() {
for (idx, func) in module.finished_functions() {
let (addr, len) = unsafe { ((**func).as_ptr() as *const u8, (**func).len()) };
if let Some(img) = &dbg_image {
if let Err(err) = self.dump_from_debug_image(img, "wasm", addr, len, pid, tid) {
@@ -315,7 +300,7 @@ impl State {
}
} else {
let timestamp = self.get_time_stamp();
let name = super::debug_name(module, idx);
let name = super::debug_name(module.module(), idx);
self.dump_code_load_record(&name, addr, len, timestamp, pid, tid);
}
}

View File

@@ -1,7 +1,5 @@
use crate::ProfilingAgent;
use anyhow::{bail, Result};
use wasmtime_environ::{DefinedFuncIndex, Module, PrimaryMap};
use wasmtime_runtime::VMFunctionBody;
/// Interface for driving vtune support
#[derive(Debug)]
@@ -21,11 +19,5 @@ impl VTuneAgent {
}
impl ProfilingAgent for VTuneAgent {
fn module_load(
&self,
_module: &Module,
_functions: &PrimaryMap<DefinedFuncIndex, *mut [VMFunctionBody]>,
_dbg_image: Option<&[u8]>,
) {
}
fn module_load(&self, _module: &crate::CompiledModule, _dbg_image: Option<&[u8]>) {}
}

View File

@@ -7,15 +7,14 @@
//!
//! Note: amplxe-cl is a command-line tool for Vtune which should be installed.
use crate::ProfilingAgent;
use crate::{CompiledModule, ProfilingAgent};
use anyhow::Result;
use core::ptr;
use ittapi_rs::*;
use std::collections::HashMap;
use std::ffi::CString;
use std::sync::{atomic, Mutex};
use wasmtime_environ::{DefinedFuncIndex, Module, PrimaryMap};
use wasmtime_runtime::VMFunctionBody;
use wasmtime_environ::DefinedFuncIndex;
/// Interface for driving the ittapi for VTune support
pub struct VTuneAgent {
@@ -110,36 +109,27 @@ impl State {
}
impl ProfilingAgent for VTuneAgent {
fn module_load(
&self,
module: &Module,
functions: &PrimaryMap<DefinedFuncIndex, *mut [VMFunctionBody]>,
dbg_image: Option<&[u8]>,
) {
self.state
.lock()
.unwrap()
.module_load(module, functions, dbg_image);
fn module_load(&self, module: &CompiledModule, dbg_image: Option<&[u8]>) {
self.state.lock().unwrap().module_load(module, dbg_image);
}
}
impl State {
fn module_load(
&mut self,
module: &Module,
functions: &PrimaryMap<DefinedFuncIndex, *mut [VMFunctionBody]>,
_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);
for (idx, func) in functions.iter() {
for (idx, func) in module.finished_functions() {
let (addr, len) = unsafe { ((**func).as_ptr() as *const u8, (**func).len()) };
let default_filename = "wasm_file";
let default_module_name = String::from("wasm_module");
let module_name = module.name.as_ref().unwrap_or(&default_module_name);
let method_name = super::debug_name(module, idx);
let module_name = module
.module()
.name
.as_ref()
.unwrap_or(&default_module_name);
let method_name = super::debug_name(module.module(), idx);
let method_id = self.get_method_id(global_module_id, idx);
println!(
"Event Load: ({}) {:?}::{:?} Addr:{:?}\n",

View File

@@ -1,36 +0,0 @@
[package]
name = "wasmtime-profiling"
version = "0.29.0"
authors = ["The Wasmtime Project Developers"]
description = "Runtime library support for Wasmtime"
license = "Apache-2.0 WITH LLVM-exception"
categories = ["wasm"]
keywords = ["webassembly", "wasm"]
repository = "https://github.com/bytecodealliance/wasmtime"
edition = "2018"
[dependencies]
anyhow = "1.0"
cfg-if = "1.0"
gimli = { version = "0.25.0", optional = true, default-features = false }
lazy_static = "1.4"
libc = { version = "0.2.60", default-features = false }
scroll = { version = "0.10.1", features = ["derive"], optional = true }
serde = { version = "1.0.99", features = ["derive"] }
target-lexicon = "0.12.0"
wasmtime-environ = { path = "../environ", version = "0.29.0" }
wasmtime-runtime = { path = "../runtime", version = "0.29.0" }
ittapi-rs = { version = "0.1.5", optional = true }
[dependencies.object]
version = "0.26.0"
optional = true
default-features = false
features = ['read_core', 'elf', 'std']
[badges]
maintenance = { status = "actively-developed" }
[features]
jitdump = ['object', 'scroll', 'gimli']
vtune = ['ittapi-rs']

View File

@@ -17,7 +17,6 @@ wasmtime-runtime = { path = "../runtime", version = "0.29.0" }
wasmtime-environ = { path = "../environ", version = "0.29.0" }
wasmtime-jit = { path = "../jit", version = "0.29.0" }
wasmtime-cache = { path = "../cache", version = "0.29.0", optional = true }
wasmtime-profiling = { path = "../profiling", version = "0.29.0" }
wasmtime-fiber = { path = "../fiber", version = "0.29.0", optional = true }
wasmtime-cranelift = { path = "../cranelift", version = "0.29.0", optional = true }
target-lexicon = { version = "0.12.0", default-features = false }

View File

@@ -11,7 +11,7 @@ use wasmparser::WasmFeatures;
#[cfg(feature = "cache")]
use wasmtime_cache::CacheConfig;
use wasmtime_environ::{CompilerBuilder, Tunables};
use wasmtime_profiling::{JitDumpAgent, NullProfilerAgent, ProfilingAgent, VTuneAgent};
use wasmtime_jit::{JitDumpAgent, NullProfilerAgent, ProfilingAgent, VTuneAgent};
use wasmtime_runtime::{
InstanceAllocator, OnDemandInstanceAllocator, PoolingInstanceAllocator, RuntimeMemoryCreator,
};

View File

@@ -49,7 +49,6 @@ const CRATES_TO_PUBLISH: &[&str] = &[
"wasmtime-fiber",
"wasmtime-environ",
"wasmtime-runtime",
"wasmtime-profiling",
"wasmtime-cranelift",
"wasmtime-lightbeam",
"wasmtime-jit",