Skip to content

Commit 119f642

Browse files
authored
Merge pull request #4654 from royAmmerschuber/feature/tree-visitor-refactor
Refactor TreeVisitor and Access Relatedness.
2 parents 63a18d4 + d4b194b commit 119f642

File tree

3 files changed

+45
-50
lines changed

3 files changed

+45
-50
lines changed

src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,7 @@ mod propagation_optimization_checks {
640640
impl Exhaustive for AccessRelatedness {
641641
fn exhaustive() -> Box<dyn Iterator<Item = Self>> {
642642
use AccessRelatedness::*;
643-
Box::new(vec![This, StrictChildAccess, AncestorAccess, CousinAccess].into_iter())
643+
Box::new(vec![ForeignAccess, LocalAccess].into_iter())
644644
}
645645
}
646646

@@ -716,13 +716,11 @@ mod propagation_optimization_checks {
716716
// We now assert it is idempotent, and never causes UB.
717717
// First, if the SIFA includes foreign reads, assert it is idempotent under foreign reads.
718718
if access >= IdempotentForeignAccess::Read {
719-
// We use `CousinAccess` here. We could also use `AncestorAccess`, since `transition::perform_access` treats these the same.
720-
// The only place they are treated differently is in protector end accesses, but these are not handled here.
721-
assert_eq!(perm, transition::perform_access(AccessKind::Read, AccessRelatedness::CousinAccess, perm, prot).unwrap());
719+
assert_eq!(perm, transition::perform_access(AccessKind::Read, AccessRelatedness::ForeignAccess, perm, prot).unwrap());
722720
}
723721
// Then, if the SIFA includes foreign writes, assert it is idempotent under foreign writes.
724722
if access >= IdempotentForeignAccess::Write {
725-
assert_eq!(perm, transition::perform_access(AccessKind::Write, AccessRelatedness::CousinAccess, perm, prot).unwrap());
723+
assert_eq!(perm, transition::perform_access(AccessKind::Write, AccessRelatedness::ForeignAccess, perm, prot).unwrap());
726724
}
727725
}
728726
}

src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs

Lines changed: 36 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use crate::borrow_tracker::tree_borrows::diagnostics::{
2424
};
2525
use crate::borrow_tracker::tree_borrows::foreign_access_skipping::IdempotentForeignAccess;
2626
use crate::borrow_tracker::tree_borrows::perms::PermTransition;
27-
use crate::borrow_tracker::tree_borrows::unimap::{UniEntry, UniIndex, UniKeyMap, UniValMap};
27+
use crate::borrow_tracker::tree_borrows::unimap::{UniIndex, UniKeyMap, UniValMap};
2828
use crate::borrow_tracker::{GlobalState, ProtectorKind};
2929
use crate::*;
3030

@@ -265,13 +265,15 @@ pub(super) struct Node {
265265
}
266266

267267
/// Data given to the transition function
268-
struct NodeAppArgs<'node> {
269-
/// Node on which the transition is currently being applied
270-
node: &'node mut Node,
271-
/// Mutable access to its permissions
272-
perm: UniEntry<'node, LocationState>,
273-
/// Relative position of the access
268+
struct NodeAppArgs<'visit> {
269+
/// The index of the current node.
270+
idx: UniIndex,
271+
/// Relative position of the access.
274272
rel_pos: AccessRelatedness,
273+
/// The node map of this tree.
274+
nodes: &'visit mut UniValMap<Node>,
275+
/// The permissions map of this tree.
276+
perms: &'visit mut UniValMap<LocationState>,
275277
}
276278
/// Data given to the error handler
277279
struct ErrHandlerArgs<'node, InErr> {
@@ -348,8 +350,7 @@ where
348350
idx: UniIndex,
349351
rel_pos: AccessRelatedness,
350352
) -> ContinueTraversal {
351-
let node = this.nodes.get_mut(idx).unwrap();
352-
let args = NodeAppArgs { node, perm: this.perms.entry(idx), rel_pos };
353+
let args = NodeAppArgs { idx, rel_pos, nodes: this.nodes, perms: this.perms };
353354
(self.f_continue)(&args)
354355
}
355356

