Skip to content

Commit 9d8bf0d

Browse files
repair build, changes based on review
1 parent dfc9d61 commit 9d8bf0d

File tree

4 files changed

+67
-60
lines changed

4 files changed

+67
-60
lines changed

src/borrow_tracker/tree_borrows/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,8 @@ impl<'tcx> Tree {
109109
// This happens because the protected_tags map still contains all protected_tags, they only get removed after
110110
// `release_protector` got called on all the relevant tags.
111111
//
112-
// This is also why we dont call `WildcardState::verify_external_consistency` here.
112+
// This is also why we dont call `WildcardState::verify_external_consistency` here. Instead we call it
113+
// in `on_stack_pop` after the permission map gets updated.
113114
let access_level = p.permission().strongest_allowed_child_access(false);
114115
WildcardState::update_exposure(
115116
idx,

src/borrow_tracker/tree_borrows/tree.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,7 @@ impl<'tcx> Tree {
683683
// For this, we insert the correct entry for this tag based on its parent, if it exists.
684684
for (_, loc) in self.locations.iter_mut_all() {
685685
if let Some(parent_access) = loc.wildcard_accesses.get(parent_idx) {
686-
loc.wildcard_accesses.insert(idx, parent_access.get_new_child());
686+
loc.wildcard_accesses.insert(idx, parent_access.for_new_child());
687687
}
688688
}
689689

@@ -897,7 +897,7 @@ impl<'tcx> Tree {
897897
#[cfg(feature = "expensive-consistency-checks")]
898898
WildcardState::verify_external_consistency(
899899
args.idx,
900-
&args.nodes,
900+
args.nodes,
901901
&args.loc.perms,
902902
&args.loc.wildcard_accesses,
903903
&global.borrow().protected_tags,
@@ -1266,7 +1266,7 @@ impl VisitProvenance for Tree {
12661266

12671267
// We also need to keep around any exposed tags through which
12681268
// an access could still happen.
1269-
self.visit_wildcards(visit);
1269+
self.gc_visit_wildcards(visit);
12701270
}
12711271
}
12721272

src/borrow_tracker/tree_borrows/unimap.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,8 @@ impl<V> UniValMap<V> {
210210

211211
/// Weather the datastructure has been allocated.
212212
/// Does not mean the map contains any values.
213-
pub fn is_initialized(&self) -> bool {
214-
self.data.capacity() != 0
213+
pub fn is_empty(&self) -> bool {
214+
self.data.len() == 0 || self.data.iter().all(|v| v.is_none())
215215
}
216216
}
217217

src/borrow_tracker/tree_borrows/wildcard.rs

Lines changed: 60 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ pub enum WildcardAccessLevel {
2525
Write,
2626
}
2727

28-
/// Were relative to the node the access happened from.
28+
/// Where the access happened relative to the current node.
2929
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
3030
pub enum WildcardAccessRelatedness {
3131
/// The access definitively happened through a local node.
@@ -59,8 +59,8 @@ pub struct WildcardState {
5959
/// The maximum access level that could happen from an exposed node
6060
/// that is foreign to this node.
6161
///
62-
/// This is calculated as the `max()` of parents `max_foreign_access`,
63-
/// `exposed_as` and its siblings `max_local_access()`.
62+
/// This is calculated as the `max()` of the parent's `max_foreign_access`,
63+
/// `exposed_as` and the siblings' `max_local_access()`.
6464
max_foreign_access: WildcardAccessLevel,
6565
/// At what access level this node itself is exposed.
6666
exposed_as: WildcardAccessLevel,
@@ -76,8 +76,8 @@ impl Debug for WildcardState {
7676
}
7777
impl WildcardState {
7878
/// The maximum access level that could happen from an exposed
79-
/// node that is a local to this node.
80-
pub fn max_local_access(&self) -> WildcardAccessLevel {
79+
/// node that is local to this node.
80+
fn max_local_access(&self) -> WildcardAccessLevel {
8181
use WildcardAccessLevel::*;
8282
max(
8383
self.exposed_as,
@@ -100,7 +100,7 @@ impl WildcardState {
100100
}
101101

102102
/// From where relative to the node with this wildcard info a read access could happen.
103-
pub fn read_access_relatedness(&self) -> Option<WildcardAccessRelatedness> {
103+
fn read_access_relatedness(&self) -> Option<WildcardAccessRelatedness> {
104104
let has_foreign = self.max_foreign_access >= WildcardAccessLevel::Read;
105105
let has_local = self.max_local_access() >= WildcardAccessLevel::Read;
106106
use WildcardAccessRelatedness as E;
@@ -113,7 +113,7 @@ impl WildcardState {
113113
}
114114

115115
/// From where relative to the node with this wildcard info a write access could happen.
116-
pub fn write_access_relatedness(&self) -> Option<WildcardAccessRelatedness> {
116+
fn write_access_relatedness(&self) -> Option<WildcardAccessRelatedness> {
117117
let has_foreign = self.max_foreign_access == WildcardAccessLevel::Write;
118118
let has_local = self.max_local_access() == WildcardAccessLevel::Write;
119119
use WildcardAccessRelatedness as E;
@@ -129,7 +129,7 @@ impl WildcardState {
129129
/// wildcard info.
130130
/// The new node doesn't have any child reads/writes, but calculates max_foreign_access
131131
/// from its parent.
132-
pub fn get_new_child(&self) -> Self {
132+
pub fn for_new_child(&self) -> Self {
133133
Self {
134134
max_foreign_access: max(self.max_foreign_access, self.max_local_access()),
135135
..Default::default()
@@ -147,9 +147,10 @@ impl WildcardState {
147147
/// of at least `read`/`write`
148148
///
149149
/// * `new_foreign_access`, `old_foreign_access`:
150-
/// The max possible access level, that is foreign to all `children`.
150+
/// The max possible access level that is foreign to all `children`
151+
/// (i.e., it is not local to *any* of them).
151152
/// This can be calculated as the max of the parent's `exposed_as()`, `max_foreign_access`
152-
/// and of all `max_local_access()` of any nodes with the same parent, that are
153+
/// and of all `max_local_access()` of any nodes with the same parent that are
153154
/// not listed in `children`.
154155
///
155156
/// This access level changed from `old` to `new`, which is why we need to
@@ -172,9 +173,9 @@ impl WildcardState {
172173
}
173174

174175
// We need to consider that the children's `max_local_access()` affect each
175-
// others `max_foreign_access`, but do not affect their own `max_foreign_access`.
176+
// other's `max_foreign_access`, but do not affect their own `max_foreign_access`.
176177

177-
// The new `max_foreign_acces` for children with `max_locala_access()==Write`.
178+
// The new `max_foreign_acces` for children with `max_local_access()==Write`.
178179
let write_foreign_access = max(
179180
new_foreign_access,
180181
if child_writes > 1 {
@@ -263,8 +264,6 @@ impl WildcardState {
263264
if old_exposed_as == new_exposed_as {
264265
return;
265266
}
266-
// Whether we are upgrading or downgrading the allowed access rights.
267-
let is_upgrade = old_exposed_as < new_exposed_as;
268267

269268
let src_old_local_access = src_state.max_local_access();
270269

@@ -273,15 +272,20 @@ impl WildcardState {
273272
let src_new_local_access = src_state.max_local_access();
274273

275274
// Stack of nodes for which the max_foreign_access field needs to be updated.
275+
// Will be filled with the children of this node and its parents children before
276+
// we begin downwards traversal.
276277
let mut stack: Vec<(UniIndex, WildcardAccessLevel)> = Vec::new();
277278

278-
// Update the direct children of this node.
279+
// Add the direct children of this node to the stack.
279280
{
280281
let node = nodes.get(id).unwrap();
281282
Self::push_relevant_children(
282283
&mut stack,
284+
// new_foreign_access
283285
max(src_state.max_foreign_access, new_exposed_as),
286+
// old_foreign_access
284287
max(src_state.max_foreign_access, old_exposed_as),
288+
// Consider all children.
285289
src_state.child_reads,
286290
src_state.child_writes,
287291
node.children.iter().copied(),
@@ -291,7 +295,7 @@ impl WildcardState {
291295
// We need to propagate the tracking info up the tree, for this we traverse up the parents.
292296
// We can skip propagating info to the parent and siblings of a node if its access didn't change.
293297
{
294-
// The child from which we came from.
298+
// The child from which we came.
295299
let mut child = id;
296300
// This is the `max_local_access()` of the child we came from, before this update...
297301
let mut old_child_access = src_old_local_access;
@@ -305,28 +309,15 @@ impl WildcardState {
305309
let old_parent_state = parent_state.clone();
306310
use WildcardAccessLevel::*;
307311
// Updating this node's tracking state for its children.
308-
if is_upgrade {
309-
if new_child_access == Write {
310-
// None -> Write
311-
// Read -> Write
312-
parent_state.child_writes += 1;
313-
}
314-
if old_child_access == None {
315-
// None -> Read
316-
// None -> Write
317-
parent_state.child_reads += 1;
318-
}
319-
} else {
320-
if old_child_access == Write {
321-
// Write -> None
322-
// Write -> Read
323-
parent_state.child_writes -= 1;
324-
}
325-
if new_child_access == None {
326-
// Read -> None
327-
// Write -> None
328-
parent_state.child_reads -= 1;
329-
}
312+
match (old_child_access, new_child_access) {
313+
(None | Read, Write) => parent_state.child_writes += 1,
314+
(Write, None | Read) => parent_state.child_writes -= 1,
315+
_ => {}
316+
}
317+
match (old_child_access, new_child_access) {
318+
(None, Read | Write) => parent_state.child_reads += 1,
319+
(Read | Write, None) => parent_state.child_reads -= 1,
320+
_ => {}
330321
}
331322

332323
let old_parent_local_access = old_parent_state.max_local_access();
@@ -341,19 +332,22 @@ impl WildcardState {
341332
// it as part of the foreign access.
342333

343334
// it doesnt matter wether we read these from old or new
344-
let constant_factors =
335+
let parent_access =
345336
max(parent_state.exposed_as, parent_state.max_foreign_access);
346337

347-
// `state` contains the correct child_writes/reads counts for just the
348-
// siblings excluding `child`.
349-
let state = if is_upgrade { &old_parent_state } else { parent_state };
350-
338+
let sibling_reads =
339+
parent_state.child_reads - if new_child_access >= Read { 1 } else { 0 };
340+
let sibling_writes =
341+
parent_state.child_writes - if new_child_access == Write { 1 } else { 0 };
351342
Self::push_relevant_children(
352343
&mut stack,
353-
max(constant_factors, new_child_access),
354-
max(constant_factors, old_child_access),
355-
state.child_reads,
356-
state.child_writes,
344+
// new_foreign_access
345+
max(parent_access, new_child_access),
346+
// old_foreign_access
347+
max(parent_access, old_child_access),
348+
// Consider only siblings of child.
349+
sibling_reads,
350+
sibling_writes,
357351
parent_node.children.iter().copied().filter(|id| child != *id),
358352
wildcard_accesses,
359353
);
@@ -368,7 +362,7 @@ impl WildcardState {
368362
child = parent_id;
369363
}
370364
}
371-
// Traverses up the tree to update max_foreign_access fields of children and cousins who need to be updated.
365+
// Traverses down the tree to update max_foreign_access fields of children and cousins who need to be updated.
372366
while let Some((id, new_access)) = stack.pop() {
373367
let node = nodes.get(id).unwrap();
374368
let mut entry = wildcard_accesses.entry(id);
@@ -379,8 +373,11 @@ impl WildcardState {
379373

380374
Self::push_relevant_children(
381375
&mut stack,
376+
// new_foreign_access
382377
max(state.exposed_as, new_access),
378+
// old_foreign_access
383379
max(state.exposed_as, old_access),
380+
// Consider all children.
384381
state.child_reads,
385382
state.child_writes,
386383
node.children.iter().copied(),
@@ -406,9 +403,13 @@ impl Tree {
406403
let protected = protected_tags.contains_key(&tag);
407404
// TODO: Only initialize neccessary ranges.
408405
for (_, loc) in self.locations.iter_mut_all() {
409-
let perm = *loc.perms.entry(id).or_insert(node.default_location_state());
406+
let perm = loc
407+
.perms
408+
.get(id)
409+
.map(|p| p.permission())
410+
.unwrap_or_else(|| node.default_location_state().permission());
410411

411-
let access_type = perm.permission().strongest_allowed_child_access(protected);
412+
let access_type = perm.strongest_allowed_child_access(protected);
412413
WildcardState::update_exposure(
413414
id,
414415
access_type,
@@ -417,7 +418,9 @@ impl Tree {
417418
);
418419
}
419420
}
420-
pub(super) fn visit_wildcards(&self, visit: &mut VisitWith<'_>) {
421+
/// Visit all tags through which a wilcard access could happen.
422+
/// Used for GC.
423+
pub(super) fn gc_visit_wildcards(&self, visit: &mut VisitWith<'_>) {
421424
for (_, loc) in self.locations.iter_all() {
422425
let mut stack = vec![self.root];
423426
let mut has_exposed = false;
@@ -427,8 +430,7 @@ impl Tree {
427430
if node.is_exposed
428431
&& let Some(perm) = loc.perms.get(id)
429432
{
430-
// If the node is already protected, then it gets already visited
431-
// through the protector. So we can assume `protected=false`.
433+
// The protector doesn't matter for this check, as it never reduces access level to None.
432434
let access_level = perm.permission().strongest_allowed_child_access(false);
433435
if access_level != WildcardAccessLevel::None {
434436
visit(None, Some(node.tag))
@@ -486,7 +488,7 @@ impl WildcardState {
486488
}
487489

488490
// Checks if accesses is empty.
489-
if !wildcard_accesses.is_initialized() {
491+
if wildcard_accesses.is_empty() {
490492
return;
491493
}
492494

@@ -497,6 +499,8 @@ impl WildcardState {
497499

498500
let access = wildcard_accesses.get(id).unwrap();
499501

502+
// The foreign wildcard accesses possible at a node are determined by which accesses
503+
// can originate from their siblings, their parent, and from above their parent.
500504
let expected_max_foreign_access = if let Some(parent) = node.parent {
501505
let parent_node = nodes.get(parent).unwrap();
502506
let parent_state = wildcard_accesses.get(parent).unwrap();
@@ -517,6 +521,8 @@ impl WildcardState {
517521
WildcardAccessLevel::None
518522
};
519523

524+
// Count how many children can be the source of wildcard reads or writes
525+
// (either directly, or via their children).
520526
let child_accesses = node.children.iter().copied().map(|child| {
521527
let state = wildcard_accesses.get(child).unwrap();
522528
state.max_local_access()

0 commit comments

Comments
 (0)