diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index 9b6a663..96542f7 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -263,24 +263,24 @@ impl MemoryRoot { let mem_left = self_length - self_position - core::mem::size_of::() as u64; let length_with_block = length + core::mem::size_of::() as u64; - // If the current position is large enough to hold the length of the block being - // allocated then check for existing free blocks that can be re-used before - // growing memory - if length_with_block <= self_position { - let b = self.find_free_block(length, self_position); - - // If there's a free block then re-use it - if let Some(b) = b { - b.used = length as usize; - b.status - .store(MemoryStatus::Active as u8, Ordering::Release); - return Some(b); - } - } - // When the allocation is larger than the number of bytes available // we will need to try to grow the memory if length_with_block >= mem_left { + // If the current position is large enough to hold the length of the block being + // allocated then check for existing free blocks that can be re-used before + // growing memory + if length_with_block <= self_position { + let b = self.find_free_block(length, self_position); + + // If there's a free block then re-use it + if let Some(b) = b { + b.used = length as usize; + b.status + .store(MemoryStatus::Active as u8, Ordering::Release); + return Some(b); + } + } + // Calculate the number of pages needed to cover the remaining bytes let npages = num_pages(length_with_block - mem_left); let x = core::arch::wasm32::memory_grow(0, npages); diff --git a/runtime/src/extism-runtime.wasm b/runtime/src/extism-runtime.wasm index e62df68..fe7f2d0 100644 Binary files a/runtime/src/extism-runtime.wasm and b/runtime/src/extism-runtime.wasm differ diff --git a/runtime/src/tests/kernel.rs b/runtime/src/tests/kernel.rs index 32dbee1..d104ca6 100644 --- a/runtime/src/tests/kernel.rs +++ b/runtime/src/tests/kernel.rs @@ -238,7 +238,7 @@ fn test_kernel_page_allocations() { let c = extism_alloc(&mut store, instance, 65500 * 2); let c_size = extism_length(&mut store, instance, c); - let d = extism_alloc(&mut store, instance, 65500); + let d = extism_alloc(&mut store, instance, 65536); assert_eq!(a + (a_size - c_size), c); assert!(c < b); @@ -461,19 +461,20 @@ quickcheck! { fn check_block_reuse(allocs: Vec) -> bool { let (mut store, mut instance) = init_kernel_test(); let instance = &mut instance; - let init = extism_alloc(&mut store, instance, allocs.iter().map(|x| *x as u64).sum::() + allocs.len() as u64 * 64); + let init = extism_alloc(&mut store, instance, allocs.iter().map(|x| *x as u64).sum::() + (allocs.len() as u64 * (65535 + 128))); let bounds = init + extism_length(&mut store, instance, init); extism_free(&mut store, instance, init); for a in allocs { - let ptr = extism_alloc(&mut store, instance, a as u64); + let ptr = extism_alloc(&mut store, instance, a as u64 + 65535); if ptr == 0 { continue } - if extism_length(&mut store, instance, ptr) != a as u64 { + if extism_length(&mut store, instance, ptr) != a as u64 + 65535 { + println!("FAILED ALLOC"); return false } - extism_free(&mut store, instance , ptr); + extism_free(&mut store, instance, ptr); if ptr > bounds { println!("ptr={ptr}, bounds={bounds}");