@@ -359,16 +360,14 @@ where
359360
idx: UniIndex,
360361
rel_pos: AccessRelatedness,
361362
) -> Result<(), OutErr> {
362-
let node = this.nodes.get_mut(idx).unwrap();
363-
(self.f_propagate)(NodeAppArgs { node, perm: this.perms.entry(idx), rel_pos }).map_err(
364-
|error_kind| {
363+
(self.f_propagate)(NodeAppArgs { idx, rel_pos, nodes: this.nodes, perms: this.perms })
364+
.map_err(|error_kind| {
365365
(self.err_builder)(ErrHandlerArgs {
366366
error_kind,
367367
conflicting_info: &this.nodes.get(idx).unwrap().debug_info,
368368
accessed_info: &this.nodes.get(self.initial).unwrap().debug_info,
369369
})
370-
},
371-
)
370+
})
372371
}
373372

374373
fn go_upwards_from_accessed(
@@ -386,14 +385,14 @@ where
386385
// be handled differently here compared to the further parents
387386
// of `accesssed_node`.
388387
{
389-
self.propagate_at(this, accessed_node, AccessRelatedness::This)?;
388+
self.propagate_at(this, accessed_node, AccessRelatedness::LocalAccess)?;
390389
if matches!(visit_children, ChildrenVisitMode::VisitChildrenOfAccessed) {
391390
let accessed_node = this.nodes.get(accessed_node).unwrap();
392391
// We `rev()` here because we reverse the entire stack later.
393392
for &child in accessed_node.children.iter().rev() {
394393
self.stack.push((
395394
child,
396-
AccessRelatedness::AncestorAccess,
395+
AccessRelatedness::ForeignAccess,
397396
RecursionState::BeforeChildren,
398397
));
399398
}
@@ -404,7 +403,7 @@ where
404403
// not the subtree that contains the accessed node.
405404
let mut last_node = accessed_node;
406405
while let Some(current) = this.nodes.get(last_node).unwrap().parent {
407-
self.propagate_at(this, current, AccessRelatedness::StrictChildAccess)?;
406+
self.propagate_at(this, current, AccessRelatedness::LocalAccess)?;
408407
let node = this.nodes.get(current).unwrap();
409408
// We `rev()` here because we reverse the entire stack later.
410409
for &child in node.children.iter().rev() {
@@ -413,7 +412,7 @@ where
413412
}
414413
self.stack.push((
415414
child,
416-
AccessRelatedness::CousinAccess,
415+
AccessRelatedness::ForeignAccess,
417416
RecursionState::BeforeChildren,
418417
));
419418
}
@@ -741,7 +740,9 @@ impl<'tcx> Tree {
741740
// visit all children, skipping none
742741
|_| ContinueTraversal::Recurse,
743742
|args: NodeAppArgs<'_>| -> Result<(), TransitionError> {
744-
let NodeAppArgs { node, perm, .. } = args;
743+
let node = args.nodes.get(args.idx).unwrap();
744+
let perm = args.perms.entry(args.idx);
745+
745746
let perm =
746747
perm.get().copied().unwrap_or_else(|| node.default_location_state());
747748
if global.borrow().protected_tags.get(&node.tag)
@@ -812,32 +813,34 @@ impl<'tcx> Tree {
812813
// `perms_range` is only for diagnostics (it is the range of
813814
// the `RangeMap` on which we are currently working).
814815
let node_skipper = |access_kind: AccessKind, args: &NodeAppArgs<'_>| -> ContinueTraversal {
815-
let NodeAppArgs { node, perm, rel_pos } = args;
816+
let node = args.nodes.get(args.idx).unwrap();
817+
let perm = args.perms.get(args.idx);
816818

817-
let old_state = perm.get().copied().unwrap_or_else(|| node.default_location_state());
818-
old_state.skip_if_known_noop(access_kind, *rel_pos)
819+
let old_state = perm.copied().unwrap_or_else(|| node.default_location_state());
820+
old_state.skip_if_known_noop(access_kind, args.rel_pos)
819821
};
820822
let node_app = |perms_range: Range<u64>,
821823
access_kind: AccessKind,
822824
access_cause: diagnostics::AccessCause,
823825
args: NodeAppArgs<'_>|
824826
-> Result<(), TransitionError> {
825-
let NodeAppArgs { node, mut perm, rel_pos } = args;
827+
let node = args.nodes.get_mut(args.idx).unwrap();
828+
let mut perm = args.perms.entry(args.idx);
826829

827830
let old_state = perm.or_insert(node.default_location_state());
828831

829832
// Call this function now, which ensures it is only called when
830833
// `skip_if_known_noop` returns `Recurse`, due to the contract of
831834
// `traverse_this_parents_children_other`.
832-
old_state.record_new_access(access_kind, rel_pos);
835+
old_state.record_new_access(access_kind, args.rel_pos);
833836

834837
let protected = global.borrow().protected_tags.contains_key(&node.tag);
835-
let transition = old_state.perform_access(access_kind, rel_pos, protected)?;
838+
let transition = old_state.perform_access(access_kind, args.rel_pos, protected)?;
836839
// Record the event as part of the history
837840
if !transition.is_noop() {
838841
node.debug_info.history.push(diagnostics::Event {
839842
transition,
840-
is_foreign: rel_pos.is_foreign(),
843+
is_foreign: args.rel_pos.is_foreign(),
841844
access_cause,
842845
access_range: access_range_and_kind.map(|x| x.0),
843846
transition_range: perms_range,
@@ -1075,24 +1078,18 @@ impl VisitProvenance for Tree {
10751078
/// Relative position of the access
10761079
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
10771080
pub enum AccessRelatedness {
1078-
/// The accessed pointer is the current one
1079-
This,
1080-
/// The accessed pointer is a (transitive) child of the current one.
1081-
// Current pointer is excluded (unlike in some other places of this module
1082-
// where "child" is inclusive).
1083-
StrictChildAccess,
1084-
/// The accessed pointer is a (transitive) parent of the current one.
1085-
// Current pointer is excluded.
1086-
AncestorAccess,
1087-
/// The accessed pointer is neither of the above.
1088-
// It's a cousin/uncle/etc., something in a side branch.
1089-
CousinAccess,
1081+
/// The access happened either through the node itself or one of
1082+
/// its transitive children.
1083+
LocalAccess,
1084+
/// The access happened through this nodes ancestor or through
1085+
/// a sibling/cousin/uncle/etc.
1086+
ForeignAccess,
10901087
}
10911088

10921089
impl AccessRelatedness {
10931090
/// Check that access is either Ancestor or Distant, i.e. not
10941091
/// a transitive child (initial pointer included).
10951092
pub fn is_foreign(self) -> bool {
1096-
matches!(self, AccessRelatedness::AncestorAccess | AccessRelatedness::CousinAccess)
1093+
matches!(self, AccessRelatedness::ForeignAccess)
10971094
}
10981095
}

src/tools/miri/src/borrow_tracker/tree_borrows/tree/tests.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -263,15 +263,15 @@ mod spurious_read {
263263
match xy_rel {
264264
RelPosXY::MutuallyForeign =>
265265
match self {
266-
PtrSelector::X => (This, CousinAccess),
267-
PtrSelector::Y => (CousinAccess, This),
268-
PtrSelector::Other => (CousinAccess, CousinAccess),
266+
PtrSelector::X => (LocalAccess, ForeignAccess),
267+
PtrSelector::Y => (ForeignAccess, LocalAccess),
268+
PtrSelector::Other => (ForeignAccess, ForeignAccess),
269269
},
270270
RelPosXY::XChildY =>
271271
match self {
272-
PtrSelector::X => (This, StrictChildAccess),
273-
PtrSelector::Y => (AncestorAccess, This),
274-
PtrSelector::Other => (CousinAccess, CousinAccess),
272+
PtrSelector::X => (LocalAccess, LocalAccess),
273+
PtrSelector::Y => (ForeignAccess, LocalAccess),
274+
PtrSelector::Other => (ForeignAccess, ForeignAccess),
275275
},
276276
}
277277
}

0 commit comments

Comments
 (0)