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

View File

@@ -13,7 +13,6 @@ edition = "2018"
[dependencies] [dependencies]
wasmtime-environ = { path = "../environ", version = "0.29.0" } wasmtime-environ = { path = "../environ", version = "0.29.0" }
wasmtime-runtime = { path = "../runtime", version = "0.29.0" } wasmtime-runtime = { path = "../runtime", version = "0.29.0" }
wasmtime-profiling = { path = "../profiling", version = "0.29.0" }
region = "2.2.0" region = "2.2.0"
thiserror = "1.0.4" thiserror = "1.0.4"
target-lexicon = { version = "0.12.0", default-features = false } 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"] } object = { version = "0.26.0", default-features = false, features = ["std", "read_core", "elf"] }
serde = { version = "1.0.94", features = ["derive"] } serde = { version = "1.0.94", features = ["derive"] }
addr2line = { version = "0.16.0", default-features = false } 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] [target.'cfg(target_os = "windows")'.dependencies]
winapi = { version = "0.3.8", features = ["winnt", "impl-default"] } winapi = { version = "0.3.8", features = ["winnt", "impl-default"] }
[features] [features]
jitdump = ["wasmtime-profiling/jitdump"] jitdump = ['libc', 'scroll']
vtune = ["wasmtime-profiling/vtune"] vtune = ['ittapi-rs']
[badges] [badges]
maintenance = { status = "actively-developed" } maintenance = { status = "actively-developed" }

View File

@@ -6,6 +6,7 @@
use crate::code_memory::CodeMemory; use crate::code_memory::CodeMemory;
use crate::debug::create_gdbjit_image; use crate::debug::create_gdbjit_image;
use crate::link::link_module; use crate::link::link_module;
use crate::ProfilingAgent;
use anyhow::{anyhow, Context, Result}; use anyhow::{anyhow, Context, Result};
use object::read::File; use object::read::File;
use object::write::{Object, StandardSegment}; use object::write::{Object, StandardSegment};
@@ -19,7 +20,6 @@ use wasmtime_environ::{
ModuleSignature, ModuleTranslation, ModuleTypeIndex, PrimaryMap, SignatureIndex, ModuleSignature, ModuleTranslation, ModuleTypeIndex, PrimaryMap, SignatureIndex,
StackMapInformation, Tunables, WasmFuncType, StackMapInformation, Tunables, WasmFuncType,
}; };
use wasmtime_profiling::ProfilingAgent;
use wasmtime_runtime::{GdbJitImageRegistration, InstantiationError, VMFunctionBody, VMTrampoline}; use wasmtime_runtime::{GdbJitImageRegistration, InstantiationError, VMFunctionBody, VMTrampoline};
/// An error condition while setting up a wasm instance, be it validation, /// 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 finished_functions = FinishedFunctions(finished_functions);
let start = code_range.0 as usize; let start = code_range.0 as usize;
let end = start + code_range.1; 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"))?; .ok_or_else(|| anyhow!("failed to find internal data section for wasm module"))?;
let wasm_data = subslice_range(data.data()?, &artifacts.obj); let wasm_data = subslice_range(data.data()?, &artifacts.obj);
Ok(Arc::new(Self { let mut ret = Self {
artifacts, artifacts,
wasm_data, wasm_data,
code: Arc::new(ModuleCode { code: Arc::new(ModuleCode {
range: (start, end), range: (start, end),
code_memory, code_memory,
dbg_jit_registration, dbg_jit_registration: None,
}), }),
finished_functions, finished_functions,
trampolines, 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. /// Extracts `CompilationArtifacts` from the compiled module.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -7,15 +7,14 @@
//! //!
//! Note: amplxe-cl is a command-line tool for Vtune which should be installed. //! 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 anyhow::Result;
use core::ptr; use core::ptr;
use ittapi_rs::*; use ittapi_rs::*;
use std::collections::HashMap; use std::collections::HashMap;
use std::ffi::CString; use std::ffi::CString;
use std::sync::{atomic, Mutex}; use std::sync::{atomic, Mutex};
use wasmtime_environ::{DefinedFuncIndex, Module, PrimaryMap}; use wasmtime_environ::DefinedFuncIndex;
use wasmtime_runtime::VMFunctionBody;
/// Interface for driving the ittapi for VTune support /// Interface for driving the ittapi for VTune support
pub struct VTuneAgent { pub struct VTuneAgent {
@@ -110,36 +109,27 @@ impl State {
} }
impl ProfilingAgent for VTuneAgent { impl ProfilingAgent for VTuneAgent {
fn module_load( fn module_load(&self, module: &CompiledModule, dbg_image: Option<&[u8]>) {
&self, self.state.lock().unwrap().module_load(module, dbg_image);
module: &Module,
functions: &PrimaryMap<DefinedFuncIndex, *mut [VMFunctionBody]>,
dbg_image: Option<&[u8]>,
) {
self.state
.lock()
.unwrap()
.module_load(module, functions, dbg_image);
} }
} }
impl State { impl State {
fn module_load( fn module_load(&mut self, module: &CompiledModule, _dbg_image: Option<&[u8]>) -> () {
&mut self,
module: &Module,
functions: &PrimaryMap<DefinedFuncIndex, *mut [VMFunctionBody]>,
_dbg_image: Option<&[u8]>,
) -> () {
// Global counter for module ids. // Global counter for module ids.
static MODULE_ID: atomic::AtomicUsize = atomic::AtomicUsize::new(0); static MODULE_ID: atomic::AtomicUsize = atomic::AtomicUsize::new(0);
let global_module_id = MODULE_ID.fetch_add(1, atomic::Ordering::SeqCst); 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 (addr, len) = unsafe { ((**func).as_ptr() as *const u8, (**func).len()) };
let default_filename = "wasm_file"; let default_filename = "wasm_file";
let default_module_name = String::from("wasm_module"); let default_module_name = String::from("wasm_module");
let module_name = module.name.as_ref().unwrap_or(&default_module_name); let module_name = module
let method_name = super::debug_name(module, idx); .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); let method_id = self.get_method_id(global_module_id, idx);
println!( println!(
"Event Load: ({}) {:?}::{:?} Addr:{:?}\n", "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-environ = { path = "../environ", version = "0.29.0" }
wasmtime-jit = { path = "../jit", version = "0.29.0" } wasmtime-jit = { path = "../jit", version = "0.29.0" }
wasmtime-cache = { path = "../cache", version = "0.29.0", optional = true } 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-fiber = { path = "../fiber", version = "0.29.0", optional = true }
wasmtime-cranelift = { path = "../cranelift", 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 } target-lexicon = { version = "0.12.0", default-features = false }

View File

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

View File

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