@@ -53,7 +53,7 @@ struct StackCache {
5353impl StackCache {
5454 /// When a tag is used, we call this function to add or refresh it in the cache.
5555 ///
56- /// We use position in the cache to represent how recently a tag was used; the first position
56+ /// We use the position in the cache to represent how recently a tag was used; the first position
5757 /// is the most recently used tag. So an add shifts every element towards the end, and inserts
5858 /// the new element at the start. We lose the last element.
5959 /// This strategy is effective at keeping the most-accessed tags in the cache, but it costs a
@@ -104,7 +104,7 @@ impl<'tcx> Stack {
104104 /// index is given it means the match was *not* in the known part of the stack.
105105 /// `Ok(None)` indicates it matched the "unknown" part of the stack.
106106 /// `Err` indicates it was not found.
107- pub fn find_granting (
107+ pub ( super ) fn find_granting (
108108 & mut self ,
109109 access : AccessKind ,
110110 tag : SbTagExtra ,
@@ -167,9 +167,15 @@ impl<'tcx> Stack {
167167
168168 #[ cfg( feature = "stack-cache" ) ]
169169 fn find_granting_cache ( & mut self , access : AccessKind , tag : SbTag ) -> Option < usize > {
170- // When the borrow stack is empty, there are no tags we could put into the cache that would
171- // be valid. Additionally, since lookups into the cache are a linear search it doesn't make
172- // sense to use the cache when it is no smaller than a search of the borrow stack itself.
170+ // This looks like a common-sense optimization; we're going to do a linear search of the
171+ // cache or the borrow stack to scan the shorter of the two. This optimization is miniscule
172+ // and this check actually ensures we do not access an invalid cache.
173+ // When a stack is created and when tags are removed from the top of the borrow stack, we
174+ // need some valid value to populate the cache. In both cases, we try to use the bottom
175+ // item. But when the stack is cleared in `set_unknown_bottom` there is nothing we could
176+ // place in the cache that is correct. But due to the way we populate the cache in
177+ // `StackCache::add`, we know that when the borrow stack has grown larger than the cache,
178+ // every slot in the cache is valid.
173179 if self . borrows . len ( ) <= CACHE_LEN {
174180 return None ;
175181 }
@@ -261,6 +267,9 @@ impl<'tcx> Stack {
261267 }
262268
263269 pub fn set_unknown_bottom ( & mut self , tag : SbTag ) {
270+ // We clear the borrow stack but the lookup cache doesn't support clearing per se. Instead,
271+ // there is a check explained in `find_granting_cache` which protects against accessing the
272+ // cache when it has been cleared and not yet refilled.
264273 self . borrows . clear ( ) ;
265274 self . unknown_bottom = Some ( tag) ;
266275 }
0 commit comments