runtime: refactor Memory to always use Box<dyn RuntimeLinearMemory> (#4086)
While working with the runtime `Memory` object, it became clear that
some refactoring was needed. In order to implement shared memory from
the threads proposal, we must be able to atomically change the memory
size. Previously, the split into variants, `Memory::Static` and
`Memory::Dynamic`, made any attempt to lock forced us to duplicate logic
in various places.
This change moves `enum Memory { Static..., Dynamic... }` to simply
`struct Memory(Box<dyn RuntimeLinearMemory>)`. A new type,
`ExternalMemory`, takes the place of `Memory::Static` and also
implements the `RuntimeLinearMemory` trait, allowing `Memory` to contain
the same two options as before: `MmapMemory` for `Memory::Dynamic` and
`ExternalMemory` for `Memory::Static`. To interface with the
`PoolingAllocator`, this change also required the ability to downcast to
the internal representation.
This commit is contained in:
@@ -445,34 +445,25 @@ impl InstancePool {
|
||||
instance_index: usize,
|
||||
memories: &mut PrimaryMap<DefinedMemoryIndex, Memory>,
|
||||
) {
|
||||
// Decommit any linear memories that were used
|
||||
for ((def_mem_idx, memory), base) in
|
||||
memories.iter_mut().zip(self.memories.get(instance_index))
|
||||
// Decommit any linear memories that were used.
|
||||
let memories = mem::take(memories);
|
||||
for ((def_mem_idx, mut memory), base) in
|
||||
memories.into_iter().zip(self.memories.get(instance_index))
|
||||
{
|
||||
let memory = mem::take(memory);
|
||||
assert!(memory.is_static());
|
||||
|
||||
match memory {
|
||||
Memory::Static {
|
||||
memory_image: Some(mut image),
|
||||
..
|
||||
} => {
|
||||
// If there was any error clearing the image, just
|
||||
// drop it here, and let the drop handler for the
|
||||
// slot unmap in a way that retains the
|
||||
// address space reservation.
|
||||
if image.clear_and_remain_ready().is_ok() {
|
||||
self.memories
|
||||
.return_memory_image_slot(instance_index, def_mem_idx, image);
|
||||
}
|
||||
}
|
||||
|
||||
_ => {
|
||||
let size = memory.byte_size();
|
||||
drop(memory);
|
||||
decommit_memory_pages(base, size)
|
||||
.expect("failed to decommit linear memory pages");
|
||||
let size = memory.byte_size();
|
||||
if let Some(mut image) = memory.unwrap_static_image() {
|
||||
// Reset the image slot. If there is any error clearing the
|
||||
// image, just drop it here, and let the drop handler for the
|
||||
// slot unmap in a way that retains the address space
|
||||
// reservation.
|
||||
if image.clear_and_remain_ready().is_ok() {
|
||||
self.memories
|
||||
.return_memory_image_slot(instance_index, def_mem_idx, image);
|
||||
}
|
||||
} else {
|
||||
// Otherwise, decommit the memory pages.
|
||||
decommit_memory_pages(base, size).expect("failed to decommit linear memory pages");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user