Struct rustc_middle::mir::interpret::allocation::Allocation [−][src]
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: 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
pub 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 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
Raw accessors. Provide access to otherwise private bytes.
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.
Returns the relocation list.
Byte accessors.
fn 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.
pub 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.
pub 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.
pub 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.
pub 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.
Reading and writing.
pub 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.
pub 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.
pub 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.
Relocations.
Returns all relocations overlapping with the given pointer-offset pair.
fn 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.
fn 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.
fn 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.
pub fn prepare_relocation_copy(
&self,
cx: &impl HasDataLayout,
src: AllocRange,
dest: Size,
count: u64
) -> 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.
Uninitialized bytes.
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.
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.
Transferring the initialization mask to other allocations.
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<_>>()
.
pub 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
fn allocate_from_iter<'a>(
arena: &'a Arena<'tcx>,
iter: impl IntoIterator<Item = Self>
) -> &'a mut [Self]
Immutably borrows from an owned value. Read more
impl<'__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>>,
type Lifted = &'tcx Allocation
impl<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>
This method tests for self
and other
values to be equal, and is used
by ==
. Read more
This method tests for !=
.
impl<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>
This method returns an ordering between self
and other
values if one exists. Read more
This method tests less than (for self
and other
) and is used by the <
operator. Read more
This method tests less than or equal to (for self
and other
) and is used by the <=
operator. Read more
This method tests greater than (for self
and other
) and is used by the >
operator. Read more
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
Mutably borrows from an owned value. Read more
impl<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,
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
This method tries to recover the query key from the given DepNode
,
something which is needed when forcing DepNode
s 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
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.