@@ -259,6 +259,8 @@ pub struct Tree {
259259 pub ( super ) rperms : RangeMap < UniValMap < LocationState > > ,
260260 /// The index of the root node.
261261 pub ( super ) root : UniIndex ,
262+ /// The number of nodes when we last ran the Garbage Collector
263+ nodes_at_last_gc : usize ,
262264}
263265
264266/// A node in the borrow tree. Each node is uniquely identified by a tag via
@@ -604,7 +606,7 @@ impl Tree {
604606 perms. insert ( root_idx, LocationState :: new_init ( Permission :: new_active ( ) ) ) ;
605607 RangeMap :: new ( size, perms)
606608 } ;
607- Self { root : root_idx, nodes, rperms, tag_mapping }
609+ Self { root : root_idx, nodes, rperms, tag_mapping, nodes_at_last_gc : 1 }
608610 }
609611}
610612
@@ -833,13 +835,30 @@ impl<'tcx> Tree {
833835
834836/// Integration with the BorTag garbage collector
835837impl Tree {
838+ /// The number of nodes in this tree
839+ pub fn nodes_count ( & self ) -> usize {
840+ self . tag_mapping . len ( )
841+ }
842+
843+ /// Whether the tree grew significantly since the last provenance GC run
844+ pub fn tree_grew_significantly_since_last_gc ( & self ) -> bool {
845+ let current = self . nodes_count ( ) ;
846+ // do not trigger the GC for small nodes
847+ let last = self . nodes_at_last_gc . max ( 50 ) ;
848+ // trigger the GC if the tree doubled since the last run,
849+ // or otherwise got "significantly" larger.
850+ // Note that for trees < 100 nodes, nothing happens.
851+ current > 2 * last || current > last + 1500
852+ }
853+
836854 pub fn remove_unreachable_tags ( & mut self , live_tags : & FxHashSet < BorTag > ) {
837855 self . remove_useless_children ( self . root , live_tags) ;
838856 // Right after the GC runs is a good moment to check if we can
839857 // merge some adjacent ranges that were made equal by the removal of some
840858 // tags (this does not necessarily mean that they have identical internal representations,
841859 // see the `PartialEq` impl for `UniValMap`)
842860 self . rperms . merge_adjacent_thorough ( ) ;
861+ self . nodes_at_last_gc = self . nodes_count ( ) ;
843862 }
844863
845864 /// Checks if a node is useless and should be GC'ed.
0 commit comments