Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimizing Stacked Borrows (part 1?): Cache locations of Tags in a Borrow Stack #1935

Merged
merged 5 commits into from
Jul 3, 2022
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 20 additions & 6 deletions src/stacked_borrows/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ struct StackCache {

#[cfg(feature = "stack-cache")]
impl StackCache {
/// When a tag is used, we call this function to add or refresh it in the cache.
///
/// We use position in the cache to represent how recently a tag was used; the first position
saethlin marked this conversation as resolved.
Show resolved Hide resolved
/// is the most recently used tag. So an add shifts every element towards the end, and inserts
/// the new element at the start. We lose the last element.
/// This strategy is effective at keeping the most-accessed tags in the cache, but it costs a
/// linear shift across the entire cache when we add a new tag.
fn add(&mut self, idx: usize, tag: SbTag) {
self.tags.copy_within(0..CACHE_LEN - 1, 1);
self.tags[0] = tag;
Expand Down Expand Up @@ -172,9 +179,12 @@ impl<'tcx> Stack {
// If we found the tag, look up its position in the stack to see if it grants
// the required permission
if self.borrows[stack_idx].perm.grants(access) {
// If it does, and it's already in the most-recently-used position, move it
// there.
if cache_idx != 0 {
// If it does, and it's not already in the most-recently-used position, move it there.
// Except if the tag is in position 1, this is equivalent to just a swap, so do that.
if cache_idx == 1 {
self.cache.tags.swap(0, 1);
self.cache.idx.swap(0, 1);
} else if cache_idx > 1 {
self.cache.add(stack_idx, tag);
saethlin marked this conversation as resolved.
Show resolved Hide resolved
}
Some(stack_idx)
Expand Down Expand Up @@ -208,9 +218,13 @@ impl<'tcx> Stack {

// The above insert changes the meaning of every index in the cache >= new_idx, so now
// we need to find every one of those indexes and increment it.
RalfJung marked this conversation as resolved.
Show resolved Hide resolved
for idx in &mut self.cache.idx {
if *idx >= new_idx {
*idx += 1;
// But if the insert is at the end (equivalent to a push), we can skip this step because
// it didn't change the position of any other tags.
if new_idx != self.borrows.len() - 1 {
for idx in &mut self.cache.idx {
if *idx >= new_idx {
*idx += 1;
}
}
}

Expand Down