Struct IsolatedAlloc

Source
pub struct IsolatedAlloc {
    page_ptrs: Vec<NonNull<u8>>,
    page_infos: Vec<DenseBitSet<usize>>,
    huge_ptrs: Vec<(NonNull<u8>, usize)>,
    page_size: usize,
}
Expand description

A dedicated allocator for interpreter memory contents, ensuring they are stored on dedicated pages (not mixed with Miri’s own memory). This is used in native-lib mode.

Fields§

§page_ptrs: Vec<NonNull<u8>>

Pointers to page-aligned memory that has been claimed by the allocator. Every pointer here must point to a page-sized allocation claimed via mmap. These pointers are used for “small” allocations.

§page_infos: Vec<DenseBitSet<usize>>

Metadata about which bytes have been allocated on each page. The length of this vector must be the same as that of page_ptrs, and the domain size of the bitset must be exactly page_size / COMPRESSION_FACTOR.

Conceptually, each bit of the bitset represents the allocation status of one n-byte chunk on the corresponding element of page_ptrs. Thus, indexing into it should be done with a value one-nth of the corresponding offset on the matching page_ptrs element (n = COMPRESSION_FACTOR).

§huge_ptrs: Vec<(NonNull<u8>, usize)>

Pointers to multiple-page-sized allocations. These must also be page-aligned, with their size stored as the second element of the vector.

§page_size: usize

The host (not emulated) page size.

Implementations§

Source§

impl IsolatedAlloc

Source

pub fn new() -> Self

Creates an empty allocator.

Source

fn normalized_layout(layout: Layout) -> Layout

For simplicity, we serve small allocations in multiples of COMPRESSION_FACTOR bytes with at least that alignment.

Source

fn huge_normalized_layout(&self, layout: Layout) -> usize

For greater-than-page-sized allocations, returns the allocation size we need to request including the slack we need to satisfy the alignment request.

Source

fn is_huge_alloc(&self, layout: &Layout) -> bool

Determined whether a given normalized (size, align) should be sent to alloc_huge / dealloc_huge.

Source

pub unsafe fn alloc(&mut self, layout: Layout) -> *mut u8

Allocates memory as described in Layout. This memory should be deallocated by calling dealloc on this same allocator.

SAFETY: See alloc::alloc().

Source

pub unsafe fn alloc_zeroed(&mut self, layout: Layout) -> *mut u8

Same as alloc, but zeroes out the memory.

SAFETY: See alloc::alloc_zeroed().

Source

unsafe fn allocate(&mut self, layout: Layout, zeroed: bool) -> *mut u8

Abstracts over the logic of alloc_zeroed vs alloc, as determined by the zeroed argument.

SAFETY: See alloc::alloc().

Source

unsafe fn alloc_small( page_size: usize, layout: Layout, page: NonNull<u8>, pinfo: &mut DenseBitSet<usize>, zeroed: bool, ) -> Option<*mut u8>

Used internally by allocate to abstract over some logic.

SAFETY: page must be a page-aligned pointer to an allocated page, where the allocation is (at least) page_size bytes.

Source

fn add_page(&mut self) -> (NonNull<u8>, &mut DenseBitSet<usize>)

Expands the available memory pool by adding one page.

Source

unsafe fn alloc_huge(&mut self, layout: Layout) -> *mut u8

Allocates in multiples of one page on the host system. Will always be zeroed.

SAFETY: Same as alloc().

Source

pub unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout)

Deallocates a pointer from this allocator.

SAFETY: This pointer must have been allocated by calling alloc() (or alloc_zeroed()) with the same layout as the one passed on this same IsolatedAlloc.

Source

unsafe fn dealloc_small(&mut self, ptr: *mut u8, layout: Layout) -> usize

Returns the index of the page that this was deallocated from.

SAFETY: the pointer must have been allocated with alloc_small.

Source

unsafe fn dealloc_huge(&mut self, ptr: *mut u8, layout: Layout)

SAFETY: Same as dealloc() with the added requirement that layout must ask for a size larger than the host pagesize.

Source

pub fn pages(&self) -> Vec<usize>

Returns a vector of page addresses managed by the allocator.

Source

pub unsafe fn prepare_ffi(&mut self) -> Result<(), Errno>

Protects all owned memory as PROT_NONE, preventing accesses.

SAFETY: Accessing memory after this point will result in a segfault unless it is first unprotected.

Source

pub fn unprep_ffi(&mut self)

Deprotects all owned memory by setting it to RW. Erroring here is very likely unrecoverable, so it may panic if applying those permissions fails.

Source

unsafe fn mprotect(&mut self, prot: ProtFlags) -> Result<(), Errno>

Applies prot to every page managed by the allocator.

SAFETY: Accessing memory in violation of the protection flags will trigger a segfault.

Trait Implementations§

Source§

impl Debug for IsolatedAlloc

Source§

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

Formats the value using the given formatter. 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> Same for T

Source§

type Output = T

Should always be Self
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.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

Layout§

Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain repr(...) attributes. Please see the Rust Reference's “Type Layout” chapter for details on type layout guarantees.

Size: 80 bytes