miri: optimize zeroed alloc
Co-authored-by: Ralf Jung <post@ralfj.de>
This commit is contained in:
parent
8231e8599e
commit
eee9df43e6
14 changed files with 88 additions and 79 deletions
|
@ -21,9 +21,10 @@ use super::error::*;
|
|||
use crate::errors::{LongRunning, LongRunningWarn};
|
||||
use crate::fluent_generated as fluent;
|
||||
use crate::interpret::{
|
||||
self, AllocId, AllocRange, ConstAllocation, CtfeProvenance, FnArg, Frame, GlobalAlloc, ImmTy,
|
||||
InterpCx, InterpResult, MPlaceTy, OpTy, RangeSet, Scalar, compile_time_machine, interp_ok,
|
||||
throw_exhaust, throw_inval, throw_ub, throw_ub_custom, throw_unsup, throw_unsup_format,
|
||||
self, AllocId, AllocInit, AllocRange, ConstAllocation, CtfeProvenance, FnArg, Frame,
|
||||
GlobalAlloc, ImmTy, InterpCx, InterpResult, MPlaceTy, OpTy, RangeSet, Scalar,
|
||||
compile_time_machine, interp_ok, throw_exhaust, throw_inval, throw_ub, throw_ub_custom,
|
||||
throw_unsup, throw_unsup_format,
|
||||
};
|
||||
|
||||
/// When hitting this many interpreted terminators we emit a deny by default lint
|
||||
|
@ -420,6 +421,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
|
|||
Size::from_bytes(size),
|
||||
align,
|
||||
interpret::MemoryKind::Machine(MemoryKind::Heap),
|
||||
AllocInit::Uninit,
|
||||
)?;
|
||||
ecx.write_pointer(ptr, dest)?;
|
||||
}
|
||||
|
|
|
@ -20,10 +20,10 @@ use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
|
|||
use tracing::{debug, instrument, trace};
|
||||
|
||||
use super::{
|
||||
AllocBytes, AllocId, AllocMap, AllocRange, Allocation, CheckAlignMsg, CheckInAllocMsg,
|
||||
CtfeProvenance, GlobalAlloc, InterpCx, InterpResult, Machine, MayLeak, Misalignment, Pointer,
|
||||
PointerArithmetic, Provenance, Scalar, alloc_range, err_ub, err_ub_custom, interp_ok, throw_ub,
|
||||
throw_ub_custom, throw_unsup, throw_unsup_format,
|
||||
AllocBytes, AllocId, AllocInit, AllocMap, AllocRange, Allocation, CheckAlignMsg,
|
||||
CheckInAllocMsg, CtfeProvenance, GlobalAlloc, InterpCx, InterpResult, Machine, MayLeak,
|
||||
Misalignment, Pointer, PointerArithmetic, Provenance, Scalar, alloc_range, err_ub,
|
||||
err_ub_custom, interp_ok, throw_ub, throw_ub_custom, throw_unsup, throw_unsup_format,
|
||||
};
|
||||
use crate::fluent_generated as fluent;
|
||||
|
||||
|
@ -230,11 +230,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
size: Size,
|
||||
align: Align,
|
||||
kind: MemoryKind<M::MemoryKind>,
|
||||
init: AllocInit,
|
||||
) -> InterpResult<'tcx, Pointer<M::Provenance>> {
|
||||
let alloc = if M::PANIC_ON_ALLOC_FAIL {
|
||||
Allocation::uninit(size, align)
|
||||
Allocation::new(size, align, init)
|
||||
} else {
|
||||
Allocation::try_uninit(size, align)?
|
||||
Allocation::try_new(size, align, init)?
|
||||
};
|
||||
self.insert_allocation(alloc, kind)
|
||||
}
|
||||
|
@ -270,6 +271,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
M::adjust_alloc_root_pointer(self, Pointer::from(id), Some(kind))
|
||||
}
|
||||
|
||||
/// If this grows the allocation, `init_growth` determines
|
||||
/// whether the additional space will be initialized.
|
||||
pub fn reallocate_ptr(
|
||||
&mut self,
|
||||
ptr: Pointer<Option<M::Provenance>>,
|
||||
|
@ -277,6 +280,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
new_size: Size,
|
||||
new_align: Align,
|
||||
kind: MemoryKind<M::MemoryKind>,
|
||||
init_growth: AllocInit,
|
||||
) -> InterpResult<'tcx, Pointer<M::Provenance>> {
|
||||
let (alloc_id, offset, _prov) = self.ptr_get_alloc_id(ptr, 0)?;
|
||||
if offset.bytes() != 0 {
|
||||
|
@ -289,7 +293,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
|
||||
// For simplicities' sake, we implement reallocate as "alloc, copy, dealloc".
|
||||
// This happens so rarely, the perf advantage is outweighed by the maintenance cost.
|
||||
let new_ptr = self.allocate_ptr(new_size, new_align, kind)?;
|
||||
// If requested, we zero-init the entire allocation, to ensure that a growing
|
||||
// allocation has its new bytes properly set. For the part that is copied,
|
||||
// `mem_copy` below will de-initialize things as necessary.
|
||||
let new_ptr = self.allocate_ptr(new_size, new_align, kind, init_growth)?;
|
||||
let old_size = match old_size_and_align {
|
||||
Some((size, _align)) => size,
|
||||
None => self.get_alloc_raw(alloc_id)?.size(),
|
||||
|
|
|
@ -12,9 +12,9 @@ use rustc_middle::{bug, mir, span_bug};
|
|||
use tracing::{instrument, trace};
|
||||
|
||||
use super::{
|
||||
AllocRef, AllocRefMut, CheckAlignMsg, CtfeProvenance, ImmTy, Immediate, InterpCx, InterpResult,
|
||||
Machine, MemoryKind, Misalignment, OffsetMode, OpTy, Operand, Pointer, Projectable, Provenance,
|
||||
Scalar, alloc_range, interp_ok, mir_assign_valid_types,
|
||||
AllocInit, AllocRef, AllocRefMut, CheckAlignMsg, CtfeProvenance, ImmTy, Immediate, InterpCx,
|
||||
InterpResult, Machine, MemoryKind, Misalignment, OffsetMode, OpTy, Operand, Pointer,
|
||||
Projectable, Provenance, Scalar, alloc_range, interp_ok, mir_assign_valid_types,
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)]
|
||||
|
@ -983,7 +983,7 @@ where
|
|||
let Some((size, align)) = self.size_and_align_of(&meta, &layout)? else {
|
||||
span_bug!(self.cur_span(), "cannot allocate space for `extern` type, size is not known")
|
||||
};
|
||||
let ptr = self.allocate_ptr(size, align, kind)?;
|
||||
let ptr = self.allocate_ptr(size, align, kind, AllocInit::Uninit)?;
|
||||
interp_ok(self.ptr_with_meta_to_mplace(ptr.into(), meta, layout, /*unaligned*/ false))
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ use std::ops::ControlFlow;
|
|||
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::mir::interpret::{Allocation, InterpResult, Pointer};
|
||||
use rustc_middle::mir::interpret::{AllocInit, Allocation, InterpResult, Pointer};
|
||||
use rustc_middle::ty::layout::TyAndLayout;
|
||||
use rustc_middle::ty::{
|
||||
self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
|
||||
|
@ -76,7 +76,7 @@ pub(crate) fn create_static_alloc<'tcx>(
|
|||
static_def_id: LocalDefId,
|
||||
layout: TyAndLayout<'tcx>,
|
||||
) -> InterpResult<'tcx, MPlaceTy<'tcx>> {
|
||||
let alloc = Allocation::try_uninit(layout.size, layout.align.abi)?;
|
||||
let alloc = Allocation::try_new(layout.size, layout.align.abi, AllocInit::Uninit)?;
|
||||
let alloc_id = ecx.tcx.reserve_and_set_static_alloc(static_def_id.into());
|
||||
assert_eq!(ecx.machine.static_root_ids, None);
|
||||
ecx.machine.static_root_ids = Some((alloc_id, static_def_id));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue