Skip to main content

SplitMetadata

Struct SplitMetadata 

Source
pub struct SplitMetadata<I: Allocator> { /* private fields */ }
Expand description

SplitMetadata wrapper.

Note: this primitive isolates allocator metadata into a separate mapping (cache-line / pollution separation). It does not by itself enforce that a linear overflow cannot reach metadata — two independent mmaps may land adjacent; see the module docs. For a hard overflow barrier, wrap the data side in GuardPage.

Adding guard pages on top requires the inner data region to be OsBacked (so GuardPage<SplitMetadata<MmapBacked>> works, but GuardPage<SplitMetadata<Slab<...>>> does not — Slab is not OsBacked and GuardPage rejects it at the type level). For the HardenedSlab recipe — the recommended security composition — the guard pages wrap the OS-mapped data side and the Slab lives on top, giving the form Slab<T, GuardPage<SplitMetadata<MmapBacked>>>.

Implementations§

Source§

impl<I: Allocator> SplitMetadata<I>

Source

pub fn new(data_region: I, meta_size: usize) -> Result<Self, AllocError>

Wrap data_region and allocate a fresh metadata mmap of meta_size bytes.

Returns Err(AllocError) if the metadata mmap fails.

Source

pub fn with_meta(data_region: I, meta_region: MmapBacked) -> Self

Wrap with a pre-built metadata region. Useful when the caller wants to construct the meta MmapBacked with specific flags (huge pages, populate, etc.).

Precondition: meta_region must not overlap the data_region’s address range. A fresh MmapBacked::new(..) always satisfies this (the OS returns a distinct mapping); the caveat exists only if you hand in a region derived from the data side. Overlap would silently defeat the isolation this type provides — it is not checked here.

Source

pub fn meta_base(&self) -> NonNull<u8>

First byte of the metadata region.

Source

pub fn meta_size(&self) -> usize

Length in bytes of the metadata region.

Source

pub fn meta(&self) -> &MmapBacked

Borrow the metadata mmap directly. Mainly for callers that want to apply OsBacked ops (release_pages, protect) to the meta region independently.

Source

pub fn data(&self) -> &I

Borrow the data allocator.

Trait Implementations§

Source§

impl<I: Allocator> Allocator for SplitMetadata<I>

Source§

fn allocate(&self, layout: NonZeroLayout) -> Result<NonNull<[u8]>, AllocError>

Allocate a block satisfying layout. The returned slice’s length is at least layout.size() but may be larger.
Source§

unsafe fn usable_size( &self, ptr: NonNull<u8>, layout: NonZeroLayout, ) -> Option<usize>

Usable size of an existing allocation, if the allocator can report it. Defaults to None — implementors that track usable size override. Read more
Source§

fn capacity_bytes(&self) -> Option<usize>

Total bytes this allocator can issue, if bounded. None for unbounded allocators like System. Used by Watermark to compute thresholds.
Source§

fn corruption_events(&self) -> u64

Detected freelist / metadata corruption events observed by this allocator since construction. Read more
Source§

fn allocate_zeroed( &self, layout: NonZeroLayout, ) -> Result<NonNull<[u8]>, AllocError>

Allocate a zero-initialized block.
Source§

unsafe fn grow( &self, ptr: NonNull<u8>, old: NonZeroLayout, new: NonZeroLayout, ) -> Result<NonNull<[u8]>, AllocError>

Grow an allocation in place if possible, otherwise allocate-copy-free. Read more
Source§

unsafe fn shrink( &self, ptr: NonNull<u8>, old: NonZeroLayout, new: NonZeroLayout, ) -> Result<NonNull<[u8]>, AllocError>

Shrink an allocation in place if possible, otherwise allocate-copy-free. Read more
Source§

fn reset(&mut self) -> Result<(), AllocError>

Reclaim everything previously allocated. Default impl returns AllocError — only arena-style allocators implement a meaningful reset. Read more
Source§

impl<I: Allocator> Deallocator for SplitMetadata<I>

Source§

unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: NonZeroLayout)

Release a previously allocated block. Read more
Source§

impl<I: Allocator + FixedRange> FixedRange for SplitMetadata<I>

Source§

fn commit(&self, offset: usize, len: usize) -> Result<(), AllocError>

Forward to the data region. The metadata lives in a separate mmap, so base/size already track data_region 1:1 — no offset translation is needed, and a commit-aware consumer over a lazy_commit data region reaches the right pages.

Source§

fn base(&self) -> NonNull<u8>

First byte of the owned address range. Read more
Source§

fn size(&self) -> usize

Length in bytes of the owned address range. Read more
Source§

fn contains(&self, ptr: NonNull<u8>) -> bool

Whether ptr lies within [base, base + size). Read more
Source§

impl<I: Allocator + OsBacked> OsBacked for SplitMetadata<I>

Source§

fn base_ptr(&self) -> NonNull<u8>

First byte of the OS-managed region.
Source§

fn region_size(&self) -> usize

Length in bytes of the OS-managed region.
Source§

unsafe fn release_pages(&self, ptr: NonNull<u8>, size: usize)

Release the physical pages backing [ptr, ptr + size) to the OS while keeping the virtual address range reserved. Read more
Source§

unsafe fn protect(&self, ptr: NonNull<u8>, size: usize, flags: ProtectFlags)

Change memory protection flags on [ptr, ptr + size). Read more

Auto Trait Implementations§

§

impl<I> !Freeze for SplitMetadata<I>

§

impl<I> !RefUnwindSafe for SplitMetadata<I>

§

impl<I> !Sync for SplitMetadata<I>

§

impl<I> Send for SplitMetadata<I>
where I: Send,

§

impl<I> Unpin for SplitMetadata<I>
where I: Unpin,

§

impl<I> UnsafeUnpin for SplitMetadata<I>
where I: UnsafeUnpin,

§

impl<I> UnwindSafe for SplitMetadata<I>
where I: 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> 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>,

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.