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