From 3b106be90dc09e36e3fdc10b1c9a5779a96c7d72 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Wed, 24 May 2023 13:52:28 +0200 Subject: [PATCH 1/4] Changed tunables to have a VMConfig settings (with only stack size for now) --- lib/api/src/sys/externals/function.rs | 5 ++++- lib/api/src/sys/mod.rs | 2 ++ lib/api/src/sys/module.rs | 8 ++++---- lib/api/src/sys/tunables.rs | 7 ++++++- lib/api/src/sys/typed_function.rs | 6 ++++++ lib/api/src/vm.rs | 2 +- lib/compiler/src/engine/artifact.rs | 5 +++-- lib/compiler/src/engine/tunables.rs | 14 +++++++++++++- lib/vm/src/instance/mod.rs | 8 +++++--- lib/vm/src/trap/mod.rs | 2 +- lib/vm/src/trap/traphandlers.rs | 22 ++++++++++++++-------- 11 files changed, 59 insertions(+), 22 deletions(-) diff --git a/lib/api/src/sys/externals/function.rs b/lib/api/src/sys/externals/function.rs index 61b59236395..5124893af1f 100644 --- a/lib/api/src/sys/externals/function.rs +++ b/lib/api/src/sys/externals/function.rs @@ -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, diff --git a/lib/api/src/sys/mod.rs b/lib/api/src/sys/mod.rs index 2fa411f8e5a..0a0a1d5345c 100644 --- a/lib/api/src/sys/mod.rs +++ b/lib/api/src/sys/mod.rs @@ -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; diff --git a/lib/api/src/sys/module.rs b/lib/api/src/sys/module.rs index 287b92ce9b3..5ea0c83f6d2 100644 --- a/lib/api/src/sys/module.rs +++ b/lib/api/src/sys/module.rs @@ -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(), @@ -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) } diff --git a/lib/api/src/sys/tunables.rs b/lib/api/src/sys/tunables.rs index d5ef8b70704..914a39806b8 100644 --- a/lib/api/src/sys/tunables.rs +++ b/lib/api/src/sys/tunables.rs @@ -15,7 +15,7 @@ mod tests { use wasmer_types::{MemoryType, Pages, WASM_PAGE_SIZE}; use wasmer_vm::{ LinearMemory, MemoryError, MemoryStyle, TableStyle, VMMemory, VMMemoryDefinition, VMTable, - VMTableDefinition, + VMTableDefinition, VMConfig, }; #[test] @@ -206,6 +206,11 @@ mod tests { ) -> Result { VMTable::from_definition(ty, style, vm_definition_location) } + + // Will use a very small stack size of 16kb, not the 1Mb default + fn vmconfig(&self) -> &wasmer_vm::VMConfig { + &VMConfig { wasm_stack_size: Some(16*1024) } + } } #[test] diff --git a/lib/api/src/sys/typed_function.rs b/lib/api/src/sys/typed_function.rs index dd5f60e3378..22508e223f9 100644 --- a/lib/api/src/sys/typed_function.rs +++ b/lib/api/src/sys/typed_function.rs @@ -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, @@ -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, diff --git a/lib/api/src/vm.rs b/lib/api/src/vm.rs index 2b0ce0664d3..2347c0ba963 100644 --- a/lib/api/src/vm.rs +++ b/lib/api/src/vm.rs @@ -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}; diff --git a/lib/compiler/src/engine/artifact.rs b/lib/compiler/src/engine/artifact.rs index 9f96a47f454..e4a6380900b 100644 --- a/lib/compiler/src/engine/artifact.rs +++ b/lib/compiler/src/engine/artifact.rs @@ -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, @@ -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> { @@ -569,7 +570,7 @@ impl Artifact { }) .collect::>(); handle - .finish_instantiation(trap_handler, &data_initializers) + .finish_instantiation(config, trap_handler, &data_initializers) .map_err(InstantiationError::Start) } diff --git a/lib/compiler/src/engine/tunables.rs b/lib/compiler/src/engine/tunables.rs index 945908a18cb..266c3bdaf87 100644 --- a/lib/compiler/src/engine/tunables.rs +++ b/lib/compiler/src/engine/tunables.rs @@ -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 @@ -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. diff --git a/lib/vm/src/instance/mod.rs b/lib/vm/src/instance/mod.rs index fe327c3fecc..3512056593a 100644 --- a/lib/vm/src/instance/mod.rs +++ b/lib/vm/src/instance/mod.rs @@ -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; @@ -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 { @@ -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) @@ -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> { @@ -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(()) } diff --git a/lib/vm/src/trap/mod.rs b/lib/vm/src/trap/mod.rs index a9c31aeae96..b77ca6ef719 100644 --- a/lib/vm/src/trap/mod.rs +++ b/lib/vm/src/trap/mod.rs @@ -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; diff --git a/lib/vm/src/trap/traphandlers.rs b/lib/vm/src/trap/traphandlers.rs index 10e8a352841..47a8ad904a7 100644 --- a/lib/vm/src/trap/traphandlers.rs +++ b/lib/vm/src/trap/traphandlers.rs @@ -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, +} + // 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 @@ -613,12 +620,13 @@ pub unsafe fn resume_panic(payload: Box) -> ! { /// 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); @@ -633,6 +641,7 @@ pub unsafe fn wasmer_call_trampoline( /// Highly unsafe since `closure` won't have any dtors run. pub unsafe fn catch_traps( trap_handler: Option<*const TrapHandlerFn<'static>>, + config: &VMConfig, closure: F, ) -> Result where @@ -640,13 +649,10 @@ where { // 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: From 7651e2de3838d1db96cee6bced70349028d4145b Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Wed, 24 May 2023 14:05:45 +0200 Subject: [PATCH 2/4] Fixed linter --- lib/api/src/sys/tunables.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/api/src/sys/tunables.rs b/lib/api/src/sys/tunables.rs index 914a39806b8..02eac4c167c 100644 --- a/lib/api/src/sys/tunables.rs +++ b/lib/api/src/sys/tunables.rs @@ -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, VMConfig, + LinearMemory, MemoryError, MemoryStyle, TableStyle, VMConfig, VMMemory, VMMemoryDefinition, + VMTable, VMTableDefinition, }; #[test] @@ -209,7 +209,9 @@ mod tests { // Will use a very small stack size of 16kb, not the 1Mb default fn vmconfig(&self) -> &wasmer_vm::VMConfig { - &VMConfig { wasm_stack_size: Some(16*1024) } + &VMConfig { + wasm_stack_size: Some(16 * 1024), + } } } From 257526089f7cb02da4ac7a30dfa6d19219994b26 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Wed, 24 May 2023 14:19:40 +0200 Subject: [PATCH 3/4] Export VMConfig in vm mod of api --- lib/api/src/sys/mod.rs | 4 ++-- lib/api/src/sys/tunables.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/api/src/sys/mod.rs b/lib/api/src/sys/mod.rs index 0a0a1d5345c..67c26f5474e 100644 --- a/lib/api/src/sys/mod.rs +++ b/lib/api/src/sys/mod.rs @@ -28,8 +28,8 @@ pub(crate) mod vm { //! The `vm` module re-exports wasmer-vm types. use wasmer_vm::InternalStoreHandle; pub(crate) use wasmer_vm::{ - VMExtern, VMExternRef, VMFuncRef, VMFunction, VMFunctionBody, VMFunctionEnvironment, - VMGlobal, VMInstance, VMMemory, VMTable, VMTrampoline, + VMConfig, VMExtern, VMExternRef, VMFuncRef, VMFunction, VMFunctionBody, + VMFunctionEnvironment, VMGlobal, VMInstance, VMMemory, VMTable, VMTrampoline, }; pub(crate) type VMExternTable = InternalStoreHandle; diff --git a/lib/api/src/sys/tunables.rs b/lib/api/src/sys/tunables.rs index 02eac4c167c..6060139395a 100644 --- a/lib/api/src/sys/tunables.rs +++ b/lib/api/src/sys/tunables.rs @@ -208,7 +208,7 @@ mod tests { } // Will use a very small stack size of 16kb, not the 1Mb default - fn vmconfig(&self) -> &wasmer_vm::VMConfig { + fn vmconfig(&self) -> &crate::vm::VMConfig { &VMConfig { wasm_stack_size: Some(16 * 1024), } From de9e9a8cea2b8ce99e173da944f3c874495da9e2 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Wed, 24 May 2023 14:50:22 +0200 Subject: [PATCH 4/4] Fixed linter --- lib/api/src/sys/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/api/src/sys/mod.rs b/lib/api/src/sys/mod.rs index 67c26f5474e..0a0a1d5345c 100644 --- a/lib/api/src/sys/mod.rs +++ b/lib/api/src/sys/mod.rs @@ -28,8 +28,8 @@ pub(crate) mod vm { //! The `vm` module re-exports wasmer-vm types. use wasmer_vm::InternalStoreHandle; pub(crate) use wasmer_vm::{ - VMConfig, VMExtern, VMExternRef, VMFuncRef, VMFunction, VMFunctionBody, - VMFunctionEnvironment, VMGlobal, VMInstance, VMMemory, VMTable, VMTrampoline, + VMExtern, VMExternRef, VMFuncRef, VMFunction, VMFunctionBody, VMFunctionEnvironment, + VMGlobal, VMInstance, VMMemory, VMTable, VMTrampoline, }; pub(crate) type VMExternTable = InternalStoreHandle;