Skip to content

Commit 349750f

Browse files
committed
Extend the BorTag GC to AllocIds
1 parent eb4e895 commit 349750f

24 files changed

+296
-236
lines changed

src/borrow_tracker/mod.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ pub struct FrameState {
7575
pub protected_tags: SmallVec<[(AllocId, BorTag); 2]>,
7676
}
7777

78-
impl VisitTags for FrameState {
79-
fn visit_tags(&self, _visit: &mut dyn FnMut(BorTag)) {
78+
impl VisitProvenance for FrameState {
79+
fn visit_tags(&self, _visit: &mut VisitWith<'_>) {
8080
// `protected_tags` are already recorded by `GlobalStateInner`.
8181
}
8282
}
@@ -110,10 +110,10 @@ pub struct GlobalStateInner {
110110
pub unique_is_unique: bool,
111111
}
112112

113-
impl VisitTags for GlobalStateInner {
114-
fn visit_tags(&self, visit: &mut dyn FnMut(BorTag)) {
113+
impl VisitProvenance for GlobalStateInner {
114+
fn visit_tags(&self, visit: &mut VisitWith<'_>) {
115115
for &tag in self.protected_tags.keys() {
116-
visit(tag);
116+
visit(None, Some(tag));
117117
}
118118
// The only other candidate is base_ptr_tags, and that does not need visiting since we don't ever
119119
// GC the bottommost/root tag.
@@ -471,8 +471,8 @@ impl AllocState {
471471
}
472472
}
473473

474-
impl VisitTags for AllocState {
475-
fn visit_tags(&self, visit: &mut dyn FnMut(BorTag)) {
474+
impl VisitProvenance for AllocState {
475+
fn visit_tags(&self, visit: &mut VisitWith<'_>) {
476476
match self {
477477
AllocState::StackedBorrows(sb) => sb.visit_tags(visit),
478478
AllocState::TreeBorrows(tb) => tb.visit_tags(visit),

src/borrow_tracker/stacked_borrows/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -462,10 +462,10 @@ impl Stacks {
462462
}
463463
}
464464

465-
impl VisitTags for Stacks {
466-
fn visit_tags(&self, visit: &mut dyn FnMut(BorTag)) {
465+
impl VisitProvenance for Stacks {
466+
fn visit_tags(&self, visit: &mut VisitWith<'_>) {
467467
for tag in self.exposed_tags.iter().copied() {
468-
visit(tag);
468+
visit(None, Some(tag));
469469
}
470470
}
471471
}

src/borrow_tracker/tree_borrows/tree.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -742,11 +742,11 @@ impl Tree {
742742
}
743743
}
744744

745-
impl VisitTags for Tree {
746-
fn visit_tags(&self, visit: &mut dyn FnMut(BorTag)) {
745+
impl VisitProvenance for Tree {
746+
fn visit_tags(&self, visit: &mut VisitWith<'_>) {
747747
// To ensure that the root never gets removed, we visit it
748748
// (the `root` node of `Tree` is not an `Option<_>`)
749-
visit(self.nodes.get(self.root).unwrap().tag)
749+
visit(None, Some(self.nodes.get(self.root).unwrap().tag))
750750
}
751751
}
752752

src/concurrency/data_race.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -790,9 +790,9 @@ pub struct VClockAlloc {
790790
alloc_ranges: RefCell<RangeMap<MemoryCellClocks>>,
791791
}
792792

793-
impl VisitTags for VClockAlloc {
794-
fn visit_tags(&self, _visit: &mut dyn FnMut(BorTag)) {
795-
// No tags here.
793+
impl VisitProvenance for VClockAlloc {
794+
fn visit_tags(&self, _visit: &mut VisitWith<'_>) {
795+
// No tags or allocIds here.
796796
}
797797
}
798798

@@ -1404,8 +1404,8 @@ pub struct GlobalState {
14041404
pub track_outdated_loads: bool,
14051405
}
14061406

1407-
impl VisitTags for GlobalState {
1408-
fn visit_tags(&self, _visit: &mut dyn FnMut(BorTag)) {
1407+
impl VisitProvenance for GlobalState {
1408+
fn visit_tags(&self, _visit: &mut VisitWith<'_>) {
14091409
// We don't have any tags.
14101410
}
14111411
}

src/concurrency/init_once.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ pub(super) struct InitOnce<'mir, 'tcx> {
4545
data_race: VClock,
4646
}
4747

48-
impl<'mir, 'tcx> VisitTags for InitOnce<'mir, 'tcx> {
49-
fn visit_tags(&self, visit: &mut dyn FnMut(BorTag)) {
48+
impl<'mir, 'tcx> VisitProvenance for InitOnce<'mir, 'tcx> {
49+
fn visit_tags(&self, visit: &mut VisitWith<'_>) {
5050
for waiter in self.waiters.iter() {
5151
waiter.callback.visit_tags(visit);
5252
}

src/concurrency/sync.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,8 @@ pub(crate) struct SynchronizationState<'mir, 'tcx> {
181181
pub(super) init_onces: IndexVec<InitOnceId, InitOnce<'mir, 'tcx>>,
182182
}
183183

184-
impl<'mir, 'tcx> VisitTags for SynchronizationState<'mir, 'tcx> {
185-
fn visit_tags(&self, visit: &mut dyn FnMut(BorTag)) {
184+
impl<'mir, 'tcx> VisitProvenance for SynchronizationState<'mir, 'tcx> {
185+
fn visit_tags(&self, visit: &mut VisitWith<'_>) {
186186
for init_once in self.init_onces.iter() {
187187
init_once.visit_tags(visit);
188188
}

src/concurrency/thread.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ enum SchedulingAction {
3434
}
3535

3636
/// Trait for callbacks that can be executed when some event happens, such as after a timeout.
37-
pub trait MachineCallback<'mir, 'tcx>: VisitTags {
37+
pub trait MachineCallback<'mir, 'tcx>: VisitProvenance {
3838
fn call(&self, ecx: &mut InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>) -> InterpResult<'tcx>;
3939
}
4040

@@ -219,8 +219,8 @@ impl<'mir, 'tcx> Thread<'mir, 'tcx> {
219219
}
220220
}
221221

222-
impl VisitTags for Thread<'_, '_> {
223-
fn visit_tags(&self, visit: &mut dyn FnMut(BorTag)) {
222+
impl VisitProvenance for Thread<'_, '_> {
223+
fn visit_tags(&self, visit: &mut VisitWith<'_>) {
224224
let Thread {
225225
panic_payloads: panic_payload,
226226
last_error,
@@ -242,8 +242,8 @@ impl VisitTags for Thread<'_, '_> {
242242
}
243243
}
244244

245-
impl VisitTags for Frame<'_, '_, Provenance, FrameExtra<'_>> {
246-
fn visit_tags(&self, visit: &mut dyn FnMut(BorTag)) {
245+
impl VisitProvenance for Frame<'_, '_, Provenance, FrameExtra<'_>> {
246+
fn visit_tags(&self, visit: &mut VisitWith<'_>) {
247247
let Frame {
248248
return_place,
249249
locals,
@@ -332,8 +332,8 @@ pub struct ThreadManager<'mir, 'tcx> {
332332
timeout_callbacks: FxHashMap<ThreadId, TimeoutCallbackInfo<'mir, 'tcx>>,
333333
}
334334

335-
impl VisitTags for ThreadManager<'_, '_> {
336-
fn visit_tags(&self, visit: &mut dyn FnMut(BorTag)) {
335+
impl VisitProvenance for ThreadManager<'_, '_> {
336+
fn visit_tags(&self, visit: &mut VisitWith<'_>) {
337337
let ThreadManager {
338338
threads,
339339
thread_local_alloc_ids,

src/concurrency/weak_memory.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,8 @@ pub struct StoreBufferAlloc {
108108
store_buffers: RefCell<RangeObjectMap<StoreBuffer>>,
109109
}
110110

111-
impl VisitTags for StoreBufferAlloc {
112-
fn visit_tags(&self, visit: &mut dyn FnMut(BorTag)) {
111+
impl VisitProvenance for StoreBufferAlloc {
112+
fn visit_tags(&self, visit: &mut VisitWith<'_>) {
113113
let Self { store_buffers } = self;
114114
for val in store_buffers
115115
.borrow()

src/intptrcast.rs

+21-3
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,23 @@ pub struct GlobalStateInner {
4646
provenance_mode: ProvenanceMode,
4747
}
4848

49-
impl VisitTags for GlobalStateInner {
50-
fn visit_tags(&self, _visit: &mut dyn FnMut(BorTag)) {
51-
// Nothing to visit here.
49+
impl VisitProvenance for GlobalStateInner {
50+
fn visit_tags(&self, visit: &mut VisitWith<'_>) {
51+
let GlobalStateInner {
52+
int_to_ptr_map: _,
53+
base_addr: _,
54+
exposed,
55+
next_base_addr: _,
56+
provenance_mode: _,
57+
} = self;
58+
// Though base_addr and int_to_ptr_map contain AllocIds, we do not want to visit them.
59+
// We're trying to remove unused elements from base_addr, so visiting it would prevent
60+
// removing anything. int_to_ptr_map is managed by free_alloc_id, and entries in it do not
61+
// actually make allocation base addresses reachable so we don't need to visit it.
62+
// But exposed tags do make base addresses reachable.
63+
for id in exposed {
64+
id.visit_tags(visit)
65+
}
5266
}
5367
}
5468

@@ -62,6 +76,10 @@ impl GlobalStateInner {
6276
provenance_mode: config.provenance_mode,
6377
}
6478
}
79+
80+
pub fn remove_unreachable_allocs(&mut self, reachable_allocs: &FxHashSet<AllocId>) {
81+
self.base_addr.retain(|id, _| reachable_allocs.contains(id));
82+
}
6583
}
6684

6785
/// Shifts `addr` to make it aligned with `align` by rounding `addr` to the smallest multiple

src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,9 @@ mod intptrcast;
7777
mod machine;
7878
mod mono_hash_map;
7979
mod operator;
80+
mod provenance_gc;
8081
mod range_map;
8182
mod shims;
82-
mod tag_gc;
8383

8484
// Establish a "crate-wide prelude": we often import `crate::*`.
8585

@@ -125,8 +125,8 @@ pub use crate::machine::{
125125
};
126126
pub use crate::mono_hash_map::MonoHashMap;
127127
pub use crate::operator::EvalContextExt as _;
128+
pub use crate::provenance_gc::{EvalContextExt as _, VisitProvenance, VisitWith};
128129
pub use crate::range_map::RangeMap;
129-
pub use crate::tag_gc::{EvalContextExt as _, VisitTags};
130130

131131
/// Insert rustc arguments at the beginning of the argument list that Miri wants to be
132132
/// set per default, for maximal validation power.

src/machine.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ impl<'tcx> std::fmt::Debug for FrameExtra<'tcx> {
7777
}
7878
}
7979

80-
impl VisitTags for FrameExtra<'_> {
81-
fn visit_tags(&self, visit: &mut dyn FnMut(BorTag)) {
80+
impl VisitProvenance for FrameExtra<'_> {
81+
fn visit_tags(&self, visit: &mut VisitWith<'_>) {
8282
let FrameExtra { catch_unwind, borrow_tracker, timing: _, is_user_relevant: _ } = self;
8383

8484
catch_unwind.visit_tags(visit);
@@ -311,8 +311,8 @@ pub struct AllocExtra<'tcx> {
311311
pub backtrace: Option<Vec<FrameInfo<'tcx>>>,
312312
}
313313

314-
impl VisitTags for AllocExtra<'_> {
315-
fn visit_tags(&self, visit: &mut dyn FnMut(BorTag)) {
314+
impl VisitProvenance for AllocExtra<'_> {
315+
fn visit_tags(&self, visit: &mut VisitWith<'_>) {
316316
let AllocExtra { borrow_tracker, data_race, weak_memory, backtrace: _ } = self;
317317

318318
borrow_tracker.visit_tags(visit);
@@ -793,8 +793,8 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
793793
}
794794
}
795795

796-
impl VisitTags for MiriMachine<'_, '_> {
797-
fn visit_tags(&self, visit: &mut dyn FnMut(BorTag)) {
796+
impl VisitProvenance for MiriMachine<'_, '_> {
797+
fn visit_tags(&self, visit: &mut VisitWith<'_>) {
798798
#[rustfmt::skip]
799799
let MiriMachine {
800800
threads,
@@ -1380,7 +1380,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
13801380
// where it mistakenly removes an important tag become visible.
13811381
if ecx.machine.gc_interval > 0 && ecx.machine.since_gc >= ecx.machine.gc_interval {
13821382
ecx.machine.since_gc = 0;
1383-
ecx.garbage_collect_tags()?;
1383+
ecx.run_provenance_gc();
13841384
}
13851385

13861386
// These are our preemption points.

0 commit comments

Comments
 (0)