Skip to content

Commit 3fb617d

Browse files
committed
more comments for these sublte games we are playing with allocations in the miri engine
1 parent 83667d6 commit 3fb617d

File tree

2 files changed

+40
-30
lines changed

2 files changed

+40
-30
lines changed

src/librustc_mir/interpret/machine.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@ pub trait Machine<'a, 'mir, 'tcx>: Sized {
122122
/// Called for read access to a foreign static item.
123123
///
124124
/// This will only be called once per static and machine; the result is cached in
125-
/// the machine memory.
125+
/// the machine memory. (This relies on `AllocMap::get_or` being able to add the
126+
/// owned allocation to the map even when the map is shared.)
126127
fn find_foreign_static(
127128
tcx: TyCtxtAt<'a, 'tcx, 'tcx>,
128129
def_id: DefId,
@@ -133,7 +134,8 @@ pub trait Machine<'a, 'mir, 'tcx>: Sized {
133134
///
134135
/// This should avoid copying if no work has to be done! If this returns an owned
135136
/// allocation (because a copy had to be done to add the tags), machine memory will
136-
/// cache the result.
137+
/// cache the result. (This relies on `AllocMap::get_or` being able to add the
138+
/// owned allocation to the map even when the map is shared.)
137139
fn static_with_default_tag(
138140
alloc: &'_ Allocation
139141
) -> Cow<'_, Allocation<Self::PointerTag>>;

src/librustc_mir/interpret/memory.rs

+36-28
Original file line numberDiff line numberDiff line change
@@ -321,14 +321,20 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
321321

322322
/// Allocation accessors
323323
impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
324-
/// Helper function to obtain the global (tcx) allocation for a static
324+
/// Helper function to obtain the global (tcx) allocation for a static.
325+
/// This attempts to return a reference to an existing allocation if
326+
/// one can be found in `tcx`. That, however, is only possible if `tcx` and
327+
/// this machine use the same pointer tag, so it is indirected through
328+
/// `M::static_with_default_tag`.
325329
fn get_static_alloc(
326330
tcx: TyCtxtAt<'a, 'tcx, 'tcx>,
327331
id: AllocId,
328332
) -> EvalResult<'tcx, Cow<'tcx, Allocation<M::PointerTag>>> {
329333
let alloc = tcx.alloc_map.lock().get(id);
330334
let def_id = match alloc {
331335
Some(AllocType::Memory(mem)) => {
336+
// We got tcx memory. Let the machine figure out whether and how to
337+
// turn that into memory with the right pointer tag.
332338
return Ok(M::static_with_default_tag(mem))
333339
}
334340
Some(AllocType::Function(..)) => {
@@ -356,6 +362,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
356362
EvalErrorKind::ReferencedConstant(err).into()
357363
}).map(|const_val| {
358364
if let ConstValue::ByRef(_, allocation, _) = const_val.val {
365+
// We got tcx memory. Let the machine figure out whether and how to
366+
// turn that into memory with the right pointer tag.
359367
M::static_with_default_tag(allocation)
360368
} else {
361369
bug!("Matching on non-ByRef static")
@@ -372,7 +380,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
372380
let alloc = Self::get_static_alloc(self.tcx, id).map_err(Err)?;
373381
match alloc {
374382
Cow::Borrowed(alloc) => {
375-
// We got a ref, cheaply return that as an "error"
383+
// We got a ref, cheaply return that as an "error" so that the
384+
// map does not get mutated.
376385
Err(Ok(alloc))
377386
}
378387
Cow::Owned(alloc) => {
@@ -392,30 +401,6 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
392401
}
393402
}
394403

395-
pub fn get_size_and_align(&self, id: AllocId) -> (Size, Align) {
396-
if let Ok(alloc) = self.get(id) {
397-
return (Size::from_bytes(alloc.bytes.len() as u64), alloc.align);
398-
}
399-
// Could also be a fn ptr or extern static
400-
match self.tcx.alloc_map.lock().get(id) {
401-
Some(AllocType::Function(..)) => (Size::ZERO, Align::from_bytes(1, 1).unwrap()),
402-
Some(AllocType::Static(did)) => {
403-
// The only way `get` couldnÄt have worked here is if this is an extern static
404-
assert!(self.tcx.is_foreign_item(did));
405-
// Use size and align of the type
406-
let ty = self.tcx.type_of(did);
407-
let layout = self.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap();
408-
(layout.size, layout.align)
409-
}
410-
_ => {
411-
// Must be a deallocated pointer
412-
*self.dead_alloc_map.get(&id).expect(
413-
"allocation missing in dead_alloc_map"
414-
)
415-
}
416-
}
417-
}
418-
419404
pub fn get_mut(
420405
&mut self,
421406
id: AllocId,
@@ -429,8 +414,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
429414
return err!(ModifiedConstantMemory);
430415
}
431416
let kind = M::STATIC_KIND.expect(
432-
"I got an owned allocation that I have to copy but the machine does \
433-
not expect that to happen"
417+
"An allocation is being mutated but the machine does not expect that to happen"
434418
);
435419
Ok((MemoryKind::Machine(kind), alloc.into_owned()))
436420
});
@@ -448,6 +432,30 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
448432
}
449433
}
450434

435+
pub fn get_size_and_align(&self, id: AllocId) -> (Size, Align) {
436+
if let Ok(alloc) = self.get(id) {
437+
return (Size::from_bytes(alloc.bytes.len() as u64), alloc.align);
438+
}
439+
// Could also be a fn ptr or extern static
440+
match self.tcx.alloc_map.lock().get(id) {
441+
Some(AllocType::Function(..)) => (Size::ZERO, Align::from_bytes(1, 1).unwrap()),
442+
Some(AllocType::Static(did)) => {
443+
// The only way `get` couldn't have worked here is if this is an extern static
444+
assert!(self.tcx.is_foreign_item(did));
445+
// Use size and align of the type
446+
let ty = self.tcx.type_of(did);
447+
let layout = self.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap();
448+
(layout.size, layout.align)
449+
}
450+
_ => {
451+
// Must be a deallocated pointer
452+
*self.dead_alloc_map.get(&id).expect(
453+
"allocation missing in dead_alloc_map"
454+
)
455+
}
456+
}
457+
}
458+
451459
pub fn get_fn(&self, ptr: Pointer<M::PointerTag>) -> EvalResult<'tcx, Instance<'tcx>> {
452460
if ptr.offset.bytes() != 0 {
453461
return err!(InvalidFunctionPointer);

0 commit comments

Comments
 (0)