1
Fork 0

add Align::ONE; add methods to access alloc.extra

This commit is contained in:
Ralf Jung 2021-05-17 13:08:12 +02:00
parent 74995c4292
commit 563ab4a106
6 changed files with 30 additions and 19 deletions

View file

@ -114,7 +114,7 @@ impl<Tag> Allocation<Tag> {
} }
pub fn from_byte_aligned_bytes<'a>(slice: impl Into<Cow<'a, [u8]>>) -> Self { pub fn from_byte_aligned_bytes<'a>(slice: impl Into<Cow<'a, [u8]>>) -> Self {
Allocation::from_bytes(slice, Align::from_bytes(1).unwrap()) Allocation::from_bytes(slice, Align::ONE)
} }
pub fn uninit(size: Size, align: Align) -> Self { pub fn uninit(size: Size, align: Align) -> Self {

View file

@ -14,7 +14,7 @@ use rustc_middle::ty;
use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{Ty, TyCtxt}; use rustc_middle::ty::{Ty, TyCtxt};
use rustc_span::symbol::{sym, Symbol}; use rustc_span::symbol::{sym, Symbol};
use rustc_target::abi::{Abi, LayoutOf as _, Primitive, Size}; use rustc_target::abi::{Abi, Align, LayoutOf as _, Primitive, Size};
use super::{ use super::{
util::ensure_monomorphic_enough, CheckInAllocMsg, ImmTy, InterpCx, Machine, OpTy, PlaceTy, util::ensure_monomorphic_enough, CheckInAllocMsg, ImmTy, InterpCx, Machine, OpTy, PlaceTy,
@ -525,7 +525,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
self.memory.check_ptr_access_align( self.memory.check_ptr_access_align(
min_ptr, min_ptr,
Size::from_bytes(size), Size::from_bytes(size),
None, Align::ONE,
CheckInAllocMsg::PointerArithmeticTest, CheckInAllocMsg::PointerArithmeticTest,
)?; )?;
Ok(offset_ptr) Ok(offset_ptr)

View file

@ -264,13 +264,12 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
Some((size, _align)) => size, Some((size, _align)) => size,
None => self.get_raw(ptr.alloc_id)?.size(), None => self.get_raw(ptr.alloc_id)?.size(),
}; };
let align = Align::from_bytes(1).unwrap();
// This will also call the access hooks. // This will also call the access hooks.
self.copy( self.copy(
ptr.into(), ptr.into(),
align, Align::ONE,
new_ptr.into(), new_ptr.into(),
align, Align::ONE,
old_size.min(new_size), old_size.min(new_size),
/*nonoverlapping*/ true, /*nonoverlapping*/ true,
)?; )?;
@ -379,10 +378,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
&self, &self,
sptr: Scalar<M::PointerTag>, sptr: Scalar<M::PointerTag>,
size: Size, size: Size,
align: Option<Align>, align: Align,
msg: CheckInAllocMsg, msg: CheckInAllocMsg,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
self.check_and_deref_ptr(sptr, size, align, msg, |ptr| { self.check_and_deref_ptr(sptr, size, Some(align), msg, |ptr| {
let (size, align) = let (size, align) =
self.get_size_and_align(ptr.alloc_id, AllocCheck::Dereferenceable)?; self.get_size_and_align(ptr.alloc_id, AllocCheck::Dereferenceable)?;
Ok((size, align, ())) Ok((size, align, ()))
@ -604,6 +603,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
} }
} }
/// Return the `extra` field of the given allocation.
pub fn get_alloc_extra<'a>(&'a self, id: AllocId) -> InterpResult<'tcx, &'a M::AllocExtra> {
Ok(&self.get_raw(id)?.extra)
}
/// Gives raw mutable access to the `Allocation`, without bounds or alignment checks. /// Gives raw mutable access to the `Allocation`, without bounds or alignment checks.
/// The caller is responsible for calling the access hooks! /// The caller is responsible for calling the access hooks!
/// ///
@ -664,6 +668,14 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
} }
} }
/// Return the `extra` field of the given allocation.
pub fn get_alloc_extra_mut<'a>(
&'a mut self,
id: AllocId,
) -> InterpResult<'tcx, &'a mut M::AllocExtra> {
Ok(&mut self.get_raw_mut(id)?.0.extra)
}
/// Obtain the size and alignment of an allocation, even if that allocation has /// Obtain the size and alignment of an allocation, even if that allocation has
/// been deallocated. /// been deallocated.
/// ///
@ -688,7 +700,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
// The caller requested no function pointers. // The caller requested no function pointers.
throw_ub!(DerefFunctionPointer(id)) throw_ub!(DerefFunctionPointer(id))
} else { } else {
Ok((Size::ZERO, Align::from_bytes(1).unwrap())) Ok((Size::ZERO, Align::ONE))
}; };
} }
@ -930,7 +942,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
/// ///
/// Performs appropriate bounds checks. /// Performs appropriate bounds checks.
pub fn read_bytes(&self, sptr: Scalar<M::PointerTag>, size: Size) -> InterpResult<'tcx, &[u8]> { pub fn read_bytes(&self, sptr: Scalar<M::PointerTag>, size: Size) -> InterpResult<'tcx, &[u8]> {
let alloc_ref = match self.get(sptr, size, Align::from_bytes(1).unwrap())? { let alloc_ref = match self.get(sptr, size, Align::ONE)? {
Some(a) => a, Some(a) => a,
None => return Ok(&[]), // zero-sized access None => return Ok(&[]), // zero-sized access
}; };
@ -956,7 +968,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
assert_eq!(lower, len, "can only write iterators with a precise length"); assert_eq!(lower, len, "can only write iterators with a precise length");
let size = Size::from_bytes(len); let size = Size::from_bytes(len);
let alloc_ref = match self.get_mut(sptr, size, Align::from_bytes(1).unwrap())? { let alloc_ref = match self.get_mut(sptr, size, Align::ONE)? {
Some(alloc_ref) => alloc_ref, Some(alloc_ref) => alloc_ref,
None => { None => {
// zero-sized access // zero-sized access

View file

@ -1031,11 +1031,8 @@ where
) -> MPlaceTy<'tcx, M::PointerTag> { ) -> MPlaceTy<'tcx, M::PointerTag> {
let ptr = self.memory.allocate_bytes(str.as_bytes(), kind); let ptr = self.memory.allocate_bytes(str.as_bytes(), kind);
let meta = Scalar::from_machine_usize(u64::try_from(str.len()).unwrap(), self); let meta = Scalar::from_machine_usize(u64::try_from(str.len()).unwrap(), self);
let mplace = MemPlace { let mplace =
ptr: ptr.into(), MemPlace { ptr: ptr.into(), align: Align::ONE, meta: MemPlaceMeta::Meta(meta) };
align: Align::from_bytes(1).unwrap(),
meta: MemPlaceMeta::Meta(meta),
};
let layout = self.layout_of(self.tcx.mk_static_str()).unwrap(); let layout = self.layout_of(self.tcx.mk_static_str()).unwrap();
MPlaceTy { mplace, layout } MPlaceTy { mplace, layout }

View file

@ -329,7 +329,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
self.ecx.memory.check_ptr_access_align( self.ecx.memory.check_ptr_access_align(
vtable, vtable,
3 * self.ecx.tcx.data_layout.pointer_size, // drop, size, align 3 * self.ecx.tcx.data_layout.pointer_size, // drop, size, align
Some(self.ecx.tcx.data_layout.pointer_align.abi), self.ecx.tcx.data_layout.pointer_align.abi,
CheckInAllocMsg::InboundsTest, // will anyway be replaced by validity message CheckInAllocMsg::InboundsTest, // will anyway be replaced by validity message
), ),
self.path, self.path,
@ -415,7 +415,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
self.ecx.memory.check_ptr_access_align( self.ecx.memory.check_ptr_access_align(
place.ptr, place.ptr,
size, size,
Some(align), align,
CheckInAllocMsg::InboundsTest, // will anyway be replaced by validity message CheckInAllocMsg::InboundsTest, // will anyway be replaced by validity message
), ),
self.path, self.path,

View file

@ -441,6 +441,8 @@ pub struct Align {
} }
impl Align { impl Align {
pub const ONE: Align = Align { pow2: 0 };
#[inline] #[inline]
pub fn from_bits(bits: u64) -> Result<Align, String> { pub fn from_bits(bits: u64) -> Result<Align, String> {
Align::from_bytes(Size::from_bits(bits).bytes()) Align::from_bytes(Size::from_bits(bits).bytes())
@ -450,7 +452,7 @@ impl Align {
pub fn from_bytes(align: u64) -> Result<Align, String> { pub fn from_bytes(align: u64) -> Result<Align, String> {
// Treat an alignment of 0 bytes like 1-byte alignment. // Treat an alignment of 0 bytes like 1-byte alignment.
if align == 0 { if align == 0 {
return Ok(Align { pow2: 0 }); return Ok(Align::ONE);
} }
#[cold] #[cold]