pub struct MemoryImageSlot { /* private fields */ }
Expand description

Slot management of a copy-on-write image which can be reused for the pooling allocator.

This data structure manages a slot of linear memory, primarily in the pooling allocator, which optionally has a contiguous memory image in the middle of it. Pictorially this data structure manages a virtual memory region that looks like:

  +--------------------+-------------------+--------------+--------------+
  |   anonymous        |      optional     |   anonymous  |    PROT_NONE |
  |     zero           |       memory      |     zero     |     memory   |
  |    memory          |       image       |    memory    |              |
  +--------------------+-------------------+--------------+--------------+
  |                     <------+---------->
  |<-----+------------>         \
  |      \                   image.len
  |       \
  |  image.linear_memory_offset
  |
  \
 self.base is this virtual address

   <------------------+------------------------------------------------>
                       \
                     static_size

   <------------------+---------------------------------->
                       \
                     accessible

When a MemoryImageSlot is created it’s told what the static_size and accessible limits are. Initially there is assumed to be no image in linear memory.

When MemoryImageSlot::instantiate is called then the method will perform a “synchronization” to take the image from its prior state to the new state for the image specified. The first instantiation for example will mmap the heap image into place. Upon reuse of a slot nothing happens except possibly shrinking self.accessible. When a new image is used then the old image is mapped to anonymous zero memory and then the new image is mapped in place.

A MemoryImageSlot is either dirty or it isn’t. When a MemoryImageSlot is dirty then it is assumed that any memory beneath self.accessible could have any value. Instantiation cannot happen into a dirty slot, however, so the MemoryImageSlot::clear_and_remain_ready returns this memory back to its original state to mark dirty = false. This is done by resetting all anonymous memory back to zero and the image itself back to its initial contents.

On Linux this is achieved with the madvise(MADV_DONTNEED) syscall. This syscall will release the physical pages back to the OS but retain the original mappings, effectively resetting everything back to its initial state. Non-linux platforms will replace all memory below self.accessible with a fresh zero’d mmap, meaning that reuse is effectively not supported.

Trait Implementations§

source§

impl Debug for MemoryImageSlot

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Drop for MemoryImageSlot

source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.