Skip to content

Commit 42a1239

Browse files
committed
avoid some redundant alignment checks
1 parent e3b4f8e commit 42a1239

File tree

1 file changed

+18
-7
lines changed

1 file changed

+18
-7
lines changed

src/librustc_mir/interpret/memory.rs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
//! The memory subsystem.
2+
//!
3+
//! Generally, we use `Pointer` to denote memory addresses. However, some operations
4+
//! have a "size"-like parameter, and they take `Scalar` for the address because
5+
//! if the size is 0, then the pointer can also be a (properly aligned, non-NULL)
6+
//! integer. It is crucial that these operations call `check_align` *before*
7+
//! short-circuiting the empty case!
8+
19
use std::collections::VecDeque;
210
use std::hash::{Hash, Hasher};
311
use std::ptr;
@@ -16,6 +24,7 @@ use syntax::ast::Mutability;
1624

1725
use super::{EvalContext, Machine};
1826

27+
1928
////////////////////////////////////////////////////////////////////////////////
2029
// Allocations and pointers
2130
////////////////////////////////////////////////////////////////////////////////
@@ -256,7 +265,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
256265
self.tcx.data_layout.endian
257266
}
258267

259-
/// Check that the pointer is aligned AND non-NULL.
268+
/// Check that the pointer is aligned AND non-NULL. This supports scalars
269+
/// for the benefit of other parts of miri that need to check alignment even for ZST.
260270
pub fn check_align(&self, ptr: Scalar, required_align: Align) -> EvalResult<'tcx> {
261271
// Check non-NULL/Undef, extract offset
262272
let (offset, alloc_align) = match ptr {
@@ -632,10 +642,10 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
632642
length: u64,
633643
nonoverlapping: bool,
634644
) -> EvalResult<'tcx> {
635-
// Empty accesses don't need to be valid pointers, but they should still be aligned
636-
self.check_align(src, src_align)?;
637-
self.check_align(dest, dest_align)?;
638645
if size.bytes() == 0 {
646+
// Nothing to do for ZST, other than checking alignment and non-NULLness.
647+
self.check_align(src, src_align)?;
648+
self.check_align(dest, dest_align)?;
639649
return Ok(());
640650
}
641651
let src = src.to_ptr()?;
@@ -661,6 +671,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
661671
new_relocations
662672
};
663673

674+
// This also checks alignment.
664675
let src_bytes = self.get_bytes_unchecked(src, size, src_align)?.as_ptr();
665676
let dest_bytes = self.get_bytes_mut(dest, size * length, dest_align)?.as_mut_ptr();
666677

@@ -718,8 +729,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
718729
pub fn read_bytes(&self, ptr: Scalar, size: Size) -> EvalResult<'tcx, &[u8]> {
719730
// Empty accesses don't need to be valid pointers, but they should still be non-NULL
720731
let align = Align::from_bytes(1, 1).unwrap();
721-
self.check_align(ptr, align)?;
722732
if size.bytes() == 0 {
733+
self.check_align(ptr, align)?;
723734
return Ok(&[]);
724735
}
725736
self.get_bytes(ptr.to_ptr()?, size, align)
@@ -728,8 +739,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
728739
pub fn write_bytes(&mut self, ptr: Scalar, src: &[u8]) -> EvalResult<'tcx> {
729740
// Empty accesses don't need to be valid pointers, but they should still be non-NULL
730741
let align = Align::from_bytes(1, 1).unwrap();
731-
self.check_align(ptr, align)?;
732742
if src.is_empty() {
743+
self.check_align(ptr, align)?;
733744
return Ok(());
734745
}
735746
let bytes = self.get_bytes_mut(ptr.to_ptr()?, Size::from_bytes(src.len() as u64), align)?;
@@ -740,8 +751,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
740751
pub fn write_repeat(&mut self, ptr: Scalar, val: u8, count: Size) -> EvalResult<'tcx> {
741752
// Empty accesses don't need to be valid pointers, but they should still be non-NULL
742753
let align = Align::from_bytes(1, 1).unwrap();
743-
self.check_align(ptr, align)?;
744754
if count.bytes() == 0 {
755+
self.check_align(ptr, align)?;
745756
return Ok(());
746757
}
747758
let bytes = self.get_bytes_mut(ptr.to_ptr()?, count, align)?;

0 commit comments

Comments
 (0)