Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
alexcrichton committed Nov 12, 2024
1 parent f406347 commit 5ef9e83
Show file tree
Hide file tree
Showing 30 changed files with 799 additions and 579 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,8 @@ jobs:
-p wasmtime --no-default-features --features threads
-p wasmtime --no-default-features --features runtime,threads
-p wasmtime --no-default-features --features cranelift,threads
-p wasmtime --no-default-features --features runtime,signals-based-traps
-p wasmtime --no-default-features --features runtime,gc,component-model,signals-based-traps
-p wasmtime --features incremental-cache
-p wasmtime --all-features
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,7 @@ threads = ["wasmtime-cli-flags/threads"]
gc = ["wasmtime-cli-flags/gc", "wasmtime/gc"]
gc-drc = ["gc", "wasmtime/gc-drc", "wasmtime-cli-flags/gc-drc"]
gc-null = ["gc", "wasmtime/gc-null", "wasmtime-cli-flags/gc-null"]
signals-based-traps = ["wasmtime/signals-based-traps", "wasmtime-cli-flags/signals-based-traps"]

# CLI subcommands for the `wasmtime` executable. See `wasmtime $cmd --help`
# for more information on each subcommand.
Expand Down
1 change: 1 addition & 0 deletions crates/cli-flags/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ gc-drc = ["gc", "wasmtime/gc-drc"]
gc-null = ["gc", "wasmtime/gc-null"]
threads = ["wasmtime/threads"]
memory-protection-keys = ["wasmtime/memory-protection-keys"]
signals-based-traps = ["wasmtime/signals-based-traps"]
54 changes: 34 additions & 20 deletions crates/cli-flags/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -639,39 +639,51 @@ impl CommonOptions {
true => err,
}

