Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
alexcrichton committed Dec 2, 2023
1 parent 3670f02 commit 5f8b2d3
Show file tree
Hide file tree
Showing 19 changed files with 656 additions and 53 deletions.
28 changes: 28 additions & 0 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ members = [
"examples/fib-debug/wasm",
"examples/wasi/wasm",
"examples/tokio/wasm",
"examples/min-platform",
"examples/min-platform/embedding",
"fuzz",
"winch",
"winch/codegen",
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
5 changes: 4 additions & 1 deletion crates/jit/src/instantiate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use crate::code_memory::CodeMemory;
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 Down Expand Up @@ -472,6 +472,8 @@ 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 = crate::debug::create_gdbjit_image(
self.mmap().to_vec(),
Expand Down Expand Up @@ -672,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
5 changes: 4 additions & 1 deletion crates/runtime/src/sys/custom/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
/// TODO: dox
//! Custom platform support in Wasmtime.
//!
//! TODO: dox
pub mod capi;
pub mod mmap;
pub mod traphandlers;
Expand Down
1 change: 1 addition & 0 deletions crates/runtime/src/sys/unix/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub unsafe fn erase_existing_mapping(ptr: *mut u8, len: usize) -> io::Result<()>
Ok(())
}

#[cfg(any(feature = "pooling-allocator", feature = "async"))]
unsafe fn decommit(addr: *mut u8, len: usize) -> io::Result<()> {
if len == 0 {
return Ok(());
Expand Down
1 change: 1 addition & 0 deletions examples/min-platform/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
libwasmtime-platform.so
15 changes: 15 additions & 0 deletions examples/min-platform/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "min-platform-host"
version.workspace = true
authors.workspace = true
edition.workspace = true
rust-version.workspace = true

[lints]
workspace = true

[dependencies]
anyhow = { workspace = true }
wasmtime = { workspace = true, features = ['cranelift'] }
libloading = "0.7"
object = { workspace = true }
19 changes: 19 additions & 0 deletions examples/min-platform/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/bin/sh

set -ex

cbindgen ../../crates/runtime/src/sys/custom/capi.rs \
--lang C \
--cpp-compat > embedding/wasmtime-platform.h

clang -shared -o libwasmtime-platform.so ./embedding/wasmtime-platform.c

RUSTC_BOOTSTRAP_SYNTHETIC_TARGET=1 \
CARGO_PROFILE_DEV_PANIC=abort \
CARGO_PROFILE_RELEASE_PANIC=abort \
RUSTFLAGS="--cfg=wasmtime_custom_platform -Cforce-frame-pointers" \
cargo +nightly build -Zbuild-std=std,panic_abort \
--manifest-path embedding/Cargo.toml \
--target ./embedding/aarch64-unknown-unknown.json

cargo run
17 changes: 17 additions & 0 deletions examples/min-platform/embedding/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "embedding"
version.workspace = true
authors.workspace = true
edition.workspace = true
rust-version.workspace = true

[lints]
workspace = true

[dependencies]
wasmtime = { workspace = true, features = ['cranelift', 'wat'] }
dlmalloc = "0.2.4"
anyhow = { workspace = true }

[lib]
crate-type = ['cdylib']
16 changes: 16 additions & 0 deletions examples/min-platform/embedding/aarch64-unknown-unknown.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"arch": "aarch64",
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"dynamic-linking": true,
"has-thread-local": true,
"is-builtin": false,
"llvm-target": "aarch64-unknown-linux-gnu",
"max-atomic-width": 64,
"os": "minwasmtime",
"position-independent-executables": true,
"relro-level": "full",
"stack-probes": {
"kind": "inline"
},
"target-pointer-width": "64"
}
Loading

0 comments on commit 5f8b2d3

Please sign in to comment.