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
impl IsolatedAlloc
Sourcefn normalized_layout(layout: Layout) -> Layout
fn normalized_layout(layout: Layout) -> Layout
For simplicity, we serve small allocations in multiples of COMPRESSION_FACTOR bytes with at least that alignment.
Sourcefn huge_normalized_layout(&self, layout: Layout) -> usize
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.
Sourcefn is_huge_alloc(&self, layout: &Layout) -> bool
fn is_huge_alloc(&self, layout: &Layout) -> bool
Determined whether a given normalized (size, align) should be sent to
alloc_huge
/ dealloc_huge
.
Sourcepub unsafe fn alloc(&mut self, layout: Layout) -> *mut u8
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()
.
Sourcepub unsafe fn alloc_zeroed(&mut self, layout: Layout) -> *mut u8
pub unsafe fn alloc_zeroed(&mut self, layout: Layout) -> *mut u8
Same as alloc
, but zeroes out the memory.
SAFETY: See alloc::alloc_zeroed()
.
Sourceunsafe fn allocate(&mut self, layout: Layout, zeroed: bool) -> *mut u8
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()
.
Sourceunsafe fn alloc_small(
page_size: usize,
layout: Layout,
page: NonNull<u8>,
pinfo: &mut DenseBitSet<usize>,
zeroed: bool,
) -> Option<*mut u8>
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.
Sourcefn add_page(&mut self) -> (NonNull<u8>, &mut DenseBitSet<usize>)
fn add_page(&mut self) -> (NonNull<u8>, &mut DenseBitSet<usize>)
Expands the available memory pool by adding one page.
Sourceunsafe fn alloc_huge(&mut self, layout: Layout) -> *mut u8
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()
.
Sourcepub unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout)
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
.
Sourceunsafe fn dealloc_small(&mut self, ptr: *mut u8, layout: Layout) -> usize
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
.
Sourceunsafe fn dealloc_huge(&mut self, ptr: *mut u8, layout: Layout)
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.
Sourcepub unsafe fn prepare_ffi(&mut self) -> Result<(), Errno>
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.
Sourcepub fn unprep_ffi(&mut self)
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.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for IsolatedAlloc
impl RefUnwindSafe for IsolatedAlloc
impl !Send for IsolatedAlloc
impl !Sync for IsolatedAlloc
impl Unpin for IsolatedAlloc
impl UnwindSafe for IsolatedAlloc
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
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