Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds perf jitdump support #360

Merged
merged 1 commit into from
Feb 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
416 changes: 295 additions & 121 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ wasmtime-environ = { path = "crates/environ" }
wasmtime-interface-types = { path = "crates/interface-types" }
wasmtime-jit = { path = "crates/jit" }
wasmtime-obj = { path = "crates/obj" }
wasmtime-profiling = { path = "crates/profiling" }
wasmtime-wast = { path = "crates/wast" }
wasmtime-wasi = { path = "crates/wasi" }
wasi-common = { path = "crates/wasi-common" }
Expand Down Expand Up @@ -75,6 +76,7 @@ lightbeam = [
"wasmtime-wast/lightbeam",
"wasmtime/lightbeam",
]
jitdump = ["wasmtime-profiling/jitdump"]
test_programs = ["test-programs/test_programs"]

yurydelendik marked this conversation as resolved.
Show resolved Hide resolved
[badges]
Expand Down
1 change: 1 addition & 0 deletions crates/api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ edition = "2018"
wasmtime-runtime = { path = "../runtime", version = "0.9.0" }
wasmtime-environ = { path = "../environ", version = "0.9.0" }
wasmtime-jit = { path = "../jit", version = "0.9.0" }
wasmtime-profiling = { path = "../profiling" }
wasmparser = "0.51.2"
target-lexicon = { version = "0.10.0", default-features = false }
anyhow = "1.0.19"
Expand Down
1 change: 1 addition & 0 deletions crates/api/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ impl Module {
&mut store.compiler_mut(),
binary,
store.engine().config().debug_info,
store.engine().config().profiler.as_ref(),
)?;

