1
Fork 0

miri: optimize zeroed alloc

Co-authored-by: Ralf Jung <post@ralfj.de>
This commit is contained in:
SpecificProtagonist 2025-01-25 00:54:51 +01:00
parent 8231e8599e
commit eee9df43e6
No known key found for this signature in database
14 changed files with 88 additions and 79 deletions

View file

@ -270,6 +270,12 @@ impl AllocRange {
}
}
/// Whether a new allocation should be initialized with zero-bytes.
pub enum AllocInit {
Uninit,
Zero,
}
// The constructors are all without extra; the extra gets added by a machine hook later.
impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
/// Creates an allocation initialized by the given bytes
@ -294,7 +300,12 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
Allocation::from_bytes(slice, Align::ONE, Mutability::Not)
}
fn uninit_inner<R>(size: Size, align: Align, fail: impl FnOnce() -> R) -> Result<Self, R> {
fn new_inner<R>(
size: Size,
align: Align,
init: AllocInit,
fail: impl FnOnce() -> R,
) -> Result<Self, R> {
// We raise an error if we cannot create the allocation on the host.
// This results in an error that can happen non-deterministically, since the memory
// available to the compiler can change between runs. Normally queries are always
@ -306,7 +317,10 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
Ok(Allocation {
bytes,
provenance: ProvenanceMap::new(),
init_mask: InitMask::new(size, false),
init_mask: InitMask::new(size, match init {
AllocInit::Uninit => false,
AllocInit::Zero => true,
}),
align,
mutability: Mutability::Mut,
extra: (),
@ -315,8 +329,8 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
/// Try to create an Allocation of `size` bytes, failing if there is not enough memory
/// available to the compiler to do so.
pub fn try_uninit<'tcx>(size: Size, align: Align) -> InterpResult<'tcx, Self> {
Self::uninit_inner(size, align, || {
pub fn try_new<'tcx>(size: Size, align: Align, init: AllocInit) -> InterpResult<'tcx, Self> {
Self::new_inner(size, align, init, || {
ty::tls::with(|tcx| tcx.dcx().delayed_bug("exhausted memory during interpretation"));
InterpErrorKind::ResourceExhaustion(ResourceExhaustionInfo::MemoryExhausted)
})
@ -328,8 +342,8 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
///
/// 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.
pub fn uninit(size: Size, align: Align) -> Self {
match Self::uninit_inner(size, align, || {
pub fn new(size: Size, align: Align, init: AllocInit) -> Self {
match Self::new_inner(size, align, init, || {
panic!(
"interpreter ran out of memory: cannot create allocation of {} bytes",
size.bytes()

View file

@ -30,8 +30,8 @@ pub use {
};
pub use self::allocation::{
AllocBytes, AllocError, AllocRange, AllocResult, Allocation, ConstAllocation, InitChunk,
InitChunkIter, alloc_range,
AllocBytes, AllocError, AllocInit, AllocRange, AllocResult, Allocation, ConstAllocation,
InitChunk, InitChunkIter, alloc_range,
};
pub use self::error::{
BadBytesAccess, CheckAlignMsg, CheckInAllocMsg, ErrorHandled, EvalStaticInitializerRawResult,

View file

@ -4,7 +4,9 @@ use rustc_ast::Mutability;
use rustc_macros::HashStable;
use rustc_type_ir::elaborate;
use crate::mir::interpret::{AllocId, Allocation, CTFE_ALLOC_SALT, Pointer, Scalar, alloc_range};
use crate::mir::interpret::{
AllocId, AllocInit, Allocation, CTFE_ALLOC_SALT, Pointer, Scalar, alloc_range,
};
use crate::ty::{self, Instance, PolyTraitRef, Ty, TyCtxt};
#[derive(Clone, Copy, PartialEq, HashStable)]
@ -108,7 +110,7 @@ pub(super) fn vtable_allocation_provider<'tcx>(
let ptr_align = tcx.data_layout.pointer_align.abi;
let vtable_size = ptr_size * u64::try_from(vtable_entries.len()).unwrap();
let mut vtable = Allocation::uninit(vtable_size, ptr_align);
let mut vtable = Allocation::new(vtable_size, ptr_align, AllocInit::Uninit);
// No need to do any alignment checks on the memory accesses below, because we know the
// allocation is correctly aligned as we created it above. Also we're only offsetting by