@@ -51,6 +51,13 @@ struct StackCache {
51
51
52
52
#[ cfg( feature = "stack-cache" ) ]
53
53
impl 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.
54
61
fn add ( & mut self , idx : usize , tag : SbTag ) {
55
62
self . tags . copy_within ( 0 ..CACHE_LEN - 1 , 1 ) ;
56
63
self . tags [ 0 ] = tag;
@@ -172,9 +179,12 @@ impl<'tcx> Stack {
172
179
// If we found the tag, look up its position in the stack to see if it grants
173
180
// the required permission
174
181
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 {
178
188
self . cache . add ( stack_idx, tag) ;
179
189
}
180
190
Some ( stack_idx)
@@ -208,9 +218,13 @@ impl<'tcx> Stack {
208
218
209
219
// The above insert changes the meaning of every index in the cache >= new_idx, so now
210
220
// 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
+ }
214
228
}
215
229
}
216
230
0 commit comments