172004aadSNick Fitzgerald use super::{ 2f8177c20SAlex Crichton InstanceAllocationRequest, InstanceAllocator, MemoryAllocationIndex, TableAllocationIndex, 372004aadSNick Fitzgerald }; 481a89169SAlex Crichton use crate::prelude::*; 590ac295eSAlex Crichton use crate::runtime::vm::CompiledModuleId; 672004aadSNick Fitzgerald use crate::runtime::vm::instance::RuntimeMemoryCreator; 772004aadSNick Fitzgerald use crate::runtime::vm::memory::{DefaultMemoryCreator, Memory}; 872004aadSNick Fitzgerald use crate::runtime::vm::mpk::ProtectionKey; 972004aadSNick Fitzgerald use crate::runtime::vm::table::Table; 1081a89169SAlex Crichton use alloc::sync::Arc; 1182ebbd5dSNick Fitzgerald use core::future::Future; 1282ebbd5dSNick Fitzgerald use core::pin::Pin; 13e1f50aadSAlex Crichton use wasmtime_environ::{DefinedMemoryIndex, DefinedTableIndex, HostPtr, Module, VMOffsets}; 1472004aadSNick Fitzgerald 1572004aadSNick Fitzgerald #[cfg(feature = "gc")] 1672004aadSNick Fitzgerald use crate::runtime::vm::{GcHeap, GcHeapAllocationIndex, GcRuntime}; 1772004aadSNick Fitzgerald 1872004aadSNick Fitzgerald #[cfg(feature = "async")] 1972004aadSNick Fitzgerald use wasmtime_fiber::RuntimeFiberStackCreator; 2072004aadSNick Fitzgerald 2172004aadSNick Fitzgerald #[cfg(feature = "component-model")] 2272004aadSNick Fitzgerald use wasmtime_environ::{ 2372004aadSNick Fitzgerald StaticModuleIndex, 2490ac295eSAlex Crichton component::{Component, VMComponentOffsets}, 2572004aadSNick Fitzgerald }; 2672004aadSNick Fitzgerald 2772004aadSNick Fitzgerald /// Represents the on-demand instance allocator. 2872004aadSNick Fitzgerald #[derive(Clone)] 2972004aadSNick Fitzgerald pub struct OnDemandInstanceAllocator { 3072004aadSNick Fitzgerald mem_creator: Option<Arc<dyn RuntimeMemoryCreator>>, 3172004aadSNick Fitzgerald #[cfg(feature = "async")] 3272004aadSNick Fitzgerald stack_creator: Option<Arc<dyn RuntimeFiberStackCreator>>, 3372004aadSNick Fitzgerald #[cfg(feature = "async")] 3472004aadSNick Fitzgerald stack_size: usize, 35980a136eSNick Fitzgerald #[cfg(feature = "async")] 36980a136eSNick Fitzgerald stack_zeroing: bool, 3772004aadSNick Fitzgerald } 3872004aadSNick Fitzgerald 3972004aadSNick Fitzgerald impl OnDemandInstanceAllocator { 4072004aadSNick Fitzgerald /// Creates a new on-demand instance allocator. new( mem_creator: Option<Arc<dyn RuntimeMemoryCreator>>, stack_size: usize, stack_zeroing: bool, ) -> Self41980a136eSNick Fitzgerald pub fn new( 42980a136eSNick Fitzgerald mem_creator: Option<Arc<dyn RuntimeMemoryCreator>>, 43980a136eSNick Fitzgerald stack_size: usize, 44980a136eSNick Fitzgerald stack_zeroing: bool, 45980a136eSNick Fitzgerald ) -> Self { 46980a136eSNick Fitzgerald let _ = (stack_size, stack_zeroing); // suppress warnings when async feature is disabled. 4772004aadSNick Fitzgerald Self { 4872004aadSNick Fitzgerald mem_creator, 4972004aadSNick Fitzgerald #[cfg(feature = "async")] 5072004aadSNick Fitzgerald stack_creator: None, 5172004aadSNick Fitzgerald #[cfg(feature = "async")] 5272004aadSNick Fitzgerald stack_size, 53980a136eSNick Fitzgerald #[cfg(feature = "async")] 54980a136eSNick Fitzgerald stack_zeroing, 5572004aadSNick Fitzgerald } 5672004aadSNick Fitzgerald } 5772004aadSNick Fitzgerald 5872004aadSNick Fitzgerald /// Set the stack creator. 5972004aadSNick Fitzgerald #[cfg(feature = "async")] set_stack_creator(&mut self, stack_creator: Arc<dyn RuntimeFiberStackCreator>)6072004aadSNick Fitzgerald pub fn set_stack_creator(&mut self, stack_creator: Arc<dyn RuntimeFiberStackCreator>) { 6172004aadSNick Fitzgerald self.stack_creator = Some(stack_creator); 6272004aadSNick Fitzgerald } 6372004aadSNick Fitzgerald } 6472004aadSNick Fitzgerald 6572004aadSNick Fitzgerald impl Default for OnDemandInstanceAllocator { default() -> Self6672004aadSNick Fitzgerald fn default() -> Self { 6772004aadSNick Fitzgerald Self { 6872004aadSNick Fitzgerald mem_creator: None, 6972004aadSNick Fitzgerald #[cfg(feature = "async")] 7072004aadSNick Fitzgerald stack_creator: None, 7172004aadSNick Fitzgerald #[cfg(feature = "async")] 7272004aadSNick Fitzgerald stack_size: 0, 73980a136eSNick Fitzgerald #[cfg(feature = "async")] 74980a136eSNick Fitzgerald stack_zeroing: false, 7572004aadSNick Fitzgerald } 7672004aadSNick Fitzgerald } 7772004aadSNick Fitzgerald } 7872004aadSNick Fitzgerald 79f8177c20SAlex Crichton unsafe impl InstanceAllocator for OnDemandInstanceAllocator { 8072004aadSNick Fitzgerald #[cfg(feature = "component-model")] validate_component<'a>( &self, _component: &Component, _offsets: &VMComponentOffsets<HostPtr>, _get_module: &'a dyn Fn(StaticModuleIndex) -> &'a Module, ) -> Result<()>81f8177c20SAlex Crichton fn validate_component<'a>( 8272004aadSNick Fitzgerald &self, 8372004aadSNick Fitzgerald _component: &Component, 8472004aadSNick Fitzgerald _offsets: &VMComponentOffsets<HostPtr>, 8572004aadSNick Fitzgerald _get_module: &'a dyn Fn(StaticModuleIndex) -> &'a Module, 8672004aadSNick Fitzgerald ) -> Result<()> { 8772004aadSNick Fitzgerald Ok(()) 8872004aadSNick Fitzgerald } 8972004aadSNick Fitzgerald validate_module(&self, _module: &Module, _offsets: &VMOffsets<HostPtr>) -> Result<()>90f8177c20SAlex Crichton fn validate_module(&self, _module: &Module, _offsets: &VMOffsets<HostPtr>) -> Result<()> { 9172004aadSNick Fitzgerald Ok(()) 9272004aadSNick Fitzgerald } 9372004aadSNick Fitzgerald 94c22b3cb9SNick Fitzgerald #[cfg(feature = "gc")] validate_memory(&self, _memory: &wasmtime_environ::Memory) -> Result<()>95f8177c20SAlex Crichton fn validate_memory(&self, _memory: &wasmtime_environ::Memory) -> Result<()> { 96c22b3cb9SNick Fitzgerald Ok(()) 97c22b3cb9SNick Fitzgerald } 98c22b3cb9SNick Fitzgerald 99ef921e81SAlex Crichton #[cfg(feature = "component-model")] increment_component_instance_count(&self) -> Result<()>10072004aadSNick Fitzgerald fn increment_component_instance_count(&self) -> Result<()> { 10172004aadSNick Fitzgerald Ok(()) 10272004aadSNick Fitzgerald } 10372004aadSNick Fitzgerald 104ef921e81SAlex Crichton #[cfg(feature = "component-model")] decrement_component_instance_count(&self)10572004aadSNick Fitzgerald fn decrement_component_instance_count(&self) {} 10672004aadSNick Fitzgerald increment_core_instance_count(&self) -> Result<()>10772004aadSNick Fitzgerald fn increment_core_instance_count(&self) -> Result<()> { 10872004aadSNick Fitzgerald Ok(()) 10972004aadSNick Fitzgerald } 11072004aadSNick Fitzgerald decrement_core_instance_count(&self)11172004aadSNick Fitzgerald fn decrement_core_instance_count(&self) {} 11272004aadSNick Fitzgerald allocate_memory<'a, 'b: 'a, 'c: 'a>( &'a self, request: &'a mut InstanceAllocationRequest<'b, 'c>, ty: &'a wasmtime_environ::Memory, memory_index: Option<DefinedMemoryIndex>, ) -> Pin<Box<dyn Future<Output = Result<(MemoryAllocationIndex, Memory)>> + Send + 'a>>11382ebbd5dSNick Fitzgerald fn allocate_memory<'a, 'b: 'a, 'c: 'a>( 11482ebbd5dSNick Fitzgerald &'a self, 11582ebbd5dSNick Fitzgerald request: &'a mut InstanceAllocationRequest<'b, 'c>, 11682ebbd5dSNick Fitzgerald ty: &'a wasmtime_environ::Memory, 117c22b3cb9SNick Fitzgerald memory_index: Option<DefinedMemoryIndex>, 118*9bc302adSAlex Crichton ) -> Pin<Box<dyn Future<Output = Result<(MemoryAllocationIndex, Memory)>> + Send + 'a>> { 11972004aadSNick Fitzgerald let creator = self 12072004aadSNick Fitzgerald .mem_creator 12172004aadSNick Fitzgerald .as_deref() 12272004aadSNick Fitzgerald .unwrap_or_else(|| &DefaultMemoryCreator); 123c22b3cb9SNick Fitzgerald 124*9bc302adSAlex Crichton crate::runtime::box_future(async move { 125c22b3cb9SNick Fitzgerald let image = if let Some(memory_index) = memory_index { 126c22b3cb9SNick Fitzgerald request.runtime_info.memory_image(memory_index)? 127c22b3cb9SNick Fitzgerald } else { 128c22b3cb9SNick Fitzgerald None 129c22b3cb9SNick Fitzgerald }; 130c22b3cb9SNick Fitzgerald 13172004aadSNick Fitzgerald let allocation_index = MemoryAllocationIndex::default(); 13272004aadSNick Fitzgerald let memory = Memory::new_dynamic( 1332a7f0653SAlex Crichton ty, 1340a55f804SAlex Crichton request.store.engine(), 13572004aadSNick Fitzgerald creator, 13672004aadSNick Fitzgerald image, 137e1f50aadSAlex Crichton request.limiter.as_deref_mut(), 138e1f50aadSAlex Crichton ) 139e1f50aadSAlex Crichton .await?; 14072004aadSNick Fitzgerald Ok((allocation_index, memory)) 141*9bc302adSAlex Crichton }) 14272004aadSNick Fitzgerald } 14372004aadSNick Fitzgerald deallocate_memory( &self, _memory_index: Option<DefinedMemoryIndex>, allocation_index: MemoryAllocationIndex, _memory: Memory, )14472004aadSNick Fitzgerald unsafe fn deallocate_memory( 14572004aadSNick Fitzgerald &self, 146c22b3cb9SNick Fitzgerald _memory_index: Option<DefinedMemoryIndex>, 14772004aadSNick Fitzgerald allocation_index: MemoryAllocationIndex, 14872004aadSNick Fitzgerald _memory: Memory, 14972004aadSNick Fitzgerald ) { 15072004aadSNick Fitzgerald debug_assert_eq!(allocation_index, MemoryAllocationIndex::default()); 15172004aadSNick Fitzgerald // Normal destructors do all the necessary clean up. 15272004aadSNick Fitzgerald } 15372004aadSNick Fitzgerald allocate_table<'a, 'b: 'a, 'c: 'a>( &'a self, request: &'a mut InstanceAllocationRequest<'b, 'c>, ty: &'a wasmtime_environ::Table, _table_index: DefinedTableIndex, ) -> Pin<Box<dyn Future<Output = Result<(TableAllocationIndex, Table)>> + Send + 'a>>15482ebbd5dSNick Fitzgerald fn allocate_table<'a, 'b: 'a, 'c: 'a>( 15582ebbd5dSNick Fitzgerald &'a self, 15682ebbd5dSNick Fitzgerald request: &'a mut InstanceAllocationRequest<'b, 'c>, 15782ebbd5dSNick Fitzgerald ty: &'a wasmtime_environ::Table, 15872004aadSNick Fitzgerald _table_index: DefinedTableIndex, 159*9bc302adSAlex Crichton ) -> Pin<Box<dyn Future<Output = Result<(TableAllocationIndex, Table)>> + Send + 'a>> { 160*9bc302adSAlex Crichton crate::runtime::box_future(async move { 16172004aadSNick Fitzgerald let allocation_index = TableAllocationIndex::default(); 162e1f50aadSAlex Crichton let table = Table::new_dynamic( 163e1f50aadSAlex Crichton ty, 164e1f50aadSAlex Crichton request.store.engine().tunables(), 165e1f50aadSAlex Crichton request.limiter.as_deref_mut(), 166e1f50aadSAlex Crichton ) 167e1f50aadSAlex Crichton .await?; 16872004aadSNick Fitzgerald Ok((allocation_index, table)) 169*9bc302adSAlex Crichton }) 17072004aadSNick Fitzgerald } 17172004aadSNick Fitzgerald deallocate_table( &self, _table_index: DefinedTableIndex, allocation_index: TableAllocationIndex, _table: Table, )17272004aadSNick Fitzgerald unsafe fn deallocate_table( 17372004aadSNick Fitzgerald &self, 17472004aadSNick Fitzgerald _table_index: DefinedTableIndex, 17572004aadSNick Fitzgerald allocation_index: TableAllocationIndex, 17672004aadSNick Fitzgerald _table: Table, 17772004aadSNick Fitzgerald ) { 17872004aadSNick Fitzgerald debug_assert_eq!(allocation_index, TableAllocationIndex::default()); 17972004aadSNick Fitzgerald // Normal destructors do all the necessary clean up. 18072004aadSNick Fitzgerald } 18172004aadSNick Fitzgerald 18272004aadSNick Fitzgerald #[cfg(feature = "async")] allocate_fiber_stack(&self) -> Result<wasmtime_fiber::FiberStack>18372004aadSNick Fitzgerald fn allocate_fiber_stack(&self) -> Result<wasmtime_fiber::FiberStack> { 18472004aadSNick Fitzgerald if self.stack_size == 0 { 18596e19700SNick Fitzgerald crate::bail!("fiber stacks are not supported by the allocator") 18672004aadSNick Fitzgerald } 18772004aadSNick Fitzgerald let stack = match &self.stack_creator { 18872004aadSNick Fitzgerald Some(stack_creator) => { 189980a136eSNick Fitzgerald let stack = stack_creator.new_stack(self.stack_size, self.stack_zeroing)?; 19072004aadSNick Fitzgerald wasmtime_fiber::FiberStack::from_custom(stack) 19172004aadSNick Fitzgerald } 192980a136eSNick Fitzgerald None => wasmtime_fiber::FiberStack::new(self.stack_size, self.stack_zeroing), 19372004aadSNick Fitzgerald }?; 19472004aadSNick Fitzgerald Ok(stack) 19572004aadSNick Fitzgerald } 19672004aadSNick Fitzgerald 19772004aadSNick Fitzgerald #[cfg(feature = "async")] deallocate_fiber_stack(&self, stack: wasmtime_fiber::FiberStack)198e1f8b9b7SNick Fitzgerald unsafe fn deallocate_fiber_stack(&self, stack: wasmtime_fiber::FiberStack) { 19972004aadSNick Fitzgerald // The on-demand allocator has no further bookkeeping for fiber stacks 200e1f8b9b7SNick Fitzgerald // beyond dropping them. 201e1f8b9b7SNick Fitzgerald let _ = stack; 20272004aadSNick Fitzgerald } 20372004aadSNick Fitzgerald purge_module(&self, _: CompiledModuleId)20472004aadSNick Fitzgerald fn purge_module(&self, _: CompiledModuleId) {} 20572004aadSNick Fitzgerald next_available_pkey(&self) -> Option<ProtectionKey>20672004aadSNick Fitzgerald fn next_available_pkey(&self) -> Option<ProtectionKey> { 20772004aadSNick Fitzgerald // The on-demand allocator cannot use protection keys--it requires 20872004aadSNick Fitzgerald // back-to-back allocation of memory slots that this allocator cannot 20972004aadSNick Fitzgerald // guarantee. 21072004aadSNick Fitzgerald None 21172004aadSNick Fitzgerald } 21272004aadSNick Fitzgerald restrict_to_pkey(&self, _: ProtectionKey)21372004aadSNick Fitzgerald fn restrict_to_pkey(&self, _: ProtectionKey) { 21472004aadSNick Fitzgerald // The on-demand allocator cannot use protection keys; an on-demand 21572004aadSNick Fitzgerald // allocator will never hand out protection keys to the stores its 21672004aadSNick Fitzgerald // engine creates. 21772004aadSNick Fitzgerald unreachable!() 21872004aadSNick Fitzgerald } 21972004aadSNick Fitzgerald allow_all_pkeys(&self)22072004aadSNick Fitzgerald fn allow_all_pkeys(&self) { 22172004aadSNick Fitzgerald // The on-demand allocator cannot use protection keys; an on-demand 22272004aadSNick Fitzgerald // allocator will never hand out protection keys to the stores its 22372004aadSNick Fitzgerald // engine creates. 22472004aadSNick Fitzgerald unreachable!() 22572004aadSNick Fitzgerald } 22672004aadSNick Fitzgerald 22772004aadSNick Fitzgerald #[cfg(feature = "gc")] allocate_gc_heap( &self, engine: &crate::Engine, gc_runtime: &dyn GcRuntime, memory_alloc_index: MemoryAllocationIndex, memory: Memory, ) -> Result<(GcHeapAllocationIndex, Box<dyn GcHeap>)>22872004aadSNick Fitzgerald fn allocate_gc_heap( 22972004aadSNick Fitzgerald &self, 230eafe7439SNick Fitzgerald engine: &crate::Engine, 23172004aadSNick Fitzgerald gc_runtime: &dyn GcRuntime, 232c22b3cb9SNick Fitzgerald memory_alloc_index: MemoryAllocationIndex, 233c22b3cb9SNick Fitzgerald memory: Memory, 23472004aadSNick Fitzgerald ) -> Result<(GcHeapAllocationIndex, Box<dyn GcHeap>)> { 235c22b3cb9SNick Fitzgerald debug_assert_eq!(memory_alloc_index, MemoryAllocationIndex::default()); 236c22b3cb9SNick Fitzgerald let mut heap = gc_runtime.new_gc_heap(engine)?; 237c22b3cb9SNick Fitzgerald heap.attach(memory); 238c22b3cb9SNick Fitzgerald Ok((GcHeapAllocationIndex::default(), heap)) 23972004aadSNick Fitzgerald } 24072004aadSNick Fitzgerald 24172004aadSNick Fitzgerald #[cfg(feature = "gc")] deallocate_gc_heap( &self, allocation_index: GcHeapAllocationIndex, mut gc_heap: Box<dyn crate::runtime::vm::GcHeap>, ) -> (MemoryAllocationIndex, Memory)24272004aadSNick Fitzgerald fn deallocate_gc_heap( 24372004aadSNick Fitzgerald &self, 24472004aadSNick Fitzgerald allocation_index: GcHeapAllocationIndex, 245c22b3cb9SNick Fitzgerald mut gc_heap: Box<dyn crate::runtime::vm::GcHeap>, 246c22b3cb9SNick Fitzgerald ) -> (MemoryAllocationIndex, Memory) { 24772004aadSNick Fitzgerald debug_assert_eq!(allocation_index, GcHeapAllocationIndex::default()); 248c22b3cb9SNick Fitzgerald (MemoryAllocationIndex::default(), gc_heap.detach()) 24972004aadSNick Fitzgerald } 25072004aadSNick Fitzgerald } 251