Skip to content

Commit

Permalink
Replace the Untagged index stack with a single index
Browse files Browse the repository at this point in the history
  • Loading branch information
saethlin committed Dec 31, 2021
1 parent 67df005 commit a73d32f
Showing 1 changed file with 43 additions and 29 deletions.
72 changes: 43 additions & 29 deletions src/stacked_borrows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ pub struct Stack {
/// search to be efficient, so we use the uniqueness guarantee to keep a map from tag to
/// position in the stack.
cache: FxHashMap<PtrId, usize>,
/// `Untagged` may occur multiple times so we store it outside of the map.
untagged: Vec<usize>,
/// Index of the most recently inserted Untagged
top_untagged: Option<usize>,
/// On a read, we need to disable all `Unique` above the granting item. We can avoid most of
/// this scan by keeping track of the region of the borrow stack that may contain `Unique`s.
first_unique: usize,
Expand Down Expand Up @@ -275,15 +275,32 @@ impl Permission {
impl<'tcx> Stack {
/// Find the item granting the given kind of access to the given tag, and return where
/// it is on the stack.
fn find_granting(&self, access: AccessKind, tag: SbTag) -> Option<usize> {
fn find_granting(&mut self, access: AccessKind, tag: SbTag) -> Option<usize> {
match tag {
SbTag::Untagged => {
let end = if let Some(idx) = self.top_untagged {
if self.borrows[idx].perm.grants(access) {
return Some(idx);
} else {
idx
}
} else {
self.borrows.len()
};
// Search top-to-bottom
for idx in self.untagged.iter().rev() {
for (idx, item) in self.borrows[..end]
.iter()
.enumerate()
.rev()
.filter(|(_, item)| item.tag == SbTag::Untagged)
{
if self.top_untagged.is_none() {
self.top_untagged = Some(idx);
}
// Return permission of the first item that grants access.
// We require a permission with the right tag, ensuring U3 and F3.
if self.borrows[*idx].perm.grants(access) {
return Some(*idx);
if item.perm.grants(access) {
return Some(idx);
}
}
return None;
Expand Down Expand Up @@ -389,9 +406,12 @@ impl<'tcx> Stack {
}
}

while self.untagged.last() >= Some(&first_incompatible_idx) {
self.untagged.pop();
if let Some(idx) = self.top_untagged {
if idx >= first_incompatible_idx {
self.top_untagged = None;
}
}

if first_incompatible_idx <= self.first_unique {
// We removed all the Unique items
self.first_unique = 0;
Expand Down Expand Up @@ -457,7 +477,6 @@ impl<'tcx> Stack {
}

self.cache.clear();
self.untagged.clear();
self.first_unique = 0;
self.last_unique = 0;

Expand Down Expand Up @@ -522,6 +541,10 @@ 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.

if new.tag == SbTag::Untagged && new_idx >= self.top_untagged.unwrap_or(0) {
self.top_untagged = Some(new_idx);
}

// Adjust the possibly-unique range if an insert occurs before or within it
if self.first_unique >= new_idx {
self.first_unique += 1;
Expand All @@ -541,20 +564,11 @@ impl<'tcx> Stack {
*self.cache.get_mut(&id).unwrap() += 1;
}
}
for idx in self.untagged.iter_mut().rev().take_while(|idx| **idx >= new_idx) {
*idx += 1;
}
}
// We've now made a (conceptual) hole in the tag lookup cache.
// Nothing maps to new_idx, because we've adjusted everything >= it.
match new.tag {
SbTag::Untagged => {
self.untagged.push(new_idx);
self.untagged.sort();
}
SbTag::Tagged(id) => {
self.cache.insert(id, new_idx);
}
if let SbTag::Tagged(id) = new.tag {
self.cache.insert(id, new_idx);
}
}

Expand All @@ -569,16 +583,16 @@ impl<'tcx> Stacks {
fn new(size: Size, perm: Permission, tag: SbTag) -> Self {
let item = Item { perm, tag, protector: None };
let mut cache = FxHashMap::default();
let mut untagged = Vec::new();
match item.tag {
SbTag::Untagged => {
untagged.push(0);
}
SbTag::Tagged(id) => {
cache.insert(id, 0);
}
if let SbTag::Tagged(id) = item.tag {
cache.insert(id, 0);
}
let stack = Stack { borrows: vec![item], cache, untagged, first_unique: 0, last_unique: 0 };
let stack = Stack {
borrows: vec![item],
cache,
first_unique: 0,
last_unique: 0,
top_untagged: None,
};

Stacks { stacks: RefCell::new(RangeMap::new(size, stack)) }
}
Expand Down

0 comments on commit a73d32f

Please sign in to comment.