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:
23
Cargo.lock
generated
23
Cargo.lock
generated
@@ -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"
|
||||
|
||||
@@ -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" }
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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)]
|
||||
@@ -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]>) {}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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]>) {}
|
||||
}
|
||||
@@ -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",
|
||||
@@ -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']
|
||||
@@ -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 }
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -49,7 +49,6 @@ const CRATES_TO_PUBLISH: &[&str] = &[
|
||||
"wasmtime-fiber",
|
||||
"wasmtime-environ",
|
||||
"wasmtime-runtime",
|
||||
"wasmtime-profiling",
|
||||
"wasmtime-cranelift",
|
||||
"wasmtime-lightbeam",
|
||||
"wasmtime-jit",
|
||||
|
||||
Reference in New Issue
Block a user