@@ -51,6 +51,13 @@ struct StackCache {
5151
5252#[ cfg( feature = "stack-cache" ) ]
5353impl StackCache {
54+ /// When a tag is used, we call this function to add or refresh it in the cache.
55+ ///
56+ /// We use position in the cache to represent how recently a tag was used; the first position
57+ /// is the most recently used tag. So an add shifts every element towards the end, and inserts
58+ /// the new element at the start. We lose the last element.
59+ /// This strategy is effective at keeping the most-accessed tags in the cache, but it costs a
60+ /// linear shift across the entire cache when we add a new tag.
5461 fn add ( & mut self , idx : usize , tag : SbTag ) {
5562 self . tags . copy_within ( 0 ..CACHE_LEN - 1 , 1 ) ;
5663 self . tags [ 0 ] = tag;
@@ -172,9 +179,12 @@ impl<'tcx> Stack {
172179 // If we found the tag, look up its position in the stack to see if it grants
173180 // the required permission
174181 if self . borrows [ stack_idx] . perm . grants ( access) {
175- // If it does, and it's already in the most-recently-used position, move it
176- // there.
177- if cache_idx != 0 {
182+ // If it does, and it's not already in the most-recently-used position, move it there.
183+ // Except if the tag is in position 1, this is equivalent to just a swap, so do that.
184+ if cache_idx == 1 {
185+ self . cache . tags . swap ( 0 , 1 ) ;
186+ self . cache . idx . swap ( 0 , 1 ) ;
187+ } else if cache_idx > 1 {
178188 self . cache . add ( stack_idx, tag) ;
179189 }
180190 Some ( stack_idx)
@@ -208,9 +218,13 @@ impl<'tcx> Stack {
208218
209219 // The above insert changes the meaning of every index in the cache >= new_idx, so now
210220 // we need to find every one of those indexes and increment it.
211- for idx in & mut self . cache . idx {
212- if * idx >= new_idx {
213- * idx += 1 ;
221+ // But if the insert is at the end (equivalent to a push), we can skip this step because
222+ // it didn't change the position of any other tags.
223+ if new_idx != self . borrows . len ( ) - 1 {
224+ for idx in & mut self . cache . idx {
225+ if * idx >= new_idx {
226+ * idx += 1 ;
227+ }
214228 }
215229 }
216230
0 commit comments