@@ -80,6 +80,8 @@ pub struct Stacks {
80
80
history : AllocHistory ,
81
81
/// The set of tags that have been exposed inside this allocation.
82
82
exposed_tags : FxHashSet < SbTag > ,
83
+ /// Whether this memory has been modified since the last time the tag GC ran
84
+ modified_since_last_gc : bool ,
83
85
}
84
86
85
87
/// Extra global state, available to the memory access hooks.
@@ -422,6 +424,7 @@ impl<'tcx> Stack {
422
424
let item = self . get ( idx) . unwrap ( ) ;
423
425
Stack :: item_popped ( & item, global, dcx) ?;
424
426
}
427
+
425
428
Ok ( ( ) )
426
429
}
427
430
@@ -496,6 +499,20 @@ impl<'tcx> Stack {
496
499
}
497
500
// # Stacked Borrows Core End
498
501
502
+ /// Integration with the SbTag garbage collector
503
+ impl Stacks {
504
+ pub fn remove_unreachable_tags ( & mut self , live_tags : & FxHashSet < SbTag > ) {
505
+ if self . modified_since_last_gc {
506
+ for stack in self . stacks . iter_mut_all ( ) {
507
+ if stack. len ( ) > 64 {
508
+ stack. retain ( live_tags) ;
509
+ }
510
+ }
511
+ self . modified_since_last_gc = false ;
512
+ }
513
+ }
514
+ }
515
+
499
516
/// Map per-stack operations to higher-level per-location-range operations.
500
517
impl < ' tcx > Stacks {
501
518
/// Creates a new stack with an initial tag. For diagnostic purposes, we also need to know
@@ -508,6 +525,7 @@ impl<'tcx> Stacks {
508
525
stacks : RangeMap :: new ( size, stack) ,
509
526
history : AllocHistory :: new ( id) ,
510
527
exposed_tags : FxHashSet :: default ( ) ,
528
+ modified_since_last_gc : false ,
511
529
}
512
530
}
513
531
@@ -522,6 +540,7 @@ impl<'tcx> Stacks {
522
540
& mut FxHashSet < SbTag > ,
523
541
) -> InterpResult < ' tcx > ,
524
542
) -> InterpResult < ' tcx > {
543
+ self . modified_since_last_gc = true ;
525
544
for ( offset, stack) in self . stacks . iter_mut ( range. start , range. size ) {
526
545
let mut dcx = dcx_builder. build ( & mut self . history , offset) ;
527
546
f ( stack, & mut dcx, & mut self . exposed_tags ) ?;
@@ -614,7 +633,7 @@ impl Stacks {
614
633
) -> InterpResult < ' tcx > {
615
634
trace ! ( "deallocation with tag {:?}: {:?}, size {}" , tag, alloc_id, range. size. bytes( ) ) ;
616
635
let dcx = DiagnosticCxBuilder :: dealloc ( & mut current_span, threads, tag) ;
617
- let state = state. borrow ( ) ;
636
+ let state = state. borrow_mut ( ) ;
618
637
self . for_each ( range, dcx, |stack, dcx, exposed_tags| {
619
638
stack. dealloc ( tag, & state, dcx, exposed_tags)
620
639
} ) ?;
0 commit comments