Skip to content

Commit 8203131

Browse files
committed
Add a shim that lets us manually run the GC
1 parent 8c610f8 commit 8203131

File tree

4 files changed

+20
-24
lines changed

4 files changed

+20
-24
lines changed

src/machine.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1358,7 +1358,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
13581358
// where it mistakenly removes an important tag become visible.
13591359
if ecx.machine.gc_interval > 0 && ecx.machine.since_gc >= ecx.machine.gc_interval {
13601360
ecx.machine.since_gc = 0;
1361-
ecx.garbage_collect_tags()?;
1361+
ecx.run_provenance_gc();
13621362
}
13631363

13641364
// These are our preemption points.

src/provenance_gc.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -149,12 +149,8 @@ impl VisitTags for crate::MiriInterpCx<'_, '_> {
149149

150150
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
151151
pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
152-
fn garbage_collect_tags(&mut self) -> InterpResult<'tcx> {
152+
fn run_provenance_gc(&mut self) {
153153
let this = self.eval_context_mut();
154-
// No reason to do anything at all if stacked borrows is off.
155-
if this.machine.borrow_tracker.is_none() {
156-
return Ok(());
157-
}
158154

159155
let mut tags = FxHashSet::default();
160156
let mut alloc_ids = FxHashSet::default();
@@ -168,8 +164,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
168164
});
169165
self.remove_unreachable_tags(tags);
170166
self.remove_unreachable_allocs(alloc_ids);
171-
172-
Ok(())
173167
}
174168

175169
fn remove_unreachable_tags(&mut self, tags: FxHashSet<BorTag>) {

src/shims/foreign_items.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,10 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
459459
// shim, add it to the corresponding submodule.
460460
match link_name.as_str() {
461461
// Miri-specific extern functions
462+
"miri_run_provenance_gc" => {
463+
let [] = this.check_shim(abi, Abi::Rust, link_name, args)?;
464+
this.run_provenance_gc();
465+
}
462466
"miri_get_alloc_id" => {
463467
let [ptr] = this.check_shim(abi, Abi::Rust, link_name, args)?;
464468
let ptr = this.read_pointer(ptr)?;

tests/pass/ptr_int_casts.rs

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
use std::mem;
55
use std::ptr;
66

7+
extern "Rust" {
8+
fn miri_run_provenance_gc();
9+
}
10+
711
fn eq_ref<T>(x: &T, y: &T) -> bool {
812
x as *const _ == y as *const _
913
}
@@ -47,25 +51,19 @@ fn ptr_int_casts() {
4751
// involving types other than usize
4852
assert_eq!((-1i32) as usize as *const i32 as usize, (-1i32) as usize);
4953

50-
// Stress-test that the GC doesn't delete context that would prevent us from casting from int
54+
// Check that the GC doesn't delete context that would prevent us from casting from int
5155
// to pointer correctly after the allocation is dead.
52-
let mut ptrs: Vec<*const u8> = Vec::new();
53-
let mut ints: Vec<usize> = Vec::new();
54-
55-
for _ in 0..100 {
56+
let (ptr, int) = {
5657
let local = 0u8;
5758
let ptr = &local as *const u8;
58-
ptrs.push(ptr);
59-
ints.push(ptr as usize);
60-
61-
let b = Box::new(0u8);
62-
let ptr = &*b as *const u8;
63-
ptrs.push(ptr);
64-
ints.push(ptr as usize);
65-
}
66-
67-
let later_ints: Vec<usize> = ptrs.iter().map(|p| *p as usize).collect();
68-
assert_eq!(ints, later_ints);
59+
(ptr, ptr as usize)
60+
};
61+
// Manually run the GC, instead of just hoping that it runs at the right time.
62+
unsafe { miri_run_provenance_gc() }
63+
let later_int = ptr as usize;
64+
assert_eq!(int, later_int);
65+
let later_ptr = int as *const u8;
66+
assert_eq!(ptr, later_ptr);
6967
}
7068

7169
fn ptr_int_ops() {

0 commit comments

Comments
 (0)