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

Consolidate platform-specific definitions in Wasmtime #7626

Merged
Merged
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ rustix = { workspace = true, features = ["mm", "param"] }

[dev-dependencies]
# depend again on wasmtime to activate its default features for tests
wasmtime = { workspace = true, features = ['component-model', 'async', 'default', 'winch'] }
wasmtime = { workspace = true, features = ['component-model', 'async', 'default', 'winch', 'debug-builtins'] }
env_logger = { workspace = true }
log = { workspace = true }
filecheck = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion cranelift/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ harness = false

[dependencies]
cfg-if = { workspace = true }
cranelift-codegen = { workspace = true, features = ["disas", "trace-log"] }
cranelift-codegen = { workspace = true, features = ["disas", "trace-log", "timing"] }
cranelift-entity = { workspace = true }
cranelift-interpreter = { workspace = true }
cranelift-reader = { workspace = true }
Expand Down
7 changes: 6 additions & 1 deletion cranelift/codegen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ cranelift-codegen-meta = { path = "meta", version = "0.103.0" }
cranelift-isle = { path = "../isle/isle", version = "=0.103.0" }

[features]
default = ["std", "unwind", "host-arch"]
default = ["std", "unwind", "host-arch", "timing"]

# The "std" feature enables use of libstd. The "core" feature enables use
# of some minimal std-like replacement libraries. At least one of these two
Expand Down Expand Up @@ -114,6 +114,11 @@ isle-errors = ["cranelift-isle/fancy-errors"]
# inspection, rather than inside of target/.
isle-in-source-tree = []

# Enable tracking how long passes take in Cranelift.
#
# Enabled by default.
timing = []

[[bench]]
name = "x64-evex-encoding"
harness = false
122 changes: 74 additions & 48 deletions cranelift/codegen/src/timing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
use core::fmt;
use std::any::Any;
use std::boxed::Box;
use std::cell::{Cell, RefCell};
use std::cell::RefCell;
use std::mem;
use std::time::{Duration, Instant};
use std::time::Duration;

// Each pass that can be timed is predefined with the `define_passes!` macro. Each pass has a
// snake_case name and a plain text description used when printing out the timing report.
Expand Down Expand Up @@ -130,22 +130,6 @@ fn start_pass(pass: Pass) -> Box<dyn Any> {
PROFILER.with(|profiler| profiler.borrow().start_pass(pass))
}

/// A timing token is responsible for timing the currently running pass. Timing starts when it
/// is created and ends when it is dropped.
///
/// Multiple passes can be active at the same time, but they must be started and stopped in a
/// LIFO fashion.
struct DefaultTimingToken {
/// Start time for this pass.
start: Instant,

// Pass being timed by this token.
pass: Pass,

// The previously active pass which will be restored when this token is dropped.
prev: Pass,
}

