Struct rustc_middle::mir::interpret::allocation::Allocation
source · [−]pub struct Allocation<Tag = AllocId, Extra = ()> {
bytes: Box<[u8]>,
relocations: Relocations<Tag>,
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: Box<[u8]>The actual bytes of the allocation. Note that the bytes of a pointer represent the offset of the pointer.
relocations: Relocations<Tag>Maps from byte addresses to extra 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: InitMaskDenotes which part of this allocation is initialized.
align: AlignThe alignment of the allocation to detect unaligned reads.
(Align guarantees that this is a power of two.)
mutability: Mutabilitytrue 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: ExtraExtra state for the machine.
Implementations
sourceimpl<Tag> Allocation<Tag>
impl<Tag> Allocation<Tag>
sourceimpl Allocation
impl Allocation
sourcepub fn convert_tag_add_extra<Tag, Extra>(
self,
cx: &impl HasDataLayout,
extra: Extra,
tagger: impl FnMut(Pointer<AllocId>) -> Pointer<Tag>
) -> Allocation<Tag, Extra>
pub fn convert_tag_add_extra<Tag, Extra>(
self,
cx: &impl HasDataLayout,
extra: Extra,
tagger: impl FnMut(Pointer<AllocId>) -> Pointer<Tag>
) -> Allocation<Tag, Extra>
Convert Tag and add Extra fields
sourceimpl<Tag, Extra> Allocation<Tag, Extra>
impl<Tag, Extra> Allocation<Tag, Extra>
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]ⓘNotable traits for &'_ [u8]impl<'_> Read for &'_ [u8]impl<'_> Write for &'_ mut [u8]
pub fn inspect_with_uninit_and_ptr_outside_interpreter(
&self,
range: Range<usize>
) -> &[u8]ⓘNotable traits for &'_ [u8]impl<'_> Read for &'_ [u8]impl<'_> Write for &'_ mut [u8]
Looks at a slice which may describe uninitialized bytes or describe a relocation. This differs
from get_bytes_with_uninit_and_ptr in that it does no relocation checks (even on the
edges) at all.
This must not be used for reads affecting the interpreter execution.
sourcepub fn relocations(&self) -> &Relocations<Tag>
pub fn relocations(&self) -> &Relocations<Tag>
Returns the relocation list.
sourceimpl<Tag: Provenance, Extra> Allocation<Tag, Extra>
impl<Tag: Provenance, Extra> Allocation<Tag, Extra>
Byte accessors.
sourcefn get_bytes_internal(
&self,
cx: &impl HasDataLayout,
range: AllocRange,
check_init_and_ptr: bool
) -> Result<&[u8], AllocError>
fn get_bytes_internal(
&self,
cx: &impl HasDataLayout,
range: AllocRange,
check_init_and_ptr: bool
) -> Result<&[u8], AllocError>
The last argument controls whether we error out when there are uninitialized
or pointer bytes. You should never call this, call get_bytes or
get_bytes_with_uninit_and_ptr instead,
This function also guarantees that the resulting pointer will remain stable
even when new allocations are pushed to the HashMap. copy_repeatedly relies
on that.
It is the caller’s responsibility to check bounds and alignment beforehand.
sourcepub fn get_bytes(
&self,
cx: &impl HasDataLayout,
range: AllocRange
) -> Result<&[u8], AllocError>
pub fn get_bytes(
&self,
cx: &impl HasDataLayout,
range: AllocRange
) -> Result<&[u8], AllocError>
Checks that these bytes are initialized and not pointer bytes, and then return them as a slice.
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_with_uninit_and_ptr(
&self,
cx: &impl HasDataLayout,
range: AllocRange
) -> Result<&[u8], AllocError>
pub fn get_bytes_with_uninit_and_ptr(
&self,
cx: &impl HasDataLayout,
range: AllocRange
) -> Result<&[u8], AllocError>
It is the caller’s responsibility to handle uninitialized and pointer bytes. However, this still checks that there are no relocations on the edges.
It is the caller’s responsibility to check bounds and alignment beforehand.
sourcepub fn get_bytes_mut(
&mut self,
cx: &impl HasDataLayout,
range: AllocRange
) -> Result<&mut [u8], AllocError>
pub fn get_bytes_mut(
&mut self,
cx: &impl HasDataLayout,
range: AllocRange
) -> Result<&mut [u8], AllocError>
Just calling this already marks everything as defined and removes relocations, so be sure to actually put 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_mut_ptr(
&mut self,
cx: &impl HasDataLayout,
range: AllocRange
) -> Result<*mut [u8], AllocError>
pub fn get_bytes_mut_ptr(
&mut self,
cx: &impl HasDataLayout,
range: AllocRange
) -> Result<*mut [u8], AllocError>
A raw pointer variant of get_bytes_mut that avoids invalidating existing aliases into this memory.
sourceimpl<Tag: Provenance, Extra> Allocation<Tag, Extra>
impl<Tag: Provenance, Extra> Allocation<Tag, Extra>
Reading and writing.
sourcepub fn check_bytes(
&self,
cx: &impl HasDataLayout,
range: AllocRange,
allow_uninit_and_ptr: bool
) -> Result<(), AllocError>
pub fn check_bytes(
&self,
cx: &impl HasDataLayout,
range: AllocRange,
allow_uninit_and_ptr: bool
) -> Result<(), AllocError>
Validates that ptr.offset and ptr.offset + size do not point to the middle of a
relocation. If allow_uninit_and_ptr is false, also enforces that the memory in the
given range contains neither relocations nor uninitialized bytes.
sourcepub fn read_scalar(
&self,
cx: &impl HasDataLayout,
range: AllocRange
) -> Result<ScalarMaybeUninit<Tag>, AllocError>
pub fn read_scalar(
&self,
cx: &impl HasDataLayout,
range: AllocRange
) -> Result<ScalarMaybeUninit<Tag>, AllocError>
Reads 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::read_scalar instead of this method.
sourcepub fn write_scalar(
&mut self,
cx: &impl HasDataLayout,
range: AllocRange,
val: ScalarMaybeUninit<Tag>
) -> Result<(), AllocError>
pub fn write_scalar(
&mut self,
cx: &impl HasDataLayout,
range: AllocRange,
val: ScalarMaybeUninit<Tag>
) -> Result<(), AllocError>
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.
sourceimpl<Tag: Copy, Extra> Allocation<Tag, Extra>
impl<Tag: Copy, Extra> Allocation<Tag, Extra>
Relocations.
sourcepub fn get_relocations(
&self,
cx: &impl HasDataLayout,
range: AllocRange
) -> &[(Size, Tag)]
pub fn get_relocations(
&self,
cx: &impl HasDataLayout,
range: AllocRange
) -> &[(Size, Tag)]
Returns all relocations overlapping with the given pointer-offset pair.
sourcefn check_relocations(
&self,
cx: &impl HasDataLayout,
range: AllocRange
) -> Result<(), AllocError>
fn check_relocations(
&self,
cx: &impl HasDataLayout,
range: AllocRange
) -> Result<(), AllocError>
Checks that there are no relocations overlapping with the given range.
sourcefn clear_relocations(
&mut self,
cx: &impl HasDataLayout,
range: AllocRange
) -> Result<(), AllocError> where
Tag: Provenance,
fn clear_relocations(
&mut self,
cx: &impl HasDataLayout,
range: AllocRange
) -> Result<(), AllocError> where
Tag: Provenance,
Removes all relocations inside the given range. If there are relocations overlapping with the edges, they are removed as well and the bytes they cover are marked as uninitialized. This is a somewhat odd “spooky action at a distance”, but it allows strictly more code to run than if we would just error immediately in that case.
sourcefn check_relocation_edges(
&self,
cx: &impl HasDataLayout,
range: AllocRange
) -> Result<(), AllocError>
fn check_relocation_edges(
&self,
cx: &impl HasDataLayout,
range: AllocRange
) -> Result<(), AllocError>
Errors if there are relocations overlapping with the edges of the given memory range.
sourceimpl<Tag: Copy, Extra> Allocation<Tag, Extra>
impl<Tag: Copy, Extra> Allocation<Tag, Extra>
pub fn prepare_relocation_copy(
&self,
cx: &impl HasDataLayout,
src: AllocRange,
dest: Size,
count: u64
) -> AllocationRelocations<Tag>
sourcepub fn mark_relocation_range(&mut self, relocations: AllocationRelocations<Tag>)
pub fn mark_relocation_range(&mut self, relocations: AllocationRelocations<Tag>)
Applies a relocation copy.
The affected range, as defined in the parameters to prepare_relocation_copy is expected
to be clear of relocations.
sourceimpl<Tag: Copy, Extra> Allocation<Tag, Extra>
impl<Tag: Copy, Extra> Allocation<Tag, Extra>
Uninitialized bytes.
sourcefn is_init(&self, range: AllocRange) -> Result<(), Range<Size>>
fn is_init(&self, range: AllocRange) -> Result<(), Range<Size>>
Checks whether the given range is entirely initialized.
Returns Ok(()) if it’s initialized. Otherwise returns the range of byte
indexes of the first contiguous uninitialized access.
sourcefn check_init(&self, range: AllocRange) -> Result<(), AllocError>
fn check_init(&self, range: AllocRange) -> Result<(), AllocError>
Checks that a range of bytes is initialized. If not, returns the InvalidUninitBytes
error which will report the first range of bytes which is uninitialized.
pub fn mark_init(&mut self, range: AllocRange, is_init: bool)
sourceimpl<Tag, Extra> Allocation<Tag, Extra>
impl<Tag, Extra> Allocation<Tag, Extra>
Transferring the initialization mask to other allocations.
sourcepub fn compress_uninit_range(&self, range: AllocRange) -> InitMaskCompressed
pub fn compress_uninit_range(&self, range: AllocRange) -> InitMaskCompressed
Creates a run-length encoding of the initialization mask; panics if range is empty.
This is essentially a more space-efficient version of
InitMask::range_as_init_chunks(...).collect::<Vec<_>>().
sourcepub fn mark_compressed_init_range(
&mut self,
defined: &InitMaskCompressed,
range: AllocRange,
repeat: u64
)
pub fn mark_compressed_init_range(
&mut self,
defined: &InitMaskCompressed,
range: AllocRange,
repeat: u64
)
Applies multiple instances of the run-length encoding to the initialization mask.
Trait Implementations
sourceimpl<'tcx> ArenaAllocatable<'tcx, IsNotCopy> for Allocation
impl<'tcx> ArenaAllocatable<'tcx, IsNotCopy> for Allocation
fn allocate_on<'a>(self, arena: &'a Arena<'tcx>) -> &'a mut Self
fn allocate_from_iter<'a>(
arena: &'a Arena<'tcx>,
iter: impl IntoIterator<Item = Self>
) -> &'a mut [Self]ⓘNotable traits for &'_ [u8]impl<'_> Read for &'_ [u8]impl<'_> Write for &'_ mut [u8]
sourceimpl<'tcx> Borrow<Allocation<AllocId, ()>> for Interned<'tcx, Allocation>
impl<'tcx> Borrow<Allocation<AllocId, ()>> for Interned<'tcx, Allocation>
sourcefn borrow<'a>(&'a self) -> &'a Allocation
fn borrow<'a>(&'a self) -> &'a Allocation
Immutably borrows from an owned value. Read more
sourceimpl<Tag: Clone, Extra: Clone> Clone for Allocation<Tag, Extra>
impl<Tag: Clone, Extra: Clone> Clone for Allocation<Tag, Extra>
sourcefn clone(&self) -> Allocation<Tag, Extra>
fn clone(&self) -> Allocation<Tag, Extra>
Returns a copy of the value. Read more
1.0.0 · sourcefn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from source. Read more
sourceimpl<Tag: Debug, Extra: Debug> Debug for Allocation<Tag, Extra>
impl<Tag: Debug, Extra: Debug> Debug for Allocation<Tag, Extra>
sourceimpl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for &'tcx Allocation
impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for &'tcx Allocation
sourceimpl<'tcx, Tag, Extra, __D: TyDecoder<'tcx>> Decodable<__D> for Allocation<Tag, Extra> where
Tag: Decodable<__D>,
Extra: Decodable<__D>,
impl<'tcx, Tag, Extra, __D: TyDecoder<'tcx>> Decodable<__D> for Allocation<Tag, Extra> where
Tag: Decodable<__D>,
Extra: Decodable<__D>,
sourceimpl<'tcx, Tag, Extra, __E: TyEncoder<'tcx>> Encodable<__E> for Allocation<Tag, Extra> where
Tag: Encodable<__E>,
Extra: Encodable<__E>,
impl<'tcx, Tag, Extra, __E: TyEncoder<'tcx>> Encodable<__E> for Allocation<Tag, Extra> where
Tag: Encodable<__E>,
Extra: Encodable<__E>,
sourceimpl<Tag: Hash, Extra: Hash> Hash for Allocation<Tag, Extra>
impl<Tag: Hash, Extra: Hash> Hash for Allocation<Tag, Extra>
sourceimpl<'__ctx, Tag, Extra> HashStable<StableHashingContext<'__ctx>> for Allocation<Tag, Extra> where
Tag: HashStable<StableHashingContext<'__ctx>>,
Extra: HashStable<StableHashingContext<'__ctx>>,
impl<'__ctx, Tag, Extra> HashStable<StableHashingContext<'__ctx>> for Allocation<Tag, Extra> where
Tag: HashStable<StableHashingContext<'__ctx>>,
Extra: HashStable<StableHashingContext<'__ctx>>,
fn hash_stable(
&self,
__hcx: &mut StableHashingContext<'__ctx>,
__hasher: &mut StableHasher
)
sourceimpl<'a, 'tcx> Lift<'tcx> for &'a Allocation
impl<'a, 'tcx> Lift<'tcx> for &'a Allocation
type Lifted = &'tcx Allocation
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted>
sourceimpl<Tag: Ord, Extra: Ord> Ord for Allocation<Tag, Extra>
impl<Tag: Ord, Extra: Ord> Ord for Allocation<Tag, Extra>
sourceimpl<Tag: PartialEq, Extra: PartialEq> PartialEq<Allocation<Tag, Extra>> for Allocation<Tag, Extra>
impl<Tag: PartialEq, Extra: PartialEq> PartialEq<Allocation<Tag, Extra>> for Allocation<Tag, Extra>
sourcefn eq(&self, other: &Allocation<Tag, Extra>) -> bool
fn eq(&self, other: &Allocation<Tag, Extra>) -> bool
This method tests for self and other values to be equal, and is used
by ==. Read more
sourcefn ne(&self, other: &Allocation<Tag, Extra>) -> bool
fn ne(&self, other: &Allocation<Tag, Extra>) -> bool
This method tests for !=.
sourceimpl<Tag: PartialOrd, Extra: PartialOrd> PartialOrd<Allocation<Tag, Extra>> for Allocation<Tag, Extra>
impl<Tag: PartialOrd, Extra: PartialOrd> PartialOrd<Allocation<Tag, Extra>> for Allocation<Tag, Extra>
sourcefn partial_cmp(&self, other: &Allocation<Tag, Extra>) -> Option<Ordering>
fn partial_cmp(&self, other: &Allocation<Tag, Extra>) -> Option<Ordering>
This method returns an ordering between self and other values if one exists. Read more
1.0.0 · sourcefn lt(&self, other: &Rhs) -> bool
fn lt(&self, other: &Rhs) -> bool
This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · sourcefn le(&self, other: &Rhs) -> bool
fn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self and other) and is used by the <=
operator. Read more
sourceimpl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for Allocation
impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for Allocation
impl<Tag: Eq, Extra: Eq> Eq for Allocation<Tag, Extra>
impl<Tag, Extra> StructuralEq for Allocation<Tag, Extra>
impl<Tag, Extra> StructuralPartialEq for Allocation<Tag, Extra>
Auto Trait Implementations
impl<Tag, Extra> RefUnwindSafe for Allocation<Tag, Extra> where
Extra: RefUnwindSafe,
Tag: RefUnwindSafe,
impl<Tag, Extra> Send for Allocation<Tag, Extra> where
Extra: Send,
Tag: Send,
impl<Tag, Extra> Sync for Allocation<Tag, Extra> where
Extra: Sync,
Tag: Sync,
impl<Tag, Extra> Unpin for Allocation<Tag, Extra> where
Extra: Unpin,
Tag: Unpin,
impl<Tag, Extra> UnwindSafe for Allocation<Tag, Extra> where
Extra: UnwindSafe,
Tag: UnwindSafe,
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcepub fn borrow_mut(&mut self) -> &mut T
pub fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
sourceimpl<Ctxt, T> DepNodeParams<Ctxt> for T where
Ctxt: DepContext,
T: for<'a> HashStable<StableHashingContext<'a>> + Debug,
impl<Ctxt, T> DepNodeParams<Ctxt> for T where
Ctxt: DepContext,
T: for<'a> HashStable<StableHashingContext<'a>> + Debug,
pub default fn fingerprint_style() -> FingerprintStyle
sourcepub default fn to_fingerprint(&self, tcx: Ctxt) -> Fingerprint
pub default fn to_fingerprint(&self, tcx: Ctxt) -> Fingerprint
This method turns the parameters of a DepNodeConstructor into an opaque Fingerprint to be used in DepNode. Not all DepNodeParams support being turned into a Fingerprint (they don’t need to if the corresponding DepNode is anonymous). Read more
pub default fn to_debug_str(&self, Ctxt) -> String
sourcepub default fn recover(
Ctxt,
&DepNode<<Ctxt as DepContext>::DepKind>
) -> Option<T>
pub default fn recover(
Ctxt,
&DepNode<<Ctxt as DepContext>::DepKind>
) -> Option<T>
This method tries to recover the query key from the given DepNode,
something which is needed when forcing DepNodes during red-green
evaluation. The query system will only call this method if
fingerprint_style() is not FingerprintStyle::Opaque.
It is always valid to return None here, in which case incremental
compilation will treat the query as having changed instead of forcing it. Read more
sourceimpl<T> MaybeResult<T> for T
impl<T> MaybeResult<T> for T
sourceimpl<T> ToOwned for T where
T: Clone,
impl<T> ToOwned for T where
T: Clone,
type Owned = T
type Owned = T
The resulting type after obtaining ownership.
sourcepub fn to_owned(&self) -> T
pub fn to_owned(&self) -> T
Creates owned data from borrowed data, usually by cloning. Read more
sourcepub fn clone_into(&self, target: &mut T)
pub fn clone_into(&self, target: &mut T)
toowned_clone_into)Uses borrowed data to replace owned data, usually by cloning. Read more
impl<'a, T> Captures<'a> for T where
T: ?Sized,
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.