wasmtime_environ

Struct EntityList

pub struct EntityList<T>{ /* private fields */ }
Expand description

A small list of entity references allocated from a pool.

An EntityList<T> type provides similar functionality to Vec<T>, but with some important differences in the implementation:

  1. Memory is allocated from a ListPool<T> instead of the global heap.
  2. The footprint of an entity list is 4 bytes, compared with the 24 bytes for Vec<T>.
  3. An entity list doesn’t implement Drop, leaving it to the pool to manage memory.

The list pool is intended to be used as a LIFO allocator. After building up a larger data structure with many list references, the whole thing can be discarded quickly by clearing the pool.

§Safety

Entity lists are not as safe to use as Vec<T>, but they never jeopardize Rust’s memory safety guarantees. These are the problems to be aware of:

  • If you lose track of an entity list, its memory won’t be recycled until the pool is cleared. This can cause the pool to grow very large with leaked lists.
  • If entity lists are used after their pool is cleared, they may contain garbage data, and modifying them may corrupt other lists in the pool.
  • If an entity list is used with two different pool instances, both pools are likely to become corrupted.

Entity lists can be cloned, but that operation should only be used as part of cloning the whole function they belong to. Cloning an entity list does not allocate new memory for the clone. It creates an alias of the same memory.

Entity lists cannot be hashed and compared for equality because it’s not possible to compare the contents of the list without the pool reference.

§Implementation

The EntityList itself is designed to have the smallest possible footprint. This is important because it is used inside very compact data structures like InstructionData. The list contains only a 32-bit index into the pool’s memory vector, pointing to the first element of the list.

The pool is just a single Vec<T> containing all of the allocated lists. Each list is represented as three contiguous parts:

  1. The number of elements in the list.
  2. The list elements.
  3. Excess capacity elements.

The total size of the three parts is always a power of two, and the excess capacity is always as small as possible. This means that shrinking a list may cause the excess capacity to shrink if a smaller power-of-two size becomes available.

Both growing and shrinking a list may cause it to be reallocated in the pool vector.

The index stored in an EntityList points to part 2, the list elements. The value 0 is reserved for the empty list which isn’t allocated in the vector.

Implementations§

§

impl<T> EntityList<T>

pub fn new() -> EntityList<T>

Create a new empty list.

pub fn from_slice(slice: &[T], pool: &mut ListPool<T>) -> EntityList<T>

Create a new list with the contents initialized from a slice.

pub fn is_empty(&self) -> bool

Returns true if the list has a length of 0.

pub fn len(&self, pool: &ListPool<T>) -> usize

Get the number of elements in the list.

pub fn is_valid(&self, pool: &ListPool<T>) -> bool

Returns true if the list is valid

pub fn as_slice<'a>(&self, pool: &'a ListPool<T>) -> &'a [T]

Get the list as a slice.

pub fn get(&self, index: usize, pool: &ListPool<T>) -> Option<T>

Get a single element from the list.

pub fn first(&self, pool: &ListPool<T>) -> Option<T>

Get the first element from the list.

pub fn as_mut_slice<'a>(&'a mut self, pool: &'a mut ListPool<T>) -> &'a mut [T]

Get the list as a mutable slice.

pub fn get_mut<'a>( &'a mut self, index: usize, pool: &'a mut ListPool<T>, ) -> Option<&'a mut T>

Get a mutable reference to a single element from the list.

pub fn deep_clone(&self, pool: &mut ListPool<T>) -> EntityList<T>

Create a deep clone of the list, which does not alias the original list.

pub fn clear(&mut self, pool: &mut ListPool<T>)

Removes all elements from the list.

The memory used by the list is put back in the pool.

pub fn take(&mut self) -> EntityList<T>

Take all elements from this list and return them as a new list. Leave this list empty.

This is the equivalent of Option::take().

pub fn push(&mut self, element: T, pool: &mut ListPool<T>) -> usize

Appends an element to the back of the list. Returns the index where the element was inserted.

pub fn from_iter<I>(elements: I, pool: &mut ListPool<T>) -> EntityList<T>
where I: IntoIterator<Item = T>,

Constructs a list from an iterator.

pub fn extend<I>(&mut self, elements: I, pool: &mut ListPool<T>)
where I: IntoIterator<Item = T>,

Appends multiple elements to the back of the list.

pub fn copy_from( &mut self, other: &EntityList<T>, slice: impl RangeBounds<usize>, index: usize, pool: &mut ListPool<T>, )

Copies a slice from an entity list in the same pool to a position in this one.

Will panic if self is the same list as other.

pub fn insert(&mut self, index: usize, element: T, pool: &mut ListPool<T>)

Inserts an element as position index in the list, shifting all elements after it to the right.

pub fn remove(&mut self, index: usize, pool: &mut ListPool<T>)

Removes the element at position index from the list. Potentially linear complexity.

pub fn swap_remove(&mut self, index: usize, pool: &mut ListPool<T>)

Removes the element at index in constant time by switching it with the last element of the list.

pub fn truncate(&mut self, new_len: usize, pool: &mut ListPool<T>)

Shortens the list down to len elements.

Does nothing if the list is already shorter than len.

pub fn grow_at(&mut self, index: usize, count: usize, pool: &mut ListPool<T>)

Grow the list by inserting count elements at index.

The new elements are not initialized, they will contain whatever happened to be in memory. Since the memory comes from the pool, this will be either zero entity references or whatever where in a previously deallocated list.

Trait Implementations§

§

impl<T> Clone for EntityList<T>

§

fn clone(&self) -> EntityList<T>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl<T> Debug for EntityList<T>

§

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

Formats the value using the given formatter. Read more
§

impl<T> Default for EntityList<T>

Create an empty list.

§

fn default() -> EntityList<T>

Returns the “default value” for a type. Read more
§

impl<'de, T> Deserialize<'de> for EntityList<T>

§

fn deserialize<__D>( __deserializer: __D, ) -> Result<EntityList<T>, <__D as Deserializer<'de>>::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
§

impl<T> Hash for EntityList<T>

§

fn hash<__H>(&self, state: &mut __H)
where __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
§

impl<T> PartialEq for EntityList<T>

§

fn eq(&self, other: &EntityList<T>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
§

impl<T> Serialize for EntityList<T>

§

fn serialize<__S>( &self, __serializer: __S, ) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
§

impl<T> Copy for EntityList<T>

§

impl<T> Eq for EntityList<T>
where T: Eq + EntityRef + ReservedValue,

§

impl<T> StructuralPartialEq for EntityList<T>

Auto Trait Implementations§

§

impl<T> Freeze for EntityList<T>

§

impl<T> RefUnwindSafe for EntityList<T>
where T: RefUnwindSafe,

§

impl<T> Send for EntityList<T>
where T: Send,

§

impl<T> Sync for EntityList<T>
where T: Sync,

§

impl<T> Unpin for EntityList<T>
where T: Unpin,

§

impl<T> UnwindSafe for EntityList<T>
where T: UnwindSafe,

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> CloneToUninit for T
where T: Clone,

source§

unsafe fn clone_to_uninit(&self, dst: *mut T)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. Read more
§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
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> ToOwned for T
where T: Clone,

source§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

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

source§

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>,

source§

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.
source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,