Skip to content

Commit

Permalink
Merge pull request #3904 from wasmerio/feat_tunables_stacksize
Browse files Browse the repository at this point in the history
Changed tunables to have a VMConfig settings
  • Loading branch information
syrusakbary authored May 24, 2023
2 parents 1c2a4b0 + de9e9a8 commit 2daaa78
Show file tree
Hide file tree
Showing 11 changed files with 62 additions and 23 deletions.
5 changes: 4 additions & 1 deletion lib/api/src/sys/externals/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,10 +271,13 @@ impl Function {
let mut r;
// TODO: This loop is needed for asyncify. It will be refactored with https://github.com/wasmerio/wasmer/issues/3451
loop {
let vm_function = self.handle.get(store.as_store_ref().objects());
let storeref = store.as_store_ref();
let vm_function = self.handle.get(storeref.objects());
let config = storeref.engine().tunables().vmconfig();
r = unsafe {
wasmer_call_trampoline(
store.as_store_ref().signal_handler(),
config,
vm_function.anyfunc.as_ptr().as_ref().vmctx,
trampoline,
vm_function.anyfunc.as_ptr().as_ref().func_ptr,
Expand Down
2 changes: 2 additions & 0 deletions lib/api/src/sys/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ pub use wasmer_compiler_llvm::{LLVMOptLevel, LLVM};
#[cfg(feature = "singlepass")]
pub use wasmer_compiler_singlepass::Singlepass;

pub use wasmer_vm::VMConfig;

pub(crate) mod vm {
//! The `vm` module re-exports wasmer-vm types.
use wasmer_vm::InternalStoreHandle;
Expand Down
8 changes: 4 additions & 4 deletions lib/api/src/sys/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,10 @@ impl Module {
return Err(InstantiationError::DifferentStores);
}
}
let signal_handler = store.as_store_ref().signal_handler();
let mut store_mut = store.as_store_mut();
let (engine, objects) = store_mut.engine_and_objects_mut();
let config = engine.tunables().vmconfig();
unsafe {
let mut instance_handle = self.artifact.instantiate(
engine.tunables(),
Expand All @@ -149,10 +151,8 @@ impl Module {
// of this steps traps, we still need to keep the instance alive
// as some of the Instance elements may have placed in other
// instance tables.
self.artifact.finish_instantiation(
store.as_store_ref().signal_handler(),
&mut instance_handle,
)?;
self.artifact
.finish_instantiation(config, signal_handler, &mut instance_handle)?;

Ok(instance_handle)
}
Expand Down
11 changes: 9 additions & 2 deletions lib/api/src/sys/tunables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ mod tests {
use wasmer_compiler::Tunables;
use wasmer_types::{MemoryType, Pages, WASM_PAGE_SIZE};
use wasmer_vm::{
LinearMemory, MemoryError, MemoryStyle, TableStyle, VMMemory, VMMemoryDefinition, VMTable,
VMTableDefinition,
LinearMemory, MemoryError, MemoryStyle, TableStyle, VMConfig, VMMemory, VMMemoryDefinition,
VMTable, VMTableDefinition,
};

#[test]
Expand Down Expand Up @@ -206,6 +206,13 @@ mod tests {
) -> Result<VMTable, String> {
VMTable::from_definition(ty, style, vm_definition_location)
}

// Will use a very small stack size of 16kb, not the 1Mb default
fn vmconfig(&self) -> &crate::vm::VMConfig {
&VMConfig {
wasm_stack_size: Some(16 * 1024),
}
}
}

#[test]
Expand Down
6 changes: 6 additions & 0 deletions lib/api/src/sys/typed_function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,12 @@ macro_rules! impl_native_traits {

let mut r;
loop {
let storeref = store.as_store_ref();
let config = storeref.engine().tunables().vmconfig();
r = unsafe {
wasmer_vm::wasmer_call_trampoline(
store.as_store_ref().signal_handler(),
config,
anyfunc.vmctx,
anyfunc.call_trampoline,
anyfunc.func_ptr,
Expand Down Expand Up @@ -128,9 +131,12 @@ macro_rules! impl_native_traits {

let mut r;
loop {
let storeref = store.as_store_ref();
let config = storeref.engine().tunables().vmconfig();
r = unsafe {
wasmer_vm::wasmer_call_trampoline(
store.as_store_ref().signal_handler(),
config,
anyfunc.vmctx,
anyfunc.call_trampoline,
anyfunc.func_ptr,
Expand Down
2 changes: 1 addition & 1 deletion lib/api/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub(crate) use crate::sys::vm::{
pub use crate::js::vm::{VMFunction, VMGlobal, VMMemory, VMSharedMemory, VMTable};

#[cfg(feature = "sys")]
pub use wasmer_vm::{VMFunction, VMGlobal, VMMemory, VMSharedMemory, VMTable};
pub use wasmer_vm::{VMConfig, VMFunction, VMGlobal, VMMemory, VMSharedMemory, VMTable};

#[cfg(feature = "jsc")]
pub use crate::jsc::vm::{VMFunction, VMGlobal, VMMemory, VMSharedMemory, VMTable};
Expand Down
5 changes: 3 additions & 2 deletions lib/compiler/src/engine/artifact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use wasmer_types::{
};
use wasmer_types::{SerializableModule, SerializeError};
use wasmer_vm::{FunctionBodyPtr, MemoryStyle, TableStyle, VMSharedSignatureIndex, VMTrampoline};
use wasmer_vm::{InstanceAllocator, StoreObjects, TrapHandlerFn, VMExtern, VMInstance};
use wasmer_vm::{InstanceAllocator, StoreObjects, TrapHandlerFn, VMConfig, VMExtern, VMInstance};

pub struct AllocatedArtifact {
finished_functions: BoxedSlice<LocalFunctionIndex, FunctionBodyPtr>,
Expand Down Expand Up @@ -557,6 +557,7 @@ impl Artifact {
#[allow(clippy::result_large_err)]
pub unsafe fn finish_instantiation(
&self,
config: &VMConfig,
trap_handler: Option<*const TrapHandlerFn<'static>>,
handle: &mut VMInstance,
) -> Result<(), InstantiationError> {
Expand All @@ -569,7 +570,7 @@ impl Artifact {
})
.collect::<Vec<_>>();
handle
.finish_instantiation(trap_handler, &data_initializers)
.finish_instantiation(config, trap_handler, &data_initializers)
.map_err(InstantiationError::Start)
}

Expand Down
14 changes: 13 additions & 1 deletion lib/compiler/src/engine/tunables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use wasmer_types::{
};
use wasmer_vm::{InternalStoreHandle, MemoryError, StoreObjects};
use wasmer_vm::{MemoryStyle, TableStyle};
use wasmer_vm::{VMGlobal, VMMemory, VMTable};
use wasmer_vm::{VMConfig, VMGlobal, VMMemory, VMTable};
use wasmer_vm::{VMMemoryDefinition, VMTableDefinition};

/// An engine delegates the creation of memories, tables, and globals
Expand Down Expand Up @@ -144,6 +144,18 @@ pub trait Tunables {

Ok(vmctx_globals)
}

/// Get the VMConfig for this tunables
/// Currently, VMConfig have optional Stack size
/// If wasm_stack_size is left to None (the default value)
/// then the global stack size will be use
/// Else the defined stack size will be used. Size is in byte
/// and the value might be rounded to sane value is needed.
fn vmconfig(&self) -> &VMConfig {
&VMConfig {
wasm_stack_size: None,
}
}
}

/// Tunable parameters for WebAssembly compilation.
Expand Down
8 changes: 5 additions & 3 deletions lib/vm/src/instance/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use crate::vmcontext::{
};
use crate::{FunctionBodyPtr, MaybeInstanceOwned, TrapHandlerFn, VMFunctionBody};
use crate::{LinearMemory, NotifyLocation};
use crate::{VMFuncRef, VMFunction, VMGlobal, VMMemory, VMTable};
use crate::{VMConfig, VMFuncRef, VMFunction, VMGlobal, VMMemory, VMTable};
pub use allocator::InstanceAllocator;
use memoffset::offset_of;
use more_asserts::assert_lt;
Expand Down Expand Up @@ -326,6 +326,7 @@ impl Instance {
/// Invoke the WebAssembly start function of the instance, if one is present.
fn invoke_start_function(
&self,
config: &VMConfig,
trap_handler: Option<*const TrapHandlerFn<'static>>,
) -> Result<(), Trap> {
let start_index = match self.module.start_function {
Expand Down Expand Up @@ -356,7 +357,7 @@ impl Instance {

// Make the call.
unsafe {
catch_traps(trap_handler, || {
catch_traps(trap_handler, config, || {
mem::transmute::<*const VMFunctionBody, unsafe extern "C" fn(VMFunctionContext)>(
callee_address,
)(callee_vmctx)
Expand Down Expand Up @@ -1143,6 +1144,7 @@ impl VMInstance {
/// Only safe to call immediately after instantiation.
pub unsafe fn finish_instantiation(
&mut self,
config: &VMConfig,
trap_handler: Option<*const TrapHandlerFn<'static>>,
data_initializers: &[DataInitializer<'_>],
) -> Result<(), Trap> {
Expand All @@ -1154,7 +1156,7 @@ impl VMInstance {

// The WebAssembly spec specifies that the start function is
// invoked automatically at instantiation time.
instance.invoke_start_function(trap_handler)?;
instance.invoke_start_function(config, trap_handler)?;
Ok(())
}

Expand Down
2 changes: 1 addition & 1 deletion lib/vm/src/trap/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ mod traphandlers;
pub use trap::Trap;
pub use traphandlers::{
catch_traps, on_host_stack, raise_lib_trap, raise_user_trap, set_stack_size,
wasmer_call_trampoline, TrapHandlerFn,
wasmer_call_trampoline, TrapHandlerFn, VMConfig,
};
pub use traphandlers::{init_traps, resume_panic};
pub use wasmer_types::TrapCode;
22 changes: 14 additions & 8 deletions lib/vm/src/trap/traphandlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ use std::sync::atomic::{compiler_fence, AtomicPtr, AtomicUsize, Ordering};
use std::sync::{Mutex, Once};
use wasmer_types::TrapCode;

/// Configuration for the the runtime VM
/// Currently only the stack size is configurable
pub struct VMConfig {
/// Optionnal stack size (in byte) of the VM. Value lower than 8K will be rounded to 8K.
pub wasm_stack_size: Option<usize>,
}

// TrapInformation can be stored in the "Undefined Instruction" itself.
// On x86_64, 0xC? select a "Register" for the Mod R/M part of "ud1" (so with no other bytes after)
// On Arm64, the udf alows for a 16bits values, so we'll use the same 0xC? to store the trapinfo
Expand Down Expand Up @@ -613,12 +620,13 @@ pub unsafe fn resume_panic(payload: Box<dyn Any + Send>) -> ! {
/// function pointers.
pub unsafe fn wasmer_call_trampoline(
trap_handler: Option<*const TrapHandlerFn<'static>>,
config: &VMConfig,
vmctx: VMFunctionContext,
trampoline: VMTrampoline,
callee: *const VMFunctionBody,
values_vec: *mut u8,
) -> Result<(), Trap> {
catch_traps(trap_handler, || {
catch_traps(trap_handler, config, || {
mem::transmute::<_, extern "C" fn(VMFunctionContext, *const VMFunctionBody, *mut u8)>(
trampoline,
)(vmctx, callee, values_vec);
Expand All @@ -633,20 +641,18 @@ pub unsafe fn wasmer_call_trampoline(
/// Highly unsafe since `closure` won't have any dtors run.
pub unsafe fn catch_traps<F, R>(
trap_handler: Option<*const TrapHandlerFn<'static>>,
config: &VMConfig,
closure: F,
) -> Result<R, Trap>
where
F: FnOnce() -> R,
{
// Ensure that per-thread initialization is done.
lazy_per_thread_init()?;

on_wasm_stack(
DEFAULT_STACK_SIZE.load(Ordering::Relaxed),
trap_handler,
closure,
)
.map_err(UnwindReason::into_trap)
let stack_size = config
.wasm_stack_size
.unwrap_or_else(|| DEFAULT_STACK_SIZE.load(Ordering::Relaxed));
on_wasm_stack(stack_size, trap_handler, closure).map_err(UnwindReason::into_trap)
}

// We need two separate thread-local variables here:
Expand Down

0 comments on commit 2daaa78

Please sign in to comment.