wasmtime/runtime/vm/memory/static_.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
//! Support for implementing the [`RuntimeLinearMemory`] trait in terms of a
//! fixed allocation that cannot move.
use crate::prelude::*;
use crate::runtime::vm::memory::RuntimeLinearMemory;
use crate::runtime::vm::MemoryBase;
/// A "static" memory where the lifetime of the backing memory is managed
/// elsewhere. Currently used with the pooling allocator.
pub struct StaticMemory {
/// The base pointer of this static memory, wrapped up in a send/sync
/// wrapper.
base: MemoryBase,
/// The byte capacity of the `base` pointer.
capacity: usize,
/// The current size, in bytes, of this memory.
size: usize,
}
impl StaticMemory {
pub fn new(
base: MemoryBase,
base_capacity: usize,
initial_size: usize,
maximum_size: Option<usize>,
) -> Result<Self> {
if base_capacity < initial_size {
bail!(
"initial memory size of {} exceeds the pooling allocator's \
configured maximum memory size of {} bytes",
initial_size,
base_capacity,
);
}
// Only use the part of the slice that is necessary.
let base_capacity = match maximum_size {
Some(max) if max < base_capacity => max,
_ => base_capacity,
};
Ok(Self {
base,
capacity: base_capacity,
size: initial_size,
})
}
}
impl RuntimeLinearMemory for StaticMemory {
fn byte_size(&self) -> usize {
self.size
}
fn byte_capacity(&self) -> usize {
self.capacity
}
fn grow_to(&mut self, new_byte_size: usize) -> Result<()> {
// Never exceed the static memory size; this check should have been made
// prior to arriving here.
assert!(new_byte_size <= self.capacity);
// Update our accounting of the available size.
self.size = new_byte_size;
Ok(())
}
fn set_byte_size(&mut self, len: usize) {
self.size = len;
}
fn base(&self) -> MemoryBase {
self.base.clone()
}
}