@@ -191,11 +191,11 @@ pub(crate) struct WasmiModule<T, L, S, U> {
191191 // This is used to prevent mutating store state in start.
192192 running_start : bool ,
193193
194- // First free byte in the heap .
195- heap_start_ptr : u32 ,
194+ // First free byte in the current arena .
195+ arena_start_ptr : u32 ,
196196
197- // Number of free bytes starting from `heap_start_ptr `.
198- heap_free_size : u32 ,
197+ // Number of free bytes starting from `arena_start_ptr `.
198+ arena_free_size : u32 ,
199199}
200200
201201impl < T , L , S , U > WasmiModule < T , L , S , U >
@@ -245,9 +245,9 @@ where
245245 start_time : Instant :: now ( ) ,
246246 running_start : true ,
247247
248- // `heap_start_ptr ` will be set on the first call to `raw_new`.
249- heap_free_size : 0 ,
250- heap_start_ptr : 0 ,
248+ // `arena_start_ptr ` will be set on the first call to `raw_new`.
249+ arena_free_size : 0 ,
250+ arena_start_ptr : 0 ,
251251 } ;
252252
253253 this. module = module
@@ -420,35 +420,32 @@ where
420420 + ' static ,
421421{
422422 fn raw_new ( & mut self , bytes : & [ u8 ] ) -> Result < u32 , Error > {
423- // We request large chunks from the AssemblyScript allocator and manage them ourselves.
424- // This assumes the arena allocator is being used in AS .
423+ // We request large chunks from the AssemblyScript allocator to use as arenas that we
424+ // manage directly .
425425
426- static MIN_HEAP_SIZE_INCREMENT : u32 = 10_000 ;
426+ static MIN_ARENA_SIZE : u32 = 10_000 ;
427427
428428 let size = u32:: try_from ( bytes. len ( ) ) . unwrap ( ) ;
429- if size > self . heap_free_size {
430- let need = size - self . heap_free_size ;
431- let allocate = need. max ( MIN_HEAP_SIZE_INCREMENT ) ;
429+ if size > self . arena_free_size {
430+ // Allocate a new arena. Any free space left in the previous arena is left unused. This
431+ // causes at most half of memory to be wasted, which is acceptable.
432+ let arena_size = size. max ( MIN_ARENA_SIZE ) ;
432433 let allocated_ptr = self
433434 . module
434435 . clone ( )
435- . invoke_export ( "memory.allocate" , & [ RuntimeValue :: from ( allocate ) ] , self )
436+ . invoke_export ( "memory.allocate" , & [ RuntimeValue :: from ( arena_size ) ] , self )
436437 . expect ( "Failed to invoke memory allocation function" )
437438 . expect ( "Function did not return a value" )
438439 . try_into :: < u32 > ( )
439440 . expect ( "Function did not return u32" ) ;
440- self . heap_free_size += allocate;
441-
442- // On the first call, initialze `self.heap_start_ptr`.
443- if self . heap_start_ptr == 0 {
444- self . heap_start_ptr = allocated_ptr;
445- }
441+ self . arena_start_ptr = allocated_ptr;
442+ self . arena_free_size = arena_size;
446443 } ;
447444
448- let ptr = self . heap_start_ptr ;
445+ let ptr = self . arena_start_ptr ;
449446 self . memory . set ( ptr, bytes) ?;
450- self . heap_start_ptr += size;
451- self . heap_free_size -= size;
447+ self . arena_start_ptr += size;
448+ self . arena_free_size -= size;
452449
453450 Ok ( ptr)
454451 }
0 commit comments