if let Some(max) = self
let memory_reservation = self
.opts
.memory_reservation
.or(self.opts.static_memory_maximum_size)
{
config.memory_reservation(max);
.or(self.opts.static_memory_maximum_size);
match_feature! {
["signals-based-traps" : memory_reservation]
size => config.memory_reservation(size),
_ => err,
}

if let Some(enable) = self.opts.static_memory_forced {
config.memory_may_move(!enable);
match_feature! {
["signals-based-traps" : self.opts.static_memory_forced]
enable => config.memory_may_move(!enable),
_ => err,
}
if let Some(enable) = self.opts.memory_may_move {
config.memory_may_move(enable);
match_feature! {
["signals-based-traps" : self.opts.memory_may_move]
enable => config.memory_may_move(enable),
_ => err,
}

if let Some(size) = self
let memory_guard_size = self
.opts
.static_memory_guard_size
.or(self.opts.dynamic_memory_guard_size)
.or(self.opts.memory_guard_size)
{
config.memory_guard_size(size);
.or(self.opts.memory_guard_size);
match_feature! {
["signals-based-traps" : memory_guard_size]
size => config.memory_guard_size(size),
_ => err,
}

if let Some(size) = self
let mem_for_growth = self
.opts
.memory_reservation_for_growth
.or(self.opts.dynamic_memory_reserved_for_growth)
{
config.memory_reservation_for_growth(size);
.or(self.opts.dynamic_memory_reserved_for_growth);
match_feature! {
["signals-based-traps" : mem_for_growth]
size => config.memory_reservation_for_growth(size),
_ => err,
}
if let Some(enable) = self.opts.guard_before_linear_memory {
config.guard_before_linear_memory(enable);
match_feature! {
["signals-based-traps" : self.opts.guard_before_linear_memory]
enable => config.guard_before_linear_memory(enable),
_ => err,
}
if let Some(enable) = self.opts.table_lazy_init {
config.table_lazy_init(enable);
Expand All @@ -691,8 +703,10 @@ impl CommonOptions {
if let Some(enable) = self.opts.memory_init_cow {
config.memory_init_cow(enable);
}
if let Some(enable) = self.opts.signals_based_traps {
config.signals_based_traps(enable);
match_feature! {
["signals-based-traps" : self.opts.signals_based_traps]
enable => config.signals_based_traps(enable),
_ => err,
}
if let Some(enable) = self.codegen.native_unwind_info {
config.native_unwind_info(enable);
Expand Down
3 changes: 3 additions & 0 deletions crates/wasmtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ default = [
'component-model',
'threads',
'std',
'signals-based-traps',
]

# An on-by-default feature enabling runtime compilation of WebAssembly modules
Expand Down Expand Up @@ -315,3 +316,5 @@ memory-protection-keys = ["pooling-allocator"]
# version changes. This is why the re-export is guarded by a feature flag which
# is off by default.
reexport-wasmparser = []

signals-based-traps = []
24 changes: 23 additions & 1 deletion crates/wasmtime/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ impl Config {
async_support: false,
module_version: ModuleVersionStrategy::default(),
parallel_compilation: !cfg!(miri),
memory_init_cow: true,
memory_init_cow: cfg!(feature = "signals-based-traps"),
memory_guaranteed_dense_image_size: 16 << 20,
force_memory_init_memfd: false,
wmemcheck: false,
Expand Down Expand Up @@ -1475,6 +1475,7 @@ impl Config {
///
/// For 32-bit platforms this value defaults to 10MiB. This means that
/// bounds checks will be required on 32-bit platforms.
#[cfg(feature = "signals-based-traps")]
pub fn memory_reservation(&mut self, bytes: u64) -> &mut Self {
self.tunables.memory_reservation = Some(bytes);
self
Expand Down Expand Up @@ -1510,6 +1511,7 @@ impl Config {
/// the memory configuration works at runtime.
///
/// The default value for this option is `true`.
#[cfg(feature = "signals-based-traps")]
pub fn memory_may_move(&mut self, enable: bool) -> &mut Self {
self.tunables.memory_may_move = Some(enable);
self
Expand Down Expand Up @@ -1558,6 +1560,7 @@ impl Config {
/// allows eliminating almost all bounds checks on loads/stores with an
/// immediate offset of less than 2GiB. On 32-bit platforms this defaults to
/// 64KiB.
#[cfg(feature = "signals-based-traps")]
pub fn memory_guard_size(&mut self, bytes: u64) -> &mut Self {
self.tunables.memory_guard_size = Some(bytes);
self
Expand Down Expand Up @@ -1647,6 +1650,7 @@ impl Config {
/// ## Default
///
/// This value defaults to `true`.
#[cfg(feature = "signals-based-traps")]
pub fn guard_before_linear_memory(&mut self, enable: bool) -> &mut Self {
self.tunables.guard_before_linear_memory = Some(enable);
self
Expand Down Expand Up @@ -2034,6 +2038,16 @@ impl Config {
None => Tunables::default_host(),
};

// When signals-based traps are disabled use slightly different defaults
// for tunables to be more amenable to `MallocMemory`. Note that these
// can still be overridden by config options.
if !cfg!(feature = "signals-based-traps") {
tunables.signals_based_traps = false;
tunables.memory_reservation = 0;
tunables.memory_guard_size = 0;
tunables.memory_reservation_for_growth = 1 << 20; // 1MB
}

self.tunables.configure(&mut tunables);

// If we're going to compile with winch, we must use the winch calling convention.
Expand All @@ -2058,6 +2072,13 @@ impl Config {
None
};

if tunables.signals_based_traps && !cfg!(feature = "signals-based-traps") {
bail!("support for signals-based-traps disabled at compile time");
}
if self.memory_init_cow && !cfg!(feature = "signals-based-traps") {
bail!("using CoW requires signals-based-traps to be enabled at compile time");
}

Ok((tunables, features))
}

Expand Down Expand Up @@ -2392,6 +2413,7 @@ impl Config {
/// are enabled by default.
///
/// **Note** Disabling this option is not compatible with the Winch compiler.
#[cfg(feature = "signals-based-traps")]
pub fn signals_based_traps(&mut self, enable: bool) -> &mut Self {
self.tunables.signals_based_traps = Some(enable);
self
Expand Down
2 changes: 2 additions & 0 deletions crates/wasmtime/src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ impl Engine {
// configured. This is the per-program initialization required for
// handling traps, such as configuring signals, vectored exception
// handlers, etc.
#[cfg(feature = "signals-based-traps")]
crate::runtime::vm::init_traps(config.macos_use_mach_ports);
#[cfg(feature = "debug-builtins")]
crate::runtime::vm::debug_builtins::ensure_exported();
Expand Down Expand Up @@ -762,6 +763,7 @@ impl Engine {
/// If other crashes are seen from using this method please feel free to
/// file an issue to update the documentation here with more preconditions
/// that must be met.
#[cfg(feature = "signals-based-traps")]
pub unsafe fn unload_process_handlers(self) {
assert_eq!(Arc::weak_count(&self.inner), 0);
assert_eq!(Arc::strong_count(&self.inner), 1);
Expand Down
4 changes: 1 addition & 3 deletions crates/wasmtime/src/runtime/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ use wasmtime_environ::{
};
mod registry;

pub use registry::{
lookup_code, register_code, unregister_code, ModuleRegistry, RegisteredModuleId,
};
pub use registry::*;

/// A compiled WebAssembly module, ready to be instantiated.
///
Expand Down
1 change: 1 addition & 0 deletions crates/wasmtime/src/runtime/module/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ type GlobalRegistry = BTreeMap<usize, (usize, Arc<CodeMemory>)>;

/// Find which registered region of code contains the given program counter, and
/// what offset that PC is within that module's code.
#[cfg(feature = "signals-based-traps")]
pub fn lookup_code(pc: usize) -> Option<(Arc<CodeMemory>, usize)> {
let all_modules = global_code().read();
let (_end, (start, module)) = all_modules.range(pc..).next()?;
Expand Down
17 changes: 11 additions & 6 deletions crates/wasmtime/src/runtime/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ use crate::runtime::vm::mpk::{self, ProtectionKey, ProtectionMask};
use crate::runtime::vm::{
Backtrace, ExportGlobal, GcRootsList, GcStore, InstanceAllocationRequest, InstanceAllocator,
InstanceHandle, ModuleRuntimeInfo, OnDemandInstanceAllocator, SignalHandler, StoreBox,
StorePtr, VMContext, VMFuncRef, VMGcRef, VMRuntimeLimits, WasmFault,
StorePtr, VMContext, VMFuncRef, VMGcRef, VMRuntimeLimits,
};
use crate::trampoline::VMHostGlobalContext;
use crate::type_registry::RegisteredType;
Expand Down Expand Up @@ -314,7 +314,7 @@ pub struct StoreOpaque {
instances: Vec<StoreInstance>,
#[cfg(feature = "component-model")]
num_component_instances: usize,
signal_handler: Option<Box<SignalHandler<'static>>>,
signal_handler: Option<SignalHandler>,
modules: ModuleRegistry,
func_refs: FuncRefs,
host_globals: Vec<StoreBox<VMHostGlobalContext>>,
Expand Down Expand Up @@ -1520,7 +1520,7 @@ impl StoreOpaque {
}

#[cfg_attr(not(target_os = "linux"), allow(dead_code))] // not used on all platforms
pub fn set_signal_handler(&mut self, handler: Option<Box<SignalHandler<'static>>>) {
pub fn set_signal_handler(&mut self, handler: Option<SignalHandler>) {
self.signal_handler = handler;
}

Expand Down Expand Up @@ -1899,9 +1899,9 @@ impl StoreOpaque {
}

#[inline]
pub fn signal_handler(&self) -> Option<*const SignalHandler<'static>> {
pub fn signal_handler(&self) -> Option<*const SignalHandler> {
let handler = self.signal_handler.as_ref()?;
Some(&**handler as *const _)
Some(handler)
}

#[inline]
Expand Down Expand Up @@ -1968,7 +1968,12 @@ impl StoreOpaque {
/// with spectre mitigations enabled since the hardware fault address is
/// always zero in these situations which means that the trapping context
/// doesn't have enough information to report the fault address.
pub(crate) fn wasm_fault(&self, pc: usize, addr: usize) -> Option<WasmFault> {
#[cfg(feature = "signals-based-traps")]
pub(crate) fn wasm_fault(
&self,
pc: usize,
addr: usize,
) -> Option<crate::runtime::vm::WasmFault> {
// There are a few instances where a "close to zero" pointer is loaded
// and we expect that to happen:
//
Expand Down
1 change: 1 addition & 0 deletions crates/wasmtime/src/runtime/trap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ pub(crate) fn from_runtime_box(
);
(error, None)
}
#[cfg(feature = "signals-based-traps")]
crate::runtime::vm::TrapReason::Jit {
pc,
faulting_addr,
Expand Down
7 changes: 6 additions & 1 deletion crates/wasmtime/src/runtime/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,18 @@
//! throughout the `wasmtime` crate with extra functionality that's only
//! available on Unix.

#[cfg(feature = "signals-based-traps")]
use crate::prelude::*;
use crate::{AsContextMut, Store};
#[cfg(feature = "signals-based-traps")]
use crate::AsContextMut;
use crate::Store;

/// Extensions for the [`Store`] type only available on Unix.
pub trait StoreExt {
// TODO: needs more docs?
/// The signal handler must be
/// [async-signal-safe](http://man7.org/linux/man-pages/man7/signal-safety.7.html).
#[cfg(feature = "signals-based-traps")]
unsafe fn set_signal_handler<H>(&mut self, handler: H)
where
H: 'static
Expand All @@ -26,6 +30,7 @@ pub trait StoreExt {
}

impl<T> StoreExt for Store<T> {
#[cfg(feature = "signals-based-traps")]
unsafe fn set_signal_handler<H>(&mut self, handler: H)
where
H: 'static
Expand Down
8 changes: 5 additions & 3 deletions crates/wasmtime/src/runtime/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ mod table;
mod traphandlers;
mod vmcontext;

mod threads;
pub use self::threads::*;
#[cfg(feature = "threads")]
mod parking_spot;

#[cfg(feature = "debug-builtins")]
pub mod debug_builtins;
Expand All @@ -65,7 +65,9 @@ pub use crate::runtime::vm::instance::{
InstanceLimits, PoolConcurrencyLimitError, PoolingInstanceAllocator,
PoolingInstanceAllocatorConfig,
};
pub use crate::runtime::vm::memory::{Memory, RuntimeLinearMemory, RuntimeMemoryCreator};
pub use crate::runtime::vm::memory::{
Memory, RuntimeLinearMemory, RuntimeMemoryCreator, SharedMemory,
};
pub use crate::runtime::vm::mmap::Mmap;
pub use crate::runtime::vm::mmap_vec::MmapVec;
pub use crate::runtime::vm::mpk::MpkEnabled;
Expand Down
Loading

0 comments on commit 5ef9e83

Please sign in to comment.