@@ -184,12 +184,35 @@ impl LiveAllocs<'_, '_> {
184
184
}
185
185
}
186
186
187
+ fn remove_unreachable_tags < ' tcx > ( this : & mut MiriInterpCx < ' tcx > , tags : FxHashSet < BorTag > ) {
188
+ // Avoid iterating all allocations if there's no borrow tracker anyway.
189
+ if this. machine . borrow_tracker . is_some ( ) {
190
+ this. memory . alloc_map ( ) . iter ( |it| {
191
+ for ( _id, ( _kind, alloc) ) in it {
192
+ alloc. extra . borrow_tracker . as_ref ( ) . unwrap ( ) . remove_unreachable_tags ( & tags) ;
193
+ }
194
+ } ) ;
195
+ }
196
+ }
197
+
198
+ fn remove_unreachable_allocs < ' tcx > ( this : & mut MiriInterpCx < ' tcx > , allocs : FxHashSet < AllocId > ) {
199
+ let allocs = LiveAllocs { ecx : this, collected : allocs } ;
200
+ this. machine . allocation_spans . borrow_mut ( ) . retain ( |id, _| allocs. is_live ( * id) ) ;
201
+ this. machine . symbolic_alignment . borrow_mut ( ) . retain ( |id, _| allocs. is_live ( * id) ) ;
202
+ this. machine . alloc_addresses . borrow_mut ( ) . remove_unreachable_allocs ( & allocs) ;
203
+ if let Some ( borrow_tracker) = & this. machine . borrow_tracker {
204
+ borrow_tracker. borrow_mut ( ) . remove_unreachable_allocs ( & allocs) ;
205
+ }
206
+ // Clean up core (non-Miri-specific) state.
207
+ this. remove_unreachable_allocs ( & allocs. collected ) ;
208
+ }
209
+
187
210
impl < ' tcx > EvalContextExt < ' tcx > for crate :: MiriInterpCx < ' tcx > { }
188
211
pub trait EvalContextExt < ' tcx > : MiriInterpCxExt < ' tcx > {
189
212
fn run_provenance_gc ( & mut self ) {
190
- // We collect all tags from various parts of the interpreter, but also
191
213
let this = self . eval_context_mut ( ) ;
192
214
215
+ // We collect all tags and AllocId from every part of the interpreter.
193
216
let mut tags = FxHashSet :: default ( ) ;
194
217
let mut alloc_ids = FxHashSet :: default ( ) ;
195
218
this. visit_provenance ( & mut |id, tag| {
@@ -200,30 +223,9 @@ pub trait EvalContextExt<'tcx>: MiriInterpCxExt<'tcx> {
200
223
tags. insert ( tag) ;
201
224
}
202
225
} ) ;
203
- self . remove_unreachable_tags ( tags) ;
204
- self . remove_unreachable_allocs ( alloc_ids) ;
205
- }
206
-
207
- fn remove_unreachable_tags ( & mut self , tags : FxHashSet < BorTag > ) {
208
- let this = self . eval_context_mut ( ) ;
209
- this. memory . alloc_map ( ) . iter ( |it| {
210
- for ( _id, ( _kind, alloc) ) in it {
211
- if let Some ( bt) = & alloc. extra . borrow_tracker {
212
- bt. remove_unreachable_tags ( & tags) ;
213
- }
214
- }
215
- } ) ;
216
- }
217
226
218
- fn remove_unreachable_allocs ( & mut self , allocs : FxHashSet < AllocId > ) {
219
- let this = self . eval_context_mut ( ) ;
220
- let allocs = LiveAllocs { ecx : this, collected : allocs } ;
221
- this. machine . allocation_spans . borrow_mut ( ) . retain ( |id, _| allocs. is_live ( * id) ) ;
222
- this. machine . symbolic_alignment . borrow_mut ( ) . retain ( |id, _| allocs. is_live ( * id) ) ;
223
- this. machine . alloc_addresses . borrow_mut ( ) . remove_unreachable_allocs ( & allocs) ;
224
- if let Some ( borrow_tracker) = & this. machine . borrow_tracker {
225
- borrow_tracker. borrow_mut ( ) . remove_unreachable_allocs ( & allocs) ;
226
- }
227
- this. remove_unreachable_allocs ( & allocs. collected ) ;
227
+ // Based on this, clean up the interpreter state.
228
+ remove_unreachable_tags ( this, tags) ;
229
+ remove_unreachable_allocs ( this, alloc_ids) ;
228
230
}
229
231
}
0 commit comments