Skip to content

Commit d8c5bc7

Browse files
committed
Replace usage of alloc.bytes in interpret
There is now a dedicate `len` method which avoids the need to access the bytes. Access the length as `Size` can also be done by a direct member. The constructors guarantee that these representations are convertable. Access which relies on the bytes, such as snapshot, can use direct raw access by reference as it does not care about undef and relocations or properly checks them seperately.
1 parent 98cff69 commit d8c5bc7

File tree

5 files changed

+37
-14
lines changed

5 files changed

+37
-14
lines changed

src/librustc/mir/interpret/allocation.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ use rustc_data_structures::sorted_map::SortedMap;
1313
use rustc_target::abi::HasDataLayout;
1414
use std::borrow::Cow;
1515

16+
// NOTE: When adding new fields, make sure to adjust the Snapshot impl in
17+
// `src/librustc_mir/interpret/snapshot.rs`.
1618
#[derive(
1719
Clone,
1820
Debug,

src/librustc_mir/interpret/intrinsics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
8181
let alloc = alloc_type_name(self.tcx.tcx, substs.type_at(0));
8282
let name_id = self.tcx.alloc_map.lock().create_memory_alloc(alloc);
8383
let id_ptr = self.memory.tag_static_base_pointer(name_id.into());
84-
let alloc_len = alloc.bytes.len() as u64;
84+
let alloc_len = alloc.size.bytes();
8585
let name_val = Immediate::new_slice(Scalar::Ptr(id_ptr), alloc_len, self);
8686
self.write_immediate(name_val, dest)?;
8787
}

src/librustc_mir/interpret/intrinsics/type_name.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ pub fn type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> &'tcx ty::Const<'tcx>
221221
val: ConstValue::Slice {
222222
data: alloc,
223223
start: 0,
224-
end: alloc.bytes.len(),
224+
end: alloc.len(),
225225
},
226226
ty: tcx.mk_static_str(),
227227
})

src/librustc_mir/interpret/memory.rs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
210210
let new_ptr = self.allocate(new_size, new_align, kind);
211211
let old_size = match old_size_and_align {
212212
Some((size, _align)) => size,
213-
None => Size::from_bytes(self.get(ptr.alloc_id)?.bytes.len() as u64),
213+
None => self.get(ptr.alloc_id)?.size,
214214
};
215215
self.copy(
216216
ptr,
@@ -271,20 +271,20 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
271271
))
272272
}
273273
if let Some((size, align)) = old_size_and_align {
274-
if size.bytes() != alloc.bytes.len() as u64 || align != alloc.align {
275-
let bytes = Size::from_bytes(alloc.bytes.len() as u64);
274+
if size != alloc.size || align != alloc.align {
275+
let bytes = alloc.size;
276276
throw_unsup!(IncorrectAllocationInformation(size, bytes, align, alloc.align))
277277
}
278278
}
279279

280280
// Let the machine take some extra action
281-
let size = Size::from_bytes(alloc.bytes.len() as u64);
281+
let size = alloc.size;
282282
AllocationExtra::memory_deallocated(&mut alloc, ptr, size)?;
283283

284284
// Don't forget to remember size and align of this now-dead allocation
285285
let old = self.dead_alloc_map.insert(
286286
ptr.alloc_id,
287-
(Size::from_bytes(alloc.bytes.len() as u64), alloc.align)
287+
(alloc.size, alloc.align)
288288
);
289289
if old.is_some() {
290290
bug!("Nothing can be deallocated twice");
@@ -555,7 +555,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
555555
// a) cause cycles in case `id` refers to a static
556556
// b) duplicate a static's allocation in miri
557557
if let Some((_, alloc)) = self.alloc_map.get(id) {
558-
return Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align));
558+
return Ok((alloc.size, alloc.align));
559559
}
560560

561561
// # Function pointers
@@ -583,7 +583,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
583583
Some(GlobalAlloc::Memory(alloc)) =>
584584
// Need to duplicate the logic here, because the global allocations have
585585
// different associated types than the interpreter-local ones.
586-
Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align)),
586+
Ok((alloc.size, alloc.align)),
587587
Some(GlobalAlloc::Function(_)) =>
588588
bug!("We already checked function pointers above"),
589589
// The rest must be dead.
@@ -645,7 +645,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
645645
let prefix_len = msg.len();
646646
let mut relocations = vec![];
647647

648-
for i in 0..(alloc.bytes.len() as u64) {
648+
for i in 0..alloc.size.bytes() {
649649
let i = Size::from_bytes(i);
650650
if let Some(&(_, target_id)) = alloc.relocations.get(&i) {
651651
if allocs_seen.insert(target_id) {
@@ -655,7 +655,12 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
655655
}
656656
if alloc.undef_mask.is_range_defined(i, i + Size::from_bytes(1)).is_ok() {
657657
// this `as usize` is fine, since `i` came from a `usize`
658-
write!(msg, "{:02x} ", alloc.bytes[i.bytes() as usize]).unwrap();
658+
let i = i.bytes() as usize;
659+
660+
// Checked definedness (and thus range) and relocations. This access also doesn't
661+
// influence interpreter execution but is only for debugging.
662+
let bytes = alloc.inspect_with_undef_and_ptr_outside_interpreter(i..i+1);
663+
write!(msg, "{:02x} ", bytes[0]).unwrap();
659664
} else {
660665
msg.push_str("__ ");
661666
}
@@ -664,7 +669,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
664669
trace!(
665670
"{}({} bytes, alignment {}){}",
666671
msg,
667-
alloc.bytes.len(),
672+
alloc.size.bytes(),
668673
alloc.align.bytes(),
669674
extra
670675
);

src/librustc_mir/interpret/snapshot.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use rustc::mir::interpret::{
1515
};
1616

1717
use rustc::ty::{self, TyCtxt};
18-
use rustc::ty::layout::Align;
18+
use rustc::ty::layout::{Align, Size};
1919
use rustc_data_structures::fx::FxHashSet;
2020
use rustc_data_structures::indexed_vec::IndexVec;
2121
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
@@ -276,6 +276,7 @@ struct AllocationSnapshot<'a> {
276276
relocations: Relocations<(), AllocIdSnapshot<'a>>,
277277
undef_mask: &'a UndefMask,
278278
align: &'a Align,
279+
size: &'a Size,
279280
mutability: &'a Mutability,
280281
}
281282

@@ -285,12 +286,27 @@ impl<'a, Ctx> Snapshot<'a, Ctx> for &'a Allocation
285286
type Item = AllocationSnapshot<'a>;
286287

287288
fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
288-
let Allocation { bytes, relocations, undef_mask, align, mutability, extra: () } = self;
289+
let Allocation {
290+
relocations,
291+
size,
292+
align,
293+
mutability,
294+
extra: (),
295+
..
296+
} = self;
297+
298+
let all_bytes = 0..self.len();
299+
// This 'inspect' is okay since following access respects undef and relocations. This does
300+
// influence interpreter exeuction, but only to detect the error of cycles in evalution
301+
// dependencies.
302+
let bytes = self.inspect_with_undef_and_ptr_outside_interpreter(all_bytes);
303+
let undef_mask = self.undef_mask();
289304

290305
AllocationSnapshot {
291306
bytes,
292307
undef_mask,
293308
align,
309+
size,
294310
mutability,
295311
relocations: relocations.snapshot(ctx),
296312
}

0 commit comments

Comments
 (0)