pub struct Allocation<Prov: Provenance = CtfeProvenance, Extra = (), Bytes = Box<[u8]>> {
bytes: Bytes,
provenance: ProvenanceMap<Prov>,
init_mask: InitMask,
pub align: Align,
pub mutability: Mutability,
pub extra: Extra,
}
Expand description
This type represents an Allocation in the Miri/CTFE core engine.
Its public API is rather low-level, working directly with allocation offsets and a custom error
type to account for the lack of an AllocId on this level. The Miri/CTFE core engine memory
module provides higher-level access.
Fields§
§bytes: Bytes
The actual bytes of the allocation. Note that the bytes of a pointer represent the offset of the pointer.
provenance: ProvenanceMap<Prov>
Maps from byte addresses to extra provenance data for each pointer.
Only the first byte of a pointer is inserted into the map; i.e.,
every entry in this map applies to pointer_size
consecutive bytes starting
at the given offset.
init_mask: InitMask
Denotes which part of this allocation is initialized.
align: Align
The alignment of the allocation to detect unaligned reads.
(Align
guarantees that this is a power of two.)
mutability: Mutability
true
if the allocation is mutable.
Also used by codegen to determine if a static should be put into mutable memory,
which happens for static mut
and static
with interior mutability.
extra: Extra
Extra state for the machine.
Implementations§
source§impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes>
impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes>
sourcepub fn from_bytes<'a>(
slice: impl Into<Cow<'a, [u8]>>,
align: Align,
mutability: Mutability,
) -> Self
pub fn from_bytes<'a>( slice: impl Into<Cow<'a, [u8]>>, align: Align, mutability: Mutability, ) -> Self
Creates an allocation initialized by the given bytes
pub fn from_bytes_byte_aligned_immutable<'a>( slice: impl Into<Cow<'a, [u8]>>, ) -> Self
fn uninit_inner<R>( size: Size, align: Align, fail: impl FnOnce() -> R, ) -> Result<Self, R>
sourcepub fn try_uninit<'tcx>(size: Size, align: Align) -> InterpResult<'tcx, Self>
pub fn try_uninit<'tcx>(size: Size, align: Align) -> InterpResult<'tcx, Self>
Try to create an Allocation of size
bytes, failing if there is not enough memory
available to the compiler to do so.
sourcepub fn uninit(size: Size, align: Align) -> Self
pub fn uninit(size: Size, align: Align) -> Self
Try to create an Allocation of size
bytes, panics if there is not enough memory
available to the compiler to do so.
Example use case: To obtain an Allocation filled with specific data, first call this function and then call write_scalar to fill in the right data.
sourcepub fn with_extra<Extra>(self, extra: Extra) -> Allocation<Prov, Extra, Bytes>
pub fn with_extra<Extra>(self, extra: Extra) -> Allocation<Prov, Extra, Bytes>
Add the extra.
source§impl Allocation
impl Allocation
sourcepub fn adjust_from_tcx<'tcx, Prov: Provenance, Bytes: AllocBytes>(
&self,
cx: &impl HasDataLayout,
alloc_bytes: impl FnMut(&[u8], Align) -> InterpResult<'tcx, Bytes>,
adjust_ptr: impl FnMut(Pointer<CtfeProvenance>) -> InterpResult<'tcx, Pointer<Prov>>,
) -> InterpResult<'tcx, Allocation<Prov, (), Bytes>>
pub fn adjust_from_tcx<'tcx, Prov: Provenance, Bytes: AllocBytes>( &self, cx: &impl HasDataLayout, alloc_bytes: impl FnMut(&[u8], Align) -> InterpResult<'tcx, Bytes>, adjust_ptr: impl FnMut(Pointer<CtfeProvenance>) -> InterpResult<'tcx, Pointer<Prov>>, ) -> InterpResult<'tcx, Allocation<Prov, (), Bytes>>
Adjust allocation from the ones in tcx
to a custom Machine instance
with a different Provenance
and Byte
type.
source§impl<Prov: Provenance, Extra, Bytes: AllocBytes> Allocation<Prov, Extra, Bytes>
impl<Prov: Provenance, Extra, Bytes: AllocBytes> Allocation<Prov, Extra, Bytes>
Raw accessors. Provide access to otherwise private bytes.
pub fn len(&self) -> usize
pub fn size(&self) -> Size
sourcepub fn inspect_with_uninit_and_ptr_outside_interpreter(
&self,
range: Range<usize>,
) -> &[u8] ⓘ
pub fn inspect_with_uninit_and_ptr_outside_interpreter( &self, range: Range<usize>, ) -> &[u8] ⓘ
Looks at a slice which may contain uninitialized bytes or provenance. This differs
from get_bytes_with_uninit_and_ptr
in that it does no provenance checks (even on the
edges) at all.
This must not be used for reads affecting the interpreter execution.
sourcepub fn provenance(&self) -> &ProvenanceMap<Prov>
pub fn provenance(&self) -> &ProvenanceMap<Prov>
Returns the provenance map.
source§impl<Prov: Provenance, Extra, Bytes: AllocBytes> Allocation<Prov, Extra, Bytes>
impl<Prov: Provenance, Extra, Bytes: AllocBytes> Allocation<Prov, Extra, Bytes>
Byte accessors.
sourcepub fn get_bytes_unchecked(&self, range: AllocRange) -> &[u8] ⓘ
pub fn get_bytes_unchecked(&self, range: AllocRange) -> &[u8] ⓘ
This is the entirely abstraction-violating way to just grab the raw bytes without caring about provenance or initialization.
This function also guarantees that the resulting pointer will remain stable
even when new allocations are pushed to the HashMap
. mem_copy_repeatedly
relies
on that.
sourcepub fn get_bytes_strip_provenance(
&self,
cx: &impl HasDataLayout,
range: AllocRange,
) -> AllocResult<&[u8]>
pub fn get_bytes_strip_provenance( &self, cx: &impl HasDataLayout, range: AllocRange, ) -> AllocResult<&[u8]>
Checks that these bytes are initialized, and then strip provenance (if possible) and return them.
It is the caller’s responsibility to check bounds and alignment beforehand.
Most likely, you want to use the PlaceTy
and OperandTy
-based methods
on InterpCx
instead.
sourcepub fn get_bytes_unchecked_for_overwrite(
&mut self,
cx: &impl HasDataLayout,
range: AllocRange,
) -> AllocResult<&mut [u8]>
pub fn get_bytes_unchecked_for_overwrite( &mut self, cx: &impl HasDataLayout, range: AllocRange, ) -> AllocResult<&mut [u8]>
This is the entirely abstraction-violating way to just get mutable access to the raw bytes. Just calling this already marks everything as defined and removes provenance, so be sure to actually overwrite all the data there!
It is the caller’s responsibility to check bounds and alignment beforehand.
Most likely, you want to use the PlaceTy
and OperandTy
-based methods
on InterpCx
instead.
sourcepub fn get_bytes_unchecked_for_overwrite_ptr(
&mut self,
cx: &impl HasDataLayout,
range: AllocRange,
) -> AllocResult<*mut [u8]>
pub fn get_bytes_unchecked_for_overwrite_ptr( &mut self, cx: &impl HasDataLayout, range: AllocRange, ) -> AllocResult<*mut [u8]>
A raw pointer variant of get_bytes_unchecked_for_overwrite
that avoids invalidating existing immutable aliases
into this memory.
sourcepub fn get_bytes_unchecked_raw_mut(&mut self) -> *mut u8
pub fn get_bytes_unchecked_raw_mut(&mut self) -> *mut u8
This gives direct mutable access to the entire buffer, just exposing their internal state
without resetting anything. Directly exposes AllocBytes::as_mut_ptr
. Only works if
OFFSET_IS_ADDR
is true.
sourcepub fn get_bytes_unchecked_raw(&self) -> *const u8
pub fn get_bytes_unchecked_raw(&self) -> *const u8
This gives direct immutable access to the entire buffer, just exposing their internal state
without resetting anything. Directly exposes AllocBytes::as_ptr
. Only works if
OFFSET_IS_ADDR
is true.
source§impl<Prov: Provenance, Extra, Bytes: AllocBytes> Allocation<Prov, Extra, Bytes>
impl<Prov: Provenance, Extra, Bytes: AllocBytes> Allocation<Prov, Extra, Bytes>
Reading and writing.
sourcefn mark_init(&mut self, range: AllocRange, is_init: bool)
fn mark_init(&mut self, range: AllocRange, is_init: bool)
Sets the init bit for the given range.
sourcepub fn read_scalar(
&self,
cx: &impl HasDataLayout,
range: AllocRange,
read_provenance: bool,
) -> AllocResult<Scalar<Prov>>
pub fn read_scalar( &self, cx: &impl HasDataLayout, range: AllocRange, read_provenance: bool, ) -> AllocResult<Scalar<Prov>>
Reads a non-ZST scalar.
If read_provenance
is true
, this will also read provenance; otherwise (if the machine
supports that) provenance is entirely ignored.
ZSTs can’t be read because in order to obtain a Pointer
, we need to check
for ZSTness anyway due to integer pointers being valid for ZSTs.
It is the caller’s responsibility to check bounds and alignment beforehand.
Most likely, you want to call InterpCx::read_scalar
instead of this method.
sourcepub fn write_scalar(
&mut self,
cx: &impl HasDataLayout,
range: AllocRange,
val: Scalar<Prov>,
) -> AllocResult
pub fn write_scalar( &mut self, cx: &impl HasDataLayout, range: AllocRange, val: Scalar<Prov>, ) -> AllocResult
Writes a non-ZST scalar.
ZSTs can’t be read because in order to obtain a Pointer
, we need to check
for ZSTness anyway due to integer pointers being valid for ZSTs.
It is the caller’s responsibility to check bounds and alignment beforehand.
Most likely, you want to call InterpCx::write_scalar
instead of this method.
sourcepub fn write_uninit(
&mut self,
cx: &impl HasDataLayout,
range: AllocRange,
) -> AllocResult
pub fn write_uninit( &mut self, cx: &impl HasDataLayout, range: AllocRange, ) -> AllocResult
Write “uninit” to the given memory range.
sourcepub fn clear_provenance(
&mut self,
cx: &impl HasDataLayout,
range: AllocRange,
) -> AllocResult
pub fn clear_provenance( &mut self, cx: &impl HasDataLayout, range: AllocRange, ) -> AllocResult
Remove all provenance in the given memory range.
sourcepub fn provenance_apply_copy(&mut self, copy: ProvenanceCopy<Prov>)
pub fn provenance_apply_copy(&mut self, copy: ProvenanceCopy<Prov>)
Applies a previously prepared provenance copy.
The affected range, as defined in the parameters to provenance().prepare_copy
is expected
to be clear of provenance.
This is dangerous to use as it can violate internal Allocation
invariants!
It only exists to support an efficient implementation of mem_copy_repeatedly
.
sourcepub fn init_mask_apply_copy(
&mut self,
copy: InitCopy,
range: AllocRange,
repeat: u64,
)
pub fn init_mask_apply_copy( &mut self, copy: InitCopy, range: AllocRange, repeat: u64, )
Applies a previously prepared copy of the init mask.
This is dangerous to use as it can violate internal Allocation
invariants!
It only exists to support an efficient implementation of mem_copy_repeatedly
.
Trait Implementations§
source§impl<'tcx> ArenaAllocatable<'tcx> for Allocation
impl<'tcx> ArenaAllocatable<'tcx> for Allocation
fn allocate_on(self, arena: &'tcx Arena<'tcx>) -> &'tcx mut Self
fn allocate_from_iter( arena: &'tcx Arena<'tcx>, iter: impl IntoIterator<Item = Self>, ) -> &'tcx mut [Self]
source§impl<'tcx> Borrow<Allocation> for InternedInSet<'tcx, Allocation>
impl<'tcx> Borrow<Allocation> for InternedInSet<'tcx, Allocation>
source§fn borrow<'a>(&'a self) -> &'a Allocation
fn borrow<'a>(&'a self) -> &'a Allocation
source§impl<Prov: Clone + Provenance, Extra: Clone, Bytes: Clone> Clone for Allocation<Prov, Extra, Bytes>
impl<Prov: Clone + Provenance, Extra: Clone, Bytes: Clone> Clone for Allocation<Prov, Extra, Bytes>
source§fn clone(&self) -> Allocation<Prov, Extra, Bytes>
fn clone(&self) -> Allocation<Prov, Extra, Bytes>
source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moresource§impl<Prov: Provenance, Extra, Bytes, __D: TyDecoder> Decodable<__D> for Allocation<Prov, Extra, Bytes>
impl<Prov: Provenance, Extra, Bytes, __D: TyDecoder> Decodable<__D> for Allocation<Prov, Extra, Bytes>
source§impl<Prov: Provenance, Extra, Bytes, __E: TyEncoder> Encodable<__E> for Allocation<Prov, Extra, Bytes>
impl<Prov: Provenance, Extra, Bytes, __E: TyEncoder> Encodable<__E> for Allocation<Prov, Extra, Bytes>
source§impl Hash for Allocation
impl Hash for Allocation
source§impl<'__ctx, Prov, Extra, Bytes> HashStable<StableHashingContext<'__ctx>> for Allocation<Prov, Extra, Bytes>where
Bytes: HashStable<StableHashingContext<'__ctx>>,
Prov: HashStable<StableHashingContext<'__ctx>> + Provenance,
Extra: HashStable<StableHashingContext<'__ctx>>,
impl<'__ctx, Prov, Extra, Bytes> HashStable<StableHashingContext<'__ctx>> for Allocation<Prov, Extra, Bytes>where
Bytes: HashStable<StableHashingContext<'__ctx>>,
Prov: HashStable<StableHashingContext<'__ctx>> + Provenance,
Extra: HashStable<StableHashingContext<'__ctx>>,
fn hash_stable( &self, __hcx: &mut StableHashingContext<'__ctx>, __hasher: &mut StableHasher, )
source§impl<Prov: PartialEq + Provenance, Extra: PartialEq, Bytes: PartialEq> PartialEq for Allocation<Prov, Extra, Bytes>
impl<Prov: PartialEq + Provenance, Extra: PartialEq, Bytes: PartialEq> PartialEq for Allocation<Prov, Extra, Bytes>
impl<Prov: Eq + Provenance, Extra: Eq, Bytes: Eq> Eq for Allocation<Prov, Extra, Bytes>
impl<Prov: Provenance, Extra, Bytes> StructuralPartialEq for Allocation<Prov, Extra, Bytes>
Auto Trait Implementations§
impl<Prov, Extra, Bytes> DynSend for Allocation<Prov, Extra, Bytes>
impl<Prov, Extra, Bytes> DynSync for Allocation<Prov, Extra, Bytes>
impl<Prov, Extra, Bytes> Freeze for Allocation<Prov, Extra, Bytes>
impl<Prov, Extra, Bytes> RefUnwindSafe for Allocation<Prov, Extra, Bytes>
impl<Prov, Extra, Bytes> Send for Allocation<Prov, Extra, Bytes>
impl<Prov, Extra, Bytes> Sync for Allocation<Prov, Extra, Bytes>
impl<Prov, Extra, Bytes> Unpin for Allocation<Prov, Extra, Bytes>
impl<Prov, Extra, Bytes> UnwindSafe for Allocation<Prov, Extra, Bytes>
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
source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)source§impl<T, R> CollectAndApply<T, R> for T
impl<T, R> CollectAndApply<T, R> for T
source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key
and return true
if they are equal.source§impl<T> Filterable for T
impl<T> Filterable for T
source§fn filterable(
self,
filter_name: &'static str,
) -> RequestFilterDataProvider<T, fn(_: DataRequest<'_>) -> bool>
fn filterable( self, filter_name: &'static str, ) -> RequestFilterDataProvider<T, fn(_: DataRequest<'_>) -> bool>
source§impl<T> Instrument for T
impl<T> Instrument for T
source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
source§impl<T> IntoEither for T
impl<T> IntoEither for T
source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moresource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moresource§impl<P> IntoQueryParam<P> for P
impl<P> IntoQueryParam<P> for P
fn into_query_param(self) -> P
source§impl<T> MaybeResult<T> for T
impl<T> MaybeResult<T> for T
source§impl<T> Pointable for T
impl<T> Pointable for T
source§impl<I, T, U> Upcast<I, U> for Twhere
U: UpcastFrom<I, T>,
impl<I, T, U> Upcast<I, U> for Twhere
U: UpcastFrom<I, T>,
source§impl<I, T> UpcastFrom<I, T> for T
impl<I, T> UpcastFrom<I, T> for T
fn upcast_from(from: T, _tcx: I) -> T
source§impl<Tcx, T> Value<Tcx> for Twhere
Tcx: DepContext,
impl<Tcx, T> Value<Tcx> for Twhere
Tcx: DepContext,
default fn from_cycle_error( tcx: Tcx, cycle_error: &CycleError, _guar: ErrorGuaranteed, ) -> T
source§impl<T> WithSubscriber for T
impl<T> WithSubscriber for T
source§fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
source§fn with_current_subscriber(self) -> WithDispatch<Self>
fn with_current_subscriber(self) -> WithDispatch<Self>
impl<'a, T> Captures<'a> for Twhere
T: ?Sized,
impl<T> ErasedDestructor for Twhere
T: 'static,
impl<T> MaybeSendSync for T
Layout§
Note: Unable to compute type layout, possibly due to this type having generic parameters. Layout can only be computed for concrete, fully-instantiated types.