/// Accumulated timing information for a single pass.
#[derive(Default, Copy, Clone)]
struct PassTime {
Expand Down Expand Up @@ -215,49 +199,91 @@ impl fmt::Display for PassTimes {

// Information about passes in a single thread.
thread_local! {
static CURRENT_PASS: Cell<Pass> = const { Cell::new(Pass::None) };
static PASS_TIME: RefCell<PassTimes> = RefCell::new(Default::default());
}

/// The default profiler. You can get the results using [`take_current`].
pub struct DefaultProfiler;

impl Profiler for DefaultProfiler {
fn start_pass(&self, pass: Pass) -> Box<dyn Any> {
let prev = CURRENT_PASS.with(|p| p.replace(pass));
log::debug!("timing: Starting {}, (during {})", pass, prev);
Box::new(DefaultTimingToken {
start: Instant::now(),
pass,
prev,
})
}
}

/// Dropping a timing token indicated the end of the pass.
impl Drop for DefaultTimingToken {
fn drop(&mut self) {
let duration = self.start.elapsed();
log::debug!("timing: Ending {}: {}ms", self.pass, duration.as_millis());
let old_cur = CURRENT_PASS.with(|p| p.replace(self.prev));
debug_assert_eq!(self.pass, old_cur, "Timing tokens dropped out of order");
PASS_TIME.with(|rc| {
let mut table = rc.borrow_mut();
table.pass[self.pass.idx()].total += duration;
if let Some(parent) = table.pass.get_mut(self.prev.idx()) {
parent.child += duration;
}
})
}
}

/// Take the current accumulated pass timings and reset the timings for the current thread.
///
/// Only applies when [`DefaultProfiler`] is used.
pub fn take_current() -> PassTimes {
PASS_TIME.with(|rc| mem::take(&mut *rc.borrow_mut()))
}

#[cfg(feature = "timing")]
mod enabled {
use super::{DefaultProfiler, Pass, Profiler, PASS_TIME};
use std::any::Any;
use std::boxed::Box;
use std::cell::Cell;
use std::time::Instant;

// Information about passes in a single thread.
thread_local! {
static CURRENT_PASS: Cell<Pass> = const { Cell::new(Pass::None) };
}

impl Profiler for DefaultProfiler {
fn start_pass(&self, pass: Pass) -> Box<dyn Any> {
let prev = CURRENT_PASS.with(|p| p.replace(pass));
log::debug!("timing: Starting {}, (during {})", pass, prev);
Box::new(DefaultTimingToken {
start: Instant::now(),
pass,
prev,
})
}
}

/// A timing token is responsible for timing the currently running pass. Timing starts when it
/// is created and ends when it is dropped.
///
/// Multiple passes can be active at the same time, but they must be started and stopped in a
/// LIFO fashion.
struct DefaultTimingToken {
/// Start time for this pass.
start: Instant,

// Pass being timed by this token.
pass: Pass,

// The previously active pass which will be restored when this token is dropped.
prev: Pass,
}

/// Dropping a timing token indicated the end of the pass.
impl Drop for DefaultTimingToken {
fn drop(&mut self) {
let duration = self.start.elapsed();
log::debug!("timing: Ending {}: {}ms", self.pass, duration.as_millis());
let old_cur = CURRENT_PASS.with(|p| p.replace(self.prev));
debug_assert_eq!(self.pass, old_cur, "Timing tokens dropped out of order");
PASS_TIME.with(|rc| {
let mut table = rc.borrow_mut();
table.pass[self.pass.idx()].total += duration;
if let Some(parent) = table.pass.get_mut(self.prev.idx()) {
parent.child += duration;
}
})
}
}
}

#[cfg(not(feature = "timing"))]
mod disabled {
use super::{DefaultProfiler, Pass, Profiler};
use std::any::Any;
use std::boxed::Box;

impl Profiler for DefaultProfiler {
fn start_pass(&self, _pass: Pass) -> Box<dyn Any> {
Box::new(())
}
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
2 changes: 1 addition & 1 deletion crates/cranelift/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ anyhow = { workspace = true }
log = { workspace = true }
wasmtime-environ = { workspace = true }
cranelift-wasm = { workspace = true }
cranelift-codegen = { workspace = true, features = ["default"] }
cranelift-codegen = { workspace = true, features = ["host-arch"] }
cranelift-frontend = { workspace = true }
cranelift-entity = { workspace = true }
cranelift-native = { workspace = true }
Expand Down
7 changes: 3 additions & 4 deletions crates/jit/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@ workspace = true

[dependencies]
wasmtime-environ = { workspace = true }
wasmtime-jit-debug = { workspace = true, features = [
"perf_jitdump",
], optional = true }
wasmtime-jit-debug = { workspace = true, features = ["perf_jitdump"], optional = true }
wasmtime-runtime = { workspace = true }
target-lexicon = { workspace = true }
anyhow = { workspace = true }
Expand All @@ -44,5 +42,6 @@ features = ["Win32_System_Diagnostics_Debug"]
ittapi = { version = "0.4.0", optional = true }

[features]
profiling = ['dep:wasmtime-jit-debug', 'dep:ittapi']
profiling = ['dep:ittapi', 'dep:wasmtime-jit-debug']
demangle = ['dep:rustc-demangle', 'dep:cpp_demangle']
debug-builtins = ['wasmtime-runtime/debug-builtins']
4 changes: 1 addition & 3 deletions crates/jit/src/code_memory.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
//! Memory management for executable code.

use crate::subslice_range;
use crate::unwind::UnwindRegistration;
use anyhow::{anyhow, bail, Context, Result};
use object::read::{File, Object, ObjectSection};
use object::ObjectSymbol;
use std::mem::ManuallyDrop;
use std::ops::Range;
use wasmtime_environ::obj;
use wasmtime_jit_icache_coherence as icache_coherence;
use wasmtime_runtime::libcalls;
use wasmtime_runtime::MmapVec;
use wasmtime_runtime::{libcalls, MmapVec, UnwindRegistration};

/// Management of executable memory within a `MmapVec`
///
Expand Down
24 changes: 15 additions & 9 deletions crates/jit/src/instantiate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@
//! steps.

use crate::code_memory::CodeMemory;
use crate::debug::create_gdbjit_image;
use crate::profiling::ProfilingAgent;
use anyhow::{bail, Context, Error, Result};
use anyhow::{bail, Error, Result};
use object::write::{Object, SectionId, StandardSegment, WritableBuffer};
use object::SectionKind;
use serde_derive::{Deserialize, Serialize};
Expand All @@ -19,9 +18,7 @@ use wasmtime_environ::{
DefinedFuncIndex, FuncIndex, FunctionLoc, MemoryInitialization, Module, ModuleTranslation,
PrimaryMap, SignatureIndex, StackMapInformation, Tunables, WasmFunctionInfo,
};
use wasmtime_runtime::{
CompiledModuleId, CompiledModuleIdAllocator, GdbJitImageRegistration, MmapVec,
};
use wasmtime_runtime::{CompiledModuleId, CompiledModuleIdAllocator, MmapVec};

/// Secondary in-memory results of function compilation.
#[derive(Serialize, Deserialize)]
Expand Down Expand Up @@ -426,7 +423,8 @@ pub struct CompiledModule {
wasm_to_native_trampolines: Vec<(SignatureIndex, FunctionLoc)>,
meta: Metadata,
code_memory: Arc<CodeMemory>,
dbg_jit_registration: Option<GdbJitImageRegistration>,
#[cfg(feature = "debug-builtins")]
dbg_jit_registration: Option<wasmtime_runtime::GdbJitImageRegistration>,
/// A unique ID used to register this module with the engine.
unique_id: CompiledModuleId,
func_names: Vec<FunctionName>,
Expand Down Expand Up @@ -459,6 +457,7 @@ impl CompiledModule {
module: Arc::new(info.module),
funcs: info.funcs,
wasm_to_native_trampolines: info.wasm_to_native_trampolines,
#[cfg(feature = "debug-builtins")]
dbg_jit_registration: None,
code_memory,
meta: info.meta,
Expand All @@ -471,11 +470,17 @@ impl CompiledModule {
}

fn register_debug_and_profiling(&mut self, profiler: &dyn ProfilingAgent) -> Result<()> {
#[cfg(feature = "debug-builtins")]
if self.meta.native_debug_info_present {
use anyhow::Context;

let text = self.text();
let bytes = create_gdbjit_image(self.mmap().to_vec(), (text.as_ptr(), text.len()))
.context("failed to create jit image for gdb")?;
let reg = GdbJitImageRegistration::register(bytes);
let bytes = crate::debug::create_gdbjit_image(
self.mmap().to_vec(),
(text.as_ptr(), text.len()),
)
.context("failed to create jit image for gdb")?;
let reg = wasmtime_runtime::GdbJitImageRegistration::register(bytes);
self.dbg_jit_registration = Some(reg);
}
profiler.register_module(&self.code_memory, &|addr| {
Expand Down Expand Up @@ -669,6 +674,7 @@ impl CompiledModule {
/// what filename and line number a wasm pc comes from.
#[cfg(feature = "addr2line")]
pub fn symbolize_context(&self) -> Result<Option<SymbolizeContext<'_>>> {
use anyhow::Context;
use gimli::EndianSlice;
if !self.meta.has_wasm_debuginfo {
return Ok(None);
Expand Down
2 changes: 1 addition & 1 deletion crates/jit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
#![deny(missing_docs)]

mod code_memory;
#[cfg(feature = "debug-builtins")]
mod debug;
mod demangling;
mod instantiate;
pub mod profiling;
mod unwind;

pub use crate::code_memory::CodeMemory;
#[cfg(feature = "addr2line")]
Expand Down
14 changes: 0 additions & 14 deletions crates/jit/src/unwind.rs

This file was deleted.

Loading
Loading