@@ -184,12 +184,35 @@ impl LiveAllocs<'_, '_> {
184184 }
185185}
186186
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+
187210impl < ' tcx > EvalContextExt < ' tcx > for crate :: MiriInterpCx < ' tcx > { }
188211pub trait EvalContextExt < ' tcx > : MiriInterpCxExt < ' tcx > {
189212 fn run_provenance_gc ( & mut self ) {
190- // We collect all tags from various parts of the interpreter, but also
191213 let this = self . eval_context_mut ( ) ;
192214
215+ // We collect all tags and AllocId from every part of the interpreter.
193216 let mut tags = FxHashSet :: default ( ) ;
194217 let mut alloc_ids = FxHashSet :: default ( ) ;
195218 this. visit_provenance ( & mut |id, tag| {
@@ -200,30 +223,9 @@ pub trait EvalContextExt<'tcx>: MiriInterpCxExt<'tcx> {
200223 tags. insert ( tag) ;
201224 }
202225 } ) ;
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- }
217226
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) ;
228230 }
229231}
0 commit comments