let names = Arc::new(Names {
Expand Down
19 changes: 18 additions & 1 deletion crates/api/src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ use std::cell::RefCell;
use std::fmt;
use std::path::Path;
use std::rc::Rc;
use std::sync::Arc;
use std::sync::{Arc, Mutex};
use wasmparser::{OperatorValidatorConfig, ValidatingParserConfig};
use wasmtime_environ::settings::{self, Configurable};
use wasmtime_environ::CacheConfig;
use wasmtime_jit::{native, CompilationStrategy, Compiler};
use wasmtime_profiling::{JitDumpAgent, ProfilingAgent, ProfilingStrategy};

// Runtime Environment

Expand All @@ -25,6 +26,7 @@ pub struct Config {
pub(crate) debug_info: bool,
pub(crate) strategy: CompilationStrategy,
pub(crate) cache_config: CacheConfig,
pub(crate) profiler: Option<Arc<Mutex<Box<dyn ProfilingAgent + Send>>>>,
}

impl Config {
Expand Down Expand Up @@ -58,6 +60,7 @@ impl Config {
flags,
strategy: CompilationStrategy::Auto,
cache_config: CacheConfig::new_cache_disabled(),
profiler: None,
}
}

Expand Down Expand Up @@ -212,6 +215,20 @@ impl Config {
Ok(self)
}

/// Creates a default profiler based on the profiling strategy choosen
///
/// Profiler creation calls the type's default initializer where the purpose is
/// really just to put in place the type used for profiling.
pub fn profiler(&mut self, profile: ProfilingStrategy) -> Result<&mut Self> {
match profile {
ProfilingStrategy::JitDumpProfiler => {
self.profiler = { Some(Arc::new(Mutex::new(Box::new(JitDumpAgent::default())))) }
}
_ => self.profiler = { None },
};
Ok(self)
}

/// Configures whether the debug verifier of Cranelift is enabled or not.
///
/// When Cranelift is used as a code generation backend this will configure
Expand Down
1 change: 1 addition & 0 deletions crates/jit/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ cranelift-frontend = "0.58.0"
wasmtime-environ = { path = "../environ", version = "0.9.0" }
wasmtime-runtime = { path = "../runtime", version = "0.9.0" }
wasmtime-debug = { path = "../debug", version = "0.9.0" }
wasmtime-profiling = { path = "../profiling" }
region = "2.0.0"
thiserror = "1.0.4"
target-lexicon = { version = "0.10.0", default-features = false }
Expand Down
19 changes: 19 additions & 0 deletions crates/jit/src/code_memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use region;
use std::mem::ManuallyDrop;
use std::{cmp, mem};
use wasmtime_environ::{Compilation, CompiledFunction};
use wasmtime_profiling::ProfilingAgent;
use wasmtime_runtime::{Mmap, VMFunctionBody};

struct CodeMemoryEntry {
Expand Down Expand Up @@ -230,4 +231,22 @@ impl CodeMemory {

Ok(())
}

/// Calls the module_load for a given ProfilerAgent. Includes
/// all memory address and length for the given module.
/// TODO: Properly handle the possibilities of multiple mmapped regions
/// which may, amongst other things, influence being more specific about
/// the module name.
pub fn profiler_module_load(
&mut self,
profiler: &mut Box<dyn ProfilingAgent + Send>,
module_name: &str,
dbg_image: Option<&[u8]>,
) -> () {
for CodeMemoryEntry { mmap: m, table: _t } in &mut self.entries {
if m.len() > 0 {
profiler.module_load(module_name, m.as_ptr(), m.len(), dbg_image);
}
}
}
}
11 changes: 11 additions & 0 deletions crates/jit/src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use wasmtime_environ::{
Compiler as _C, FunctionBodyData, Module, ModuleMemoryOffset, ModuleVmctxInfo, Relocations,
Traps, Tunables, VMOffsets,
};
use wasmtime_profiling::ProfilingAgent;
use wasmtime_runtime::{
InstantiationError, SignatureRegistry, TrapRegistration, TrapRegistry, VMFunctionBody,
VMSharedSignatureIndex,
Expand Down Expand Up @@ -235,6 +236,16 @@ impl Compiler {
self.code_memory.publish();
}

pub(crate) fn profiler_module_load(
&mut self,
profiler: &mut Box<dyn ProfilingAgent + Send>,
module_name: &str,
dbg_image: Option<&[u8]>,
) -> () {
self.code_memory
.profiler_module_load(profiler, module_name, dbg_image);
}

/// Shared signature registry.
pub fn signatures(&self) -> &SignatureRegistry {
&self.signatures
Expand Down
28 changes: 24 additions & 4 deletions crates/jit/src/instantiate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ use crate::link::link_module;
use crate::resolver::Resolver;
use std::io::Write;
use std::rc::Rc;
use std::sync::Arc;
use std::sync::{Arc, Mutex};
use thiserror::Error;
use wasmtime_debug::read_debuginfo;
use wasmtime_environ::entity::{BoxedSlice, PrimaryMap};
use wasmtime_environ::wasm::{DefinedFuncIndex, SignatureIndex};
use wasmtime_environ::{
CompileError, DataInitializer, DataInitializerLocation, Module, ModuleEnvironment,
};
use wasmtime_profiling::ProfilingAgent;
use wasmtime_runtime::{
GdbJitImageRegistration, InstanceHandle, InstantiationError, TrapRegistration, VMFunctionBody,
VMSharedSignatureIndex,
Expand Down Expand Up @@ -61,6 +62,7 @@ impl<'data> RawCompiledModule<'data> {
compiler: &mut Compiler,
data: &'data [u8],
debug_info: bool,
profiler: Option<&Arc<Mutex<Box<dyn ProfilingAgent + Send>>>>,
) -> Result<Self, SetupError> {
let environ = ModuleEnvironment::new(compiler.frontend_config(), compiler.tunables());

Expand Down Expand Up @@ -103,6 +105,21 @@ impl<'data> RawCompiledModule<'data> {
// Make all code compiled thus far executable.
compiler.publish_compiled_code();

// Initialize profiler and load the wasm module
match profiler {
Some(_) => {
let region_name = String::from("wasm_module");
let mut profiler = profiler.unwrap().lock().unwrap();
match &dbg_image {
Some(dbg) => {
compiler.profiler_module_load(&mut profiler, &region_name, Some(&dbg))
}
_ => compiler.profiler_module_load(&mut profiler, &region_name, None),
};
}
_ => (),
};

let dbg_jit_registration = if let Some(img) = dbg_image {
let mut bytes = Vec::new();
bytes.write_all(&img).expect("all written");
Expand Down Expand Up @@ -139,8 +156,9 @@ impl CompiledModule {
compiler: &mut Compiler,
data: &'data [u8],
debug_info: bool,
profiler: Option<&Arc<Mutex<Box<dyn ProfilingAgent + Send>>>>,
) -> Result<Self, SetupError> {
let raw = RawCompiledModule::<'data>::new(compiler, data, debug_info)?;
let raw = RawCompiledModule::<'data>::new(compiler, data, debug_info, profiler)?;

Ok(Self::from_parts(
raw.module,
Expand Down Expand Up @@ -246,7 +264,7 @@ impl OwnedDataInitializer {

/// Create a new wasm instance by compiling the wasm module in `data` and instatiating it.
///
/// This is equivalent to createing a `CompiledModule` and calling `instantiate()` on it,
/// This is equivalent to creating a `CompiledModule` and calling `instantiate()` on it,
/// but avoids creating an intermediate copy of the data initializers.
///
/// # Unsafety
Expand All @@ -258,7 +276,9 @@ pub unsafe fn instantiate(
data: &[u8],
resolver: &mut dyn Resolver,
debug_info: bool,
profiler: Option<&Arc<Mutex<Box<dyn ProfilingAgent + Send>>>>,
) -> Result<InstanceHandle, SetupError> {
let instance = CompiledModule::new(compiler, data, debug_info)?.instantiate(resolver)?;
let instance =
CompiledModule::new(compiler, data, debug_info, profiler)?.instantiate(resolver)?;
Ok(instance)
}
27 changes: 27 additions & 0 deletions crates/profiling/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[package]
name = "wasmtime-profiling"
version = "0.1.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"
readme = "README.md"
edition = "2018"

[dependencies]
libc = { version = "0.2.60", default-features = false }
goblin = "0.0.24"
serde = { version = "1.0.99", features = ["derive"] }
scroll = "0.9.2"
gimli = "0.19.0"
object = "0.12.0"
target-lexicon = "0.4.0"
lazy_static = "1.4"

[badges]
maintenance = { status = "actively-developed" }

[features]
jitdump = []
Loading