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>
impl<I: Allocator> SplitMetadata<I>
Sourcepub fn new(data_region: I, meta_size: usize) -> Result<Self, AllocError>
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.
Sourcepub fn with_meta(data_region: I, meta_region: MmapBacked) -> Self
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.
Sourcepub fn meta(&self) -> &MmapBacked
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.
Trait Implementations§
Source§impl<I: Allocator> Allocator for SplitMetadata<I>
impl<I: Allocator> Allocator for SplitMetadata<I>
Source§fn allocate(&self, layout: NonZeroLayout) -> Result<NonNull<[u8]>, AllocError>
fn allocate(&self, layout: NonZeroLayout) -> Result<NonNull<[u8]>, AllocError>
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>
unsafe fn usable_size( &self, ptr: NonNull<u8>, layout: NonZeroLayout, ) -> Option<usize>
None — implementors that track usable size
override. Read moreSource§fn capacity_bytes(&self) -> Option<usize>
fn capacity_bytes(&self) -> Option<usize>
None for unbounded
allocators like System. Used by Watermark to compute thresholds.Source§fn corruption_events(&self) -> u64
fn corruption_events(&self) -> u64
Source§fn allocate_zeroed(
&self,
layout: NonZeroLayout,
) -> Result<NonNull<[u8]>, AllocError>
fn allocate_zeroed( &self, layout: NonZeroLayout, ) -> Result<NonNull<[u8]>, AllocError>
Source§unsafe fn grow(
&self,
ptr: NonNull<u8>,
old: NonZeroLayout,
new: NonZeroLayout,
) -> Result<NonNull<[u8]>, AllocError>
unsafe fn grow( &self, ptr: NonNull<u8>, old: NonZeroLayout, new: NonZeroLayout, ) -> Result<NonNull<[u8]>, AllocError>
Source§unsafe fn shrink(
&self,
ptr: NonNull<u8>,
old: NonZeroLayout,
new: NonZeroLayout,
) -> Result<NonNull<[u8]>, AllocError>
unsafe fn shrink( &self, ptr: NonNull<u8>, old: NonZeroLayout, new: NonZeroLayout, ) -> Result<NonNull<[u8]>, AllocError>
Source§impl<I: Allocator> Deallocator for SplitMetadata<I>
impl<I: Allocator> Deallocator for SplitMetadata<I>
Source§unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: NonZeroLayout)
unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: NonZeroLayout)
Source§impl<I: Allocator + FixedRange> FixedRange for SplitMetadata<I>
impl<I: Allocator + FixedRange> FixedRange for SplitMetadata<I>
Source§fn commit(&self, offset: usize, len: usize) -> Result<(), AllocError>
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.