Skip to content

Commit eb30ce8

Browse files
committed
Move relocation methods from Memory to Allocation
1 parent d40a771 commit eb30ce8

File tree

2 files changed

+73
-73
lines changed

2 files changed

+73
-73
lines changed

src/librustc/mir/interpret/allocation.rs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,79 @@ impl<'tcx, Tag, Extra> Allocation<Tag, Extra> {
133133
}
134134
}
135135

136+
/// Relocations
137+
impl<'tcx, Tag, Extra> Allocation<Tag, Extra> {
138+
/// Return all relocations overlapping with the given ptr-offset pair.
139+
fn relocations(
140+
&self,
141+
ptr: Pointer<M::PointerTag>,
142+
size: Size,
143+
) -> EvalResult<'tcx, &[(Size, (M::PointerTag, AllocId))]> {
144+
// We have to go back `pointer_size - 1` bytes, as that one would still overlap with
145+
// the beginning of this range.
146+
let start = ptr.offset.bytes().saturating_sub(self.pointer_size().bytes() - 1);
147+
let end = ptr.offset + size; // this does overflow checking
148+
Ok(self.get(ptr.alloc_id)?.relocations.range(Size::from_bytes(start)..end))
149+
}
150+
151+
/// Check that there ar eno relocations overlapping with the given range.
152+
#[inline(always)]
153+
fn check_relocations(&self, ptr: Pointer<M::PointerTag>, size: Size) -> EvalResult<'tcx> {
154+
if self.relocations(ptr, size)?.len() != 0 {
155+
err!(ReadPointerAsBytes)
156+
} else {
157+
Ok(())
158+
}
159+
}
160+
161+
/// Remove all relocations inside the given range.
162+
/// If there are relocations overlapping with the edges, they
163+
/// are removed as well *and* the bytes they cover are marked as
164+
/// uninitialized. This is a somewhat odd "spooky action at a distance",
165+
/// but it allows strictly more code to run than if we would just error
166+
/// immediately in that case.
167+
fn clear_relocations(&mut self, ptr: Pointer<M::PointerTag>, size: Size) -> EvalResult<'tcx> {
168+
// Find the start and end of the given range and its outermost relocations.
169+
let (first, last) = {
170+
// Find all relocations overlapping the given range.
171+
let relocations = self.relocations(ptr, size)?;
172+
if relocations.is_empty() {
173+
return Ok(());
174+
}
175+
176+
(relocations.first().unwrap().0,
177+
relocations.last().unwrap().0 + self.pointer_size())
178+
};
179+
let start = ptr.offset;
180+
let end = start + size;
181+
182+
let alloc = self.get_mut(ptr.alloc_id)?;
183+
184+
// Mark parts of the outermost relocations as undefined if they partially fall outside the
185+
// given range.
186+
if first < start {
187+
alloc.undef_mask.set_range(first, start, false);
188+
}
189+
if last > end {
190+
alloc.undef_mask.set_range(end, last, false);
191+
}
192+
193+
// Forget all the relocations.
194+
alloc.relocations.remove_range(first..last);
195+
196+
Ok(())
197+
}
198+
199+
/// Error if there are relocations overlapping with the edges of the
200+
/// given memory range.
201+
#[inline]
202+
fn check_relocation_edges(&self, ptr: Pointer<M::PointerTag>, size: Size) -> EvalResult<'tcx> {
203+
self.check_relocations(ptr, Size::ZERO)?;
204+
self.check_relocations(ptr.offset(size, self)?, Size::ZERO)?;
205+
Ok(())
206+
}
207+
}
208+
136209
pub trait AllocationExtra<Tag>: ::std::fmt::Debug + Default + Clone {
137210
/// Hook for performing extra checks on a memory read access.
138211
///

src/librustc_mir/interpret/memory.rs

Lines changed: 0 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -955,79 +955,6 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
955955
}
956956
}
957957

958-
/// Relocations
959-
impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
960-
/// Return all relocations overlapping with the given ptr-offset pair.
961-
fn relocations(
962-
&self,
963-
ptr: Pointer<M::PointerTag>,
964-
size: Size,
965-
) -> EvalResult<'tcx, &[(Size, (M::PointerTag, AllocId))]> {
966-
// We have to go back `pointer_size - 1` bytes, as that one would still overlap with
967-
// the beginning of this range.
968-
let start = ptr.offset.bytes().saturating_sub(self.pointer_size().bytes() - 1);
969-
let end = ptr.offset + size; // this does overflow checking
970-
Ok(self.get(ptr.alloc_id)?.relocations.range(Size::from_bytes(start)..end))
971-
}
972-
973-
/// Check that there ar eno relocations overlapping with the given range.
974-
#[inline(always)]
975-
fn check_relocations(&self, ptr: Pointer<M::PointerTag>, size: Size) -> EvalResult<'tcx> {
976-
if self.relocations(ptr, size)?.len() != 0 {
977-
err!(ReadPointerAsBytes)
978-
} else {
979-
Ok(())
980-
}
981-
}
982-
983-
/// Remove all relocations inside the given range.
984-
/// If there are relocations overlapping with the edges, they
985-
/// are removed as well *and* the bytes they cover are marked as
986-
/// uninitialized. This is a somewhat odd "spooky action at a distance",
987-
/// but it allows strictly more code to run than if we would just error
988-
/// immediately in that case.
989-
fn clear_relocations(&mut self, ptr: Pointer<M::PointerTag>, size: Size) -> EvalResult<'tcx> {
990-
// Find the start and end of the given range and its outermost relocations.
991-
let (first, last) = {
992-
// Find all relocations overlapping the given range.
993-
let relocations = self.relocations(ptr, size)?;
994-
if relocations.is_empty() {
995-
return Ok(());
996-
}
997-
998-
(relocations.first().unwrap().0,
999-
relocations.last().unwrap().0 + self.pointer_size())
1000-
};
1001-
let start = ptr.offset;
1002-
let end = start + size;
1003-
1004-
let alloc = self.get_mut(ptr.alloc_id)?;
1005-
1006-
// Mark parts of the outermost relocations as undefined if they partially fall outside the
1007-
// given range.
1008-
if first < start {
1009-
alloc.undef_mask.set_range(first, start, false);
1010-
}
1011-
if last > end {
1012-
alloc.undef_mask.set_range(end, last, false);
1013-
}
1014-
1015-
// Forget all the relocations.
1016-
alloc.relocations.remove_range(first..last);
1017-
1018-
Ok(())
1019-
}
1020-
1021-
/// Error if there are relocations overlapping with the edges of the
1022-
/// given memory range.
1023-
#[inline]
1024-
fn check_relocation_edges(&self, ptr: Pointer<M::PointerTag>, size: Size) -> EvalResult<'tcx> {
1025-
self.check_relocations(ptr, Size::ZERO)?;
1026-
self.check_relocations(ptr.offset(size, self)?, Size::ZERO)?;
1027-
Ok(())
1028-
}
1029-
}
1030-
1031958
/// Undefined bytes
1032959
impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
1033960
// FIXME: Add a fast version for the common, nonoverlapping case

0 commit comments

Comments
 (0)