2121mod decommit_queue;
2222mod index_allocator;
2323mod memory_pool;
24+ mod metrics;
2425mod table_pool;
2526
2627#[ cfg( feature = "gc" ) ]
@@ -54,6 +55,7 @@ use crate::runtime::vm::{
5455 mpk:: { self , ProtectionKey , ProtectionMask } ,
5556 sys:: vm:: PageMap ,
5657} ;
58+ use core:: sync:: atomic:: AtomicUsize ;
5759use std:: borrow:: Cow ;
5860use std:: fmt:: Display ;
5961use std:: sync:: { Mutex , MutexGuard } ;
@@ -65,6 +67,8 @@ use wasmtime_environ::{
6567 DefinedMemoryIndex , DefinedTableIndex , HostPtr , Module , Tunables , VMOffsets ,
6668} ;
6769
70+ pub use self :: metrics:: PoolingAllocatorMetrics ;
71+
6872#[ cfg( feature = "gc" ) ]
6973use super :: GcHeapAllocationIndex ;
7074#[ cfg( feature = "gc" ) ]
@@ -305,8 +309,12 @@ pub struct PoolingInstanceAllocator {
305309 live_component_instances : AtomicU64 ,
306310
307311 decommit_queue : Mutex < DecommitQueue > ,
312+
308313 memories : MemoryPool ,
314+ live_memories : AtomicUsize ,
315+
309316 tables : TablePool ,
317+ live_tables : AtomicUsize ,
310318
311319 #[ cfg( feature = "gc" ) ]
312320 gc_heaps : GcHeapPool ,
@@ -335,6 +343,8 @@ impl Drop for PoolingInstanceAllocator {
335343
336344 debug_assert_eq ! ( self . live_component_instances. load( Ordering :: Acquire ) , 0 ) ;
337345 debug_assert_eq ! ( self . live_core_instances. load( Ordering :: Acquire ) , 0 ) ;
346+ debug_assert_eq ! ( self . live_memories. load( Ordering :: Acquire ) , 0 ) ;
347+ debug_assert_eq ! ( self . live_tables. load( Ordering :: Acquire ) , 0 ) ;
338348
339349 debug_assert ! ( self . memories. is_empty( ) ) ;
340350 debug_assert ! ( self . tables. is_empty( ) ) ;
@@ -357,7 +367,9 @@ impl PoolingInstanceAllocator {
357367 live_core_instances : AtomicU64 :: new ( 0 ) ,
358368 decommit_queue : Mutex :: new ( DecommitQueue :: default ( ) ) ,
359369 memories : MemoryPool :: new ( config, tunables) ?,
370+ live_memories : AtomicUsize :: new ( 0 ) ,
360371 tables : TablePool :: new ( config) ?,
372+ live_tables : AtomicUsize :: new ( 0 ) ,
361373 #[ cfg( feature = "gc" ) ]
362374 gc_heaps : GcHeapPool :: new ( config) ?,
363375 #[ cfg( feature = "async" ) ]
@@ -652,23 +664,29 @@ unsafe impl InstanceAllocator for PoolingInstanceAllocator {
652664 ty : & wasmtime_environ:: Memory ,
653665 memory_index : Option < DefinedMemoryIndex > ,
654666 ) -> Result < ( MemoryAllocationIndex , Memory ) > {
655- // FIXME(rust-lang/rust#145127) this should ideally use a version of
656- // `with_flush_and_retry` but adapted for async closures instead of only
657- // sync closures. Right now that won't compile though so this is the
658- // manually expanded version of the method.
659- let e = match self . memories . allocate ( request, ty, memory_index) . await {
660- Ok ( result) => return Ok ( result) ,
661- Err ( e) => e,
662- } ;
667+ async {
668+ // FIXME(rust-lang/rust#145127) this should ideally use a version of
669+ // `with_flush_and_retry` but adapted for async closures instead of only
670+ // sync closures. Right now that won't compile though so this is the
671+ // manually expanded version of the method.
672+ let e = match self . memories . allocate ( request, ty, memory_index) . await {
673+ Ok ( result) => return Ok ( result) ,
674+ Err ( e) => e,
675+ } ;
663676
664- if e. is :: < PoolConcurrencyLimitError > ( ) {
665- let queue = self . decommit_queue . lock ( ) . unwrap ( ) ;
666- if self . flush_decommit_queue ( queue) {
667- return self . memories . allocate ( request, ty, memory_index) . await ;
677+ if e. is :: < PoolConcurrencyLimitError > ( ) {
678+ let queue = self . decommit_queue . lock ( ) . unwrap ( ) ;
679+ if self . flush_decommit_queue ( queue) {
680+ return self . memories . allocate ( request, ty, memory_index) . await ;
681+ }
668682 }
669- }
670683
671- Err ( e)
684+ Err ( e)
685+ }
686+ . await
687+ . inspect ( |_| {
688+ self . live_memories . fetch_add ( 1 , Ordering :: Relaxed ) ;
689+ } )
672690 }
673691
674692 unsafe fn deallocate_memory (
@@ -677,6 +695,7 @@ unsafe impl InstanceAllocator for PoolingInstanceAllocator {
677695 allocation_index : MemoryAllocationIndex ,
678696 memory : Memory ,
679697 ) {
698+ self . live_memories . fetch_sub ( 1 , Ordering :: Relaxed ) ;
680699 // Reset the image slot. If there is any error clearing the
681700 // image, just drop it here, and let the drop handler for the
682701 // slot unmap in a way that retains the address space
@@ -712,21 +731,27 @@ unsafe impl InstanceAllocator for PoolingInstanceAllocator {
712731 ty : & wasmtime_environ:: Table ,
713732 _table_index : DefinedTableIndex ,
714733 ) -> Result < ( super :: TableAllocationIndex , Table ) > {
715- // FIXME: see `allocate_memory` above for comments about duplication
716- // with `with_flush_and_retry`.
717- let e = match self . tables . allocate ( request, ty) . await {
718- Ok ( result) => return Ok ( result) ,
719- Err ( e) => e,
720- } ;
734+ async {
735+ // FIXME: see `allocate_memory` above for comments about duplication
736+ // with `with_flush_and_retry`.
737+ let e = match self . tables . allocate ( request, ty) . await {
738+ Ok ( result) => return Ok ( result) ,
739+ Err ( e) => e,
740+ } ;
721741
722- if e. is :: < PoolConcurrencyLimitError > ( ) {
723- let queue = self . decommit_queue . lock ( ) . unwrap ( ) ;
724- if self . flush_decommit_queue ( queue) {
725- return self . tables . allocate ( request, ty) . await ;
742+ if e. is :: < PoolConcurrencyLimitError > ( ) {
743+ let queue = self . decommit_queue . lock ( ) . unwrap ( ) ;
744+ if self . flush_decommit_queue ( queue) {
745+ return self . tables . allocate ( request, ty) . await ;
746+ }
726747 }
727- }
728748
729- Err ( e)
749+ Err ( e)
750+ }
751+ . await
752+ . inspect ( |_| {
753+ self . live_tables . fetch_add ( 1 , Ordering :: Relaxed ) ;
754+ } )
730755 }
731756
732757 unsafe fn deallocate_table (
@@ -735,6 +760,7 @@ unsafe impl InstanceAllocator for PoolingInstanceAllocator {
735760 allocation_index : TableAllocationIndex ,
736761 mut table : Table ,
737762 ) {
763+ self . live_tables . fetch_sub ( 1 , Ordering :: Relaxed ) ;
738764 let mut queue = DecommitQueue :: default ( ) ;
739765 // SAFETY: This table is no longer in use by the allocator when this
740766 // method is called and additionally all image ranges are pushed with
@@ -816,6 +842,10 @@ unsafe impl InstanceAllocator for PoolingInstanceAllocator {
816842 ) -> ( MemoryAllocationIndex , Memory ) {
817843 self . gc_heaps . deallocate ( allocation_index, gc_heap)
818844 }
845+
846+ fn as_pooling ( & self ) -> Option < & PoolingInstanceAllocator > {
847+ Some ( self )
848+ }
819849}
820850
821851#[ cfg( test) ]
0 commit comments