Skip to content

Commit e705a08

Browse files
committed
various minor cleanups
1 parent 614f446 commit e705a08

File tree

3 files changed

+66
-58
lines changed

3 files changed

+66
-58
lines changed

src/borrow_tracker/tree_borrows/mod.rs

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use rustc_middle::mir::{Mutability, RetagKind};
33
use rustc_middle::ty::layout::HasTypingEnv;
44
use rustc_middle::ty::{self, Ty};
55

6-
use self::tree::LocationState;
76
use crate::borrow_tracker::{GlobalState, GlobalStateInner, ProtectorKind};
87
use crate::concurrency::data_race::NaReadType;
98
use crate::*;
@@ -218,6 +217,15 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
218217
) -> InterpResult<'tcx, Option<Provenance>> {
219218
// Make sure the new permissions make sense as the initial permissions of a fresh tag.
220219
assert!(new_perm.freeze_perm.is_initial() && new_perm.nonfreeze_perm.is_initial());
220+
// SIFA of the frozen part must be weaker than SIFA of the non-frozen part, otherwise
221+
// `self.update_last_accessed_after_retag` will break the SIFA invariant (see `foreign_access_skipping.rs`).
222+
assert!(
223+
new_perm.freeze_perm.strongest_idempotent_foreign_access(new_perm.protector.is_some())
224+
<= new_perm
225+
.nonfreeze_perm
226+
.strongest_idempotent_foreign_access(new_perm.protector.is_some())
227+
);
228+
221229
let this = self.eval_context_mut();
222230
// Ensure we bail out if the pointer goes out-of-bounds (see miri#1050).
223231
this.check_ptr_access(place.ptr(), ptr_size, CheckInAllocMsg::Dereferenceable)?;
@@ -315,76 +323,72 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
315323
let span = this.machine.current_span();
316324
let alloc_extra = this.get_alloc_extra(alloc_id)?;
317325
let mut tree_borrows = alloc_extra.borrow_tracker_tb().borrow_mut();
318-
let prot = new_perm.protector.is_some();
319326

320327
// Store initial permissions and their corresponding range.
321-
let mut perms_map: RangeMap<LocationState> = RangeMap::new(
328+
let mut perms_map: RangeMap<Permission> = RangeMap::new(
322329
ptr_size,
323-
LocationState::new_uninit(
324-
Permission::new_disabled(),
325-
foreign_access_skipping::IdempotentForeignAccess::None,
326-
),
330+
Permission::new_disabled(), // this will be overwritten
327331
);
328332
// Keep track of whether the node has any part that allows for interior mutability.
333+
// FIXME: This misses `PhantomData<UnsafeCell<T>>` which could be considered a marker
334+
// for requesting interior mutability.
329335
let mut has_unsafe_cell = false;
330336

331337
this.visit_freeze_sensitive(place, ptr_size, |range, frozen| {
332338
has_unsafe_cell = has_unsafe_cell || !frozen;
333339

334-
// Adjust range.
335-
let mut range_with_offset = range;
336-
range_with_offset.start += base_offset;
337-
338340
// We are only ever `Frozen` inside the frozen bits.
339-
let (perm, access) = if frozen {
341+
let (perm_init, access) = if frozen {
340342
(new_perm.freeze_perm, new_perm.freeze_access)
341343
} else {
342344
(new_perm.nonfreeze_perm, new_perm.nonfreeze_access)
343345
};
344-
let strongest_idempotent = perm.strongest_idempotent_foreign_access(prot);
345346

346347
// Store initial permissions.
347-
let perm_init = LocationState::new_init(perm, strongest_idempotent);
348348
for (_perm_range, perm) in perms_map.iter_mut(range.start, range.size) {
349349
*perm = perm_init;
350350
}
351351

352352
// Some reborrows incur a read access to the parent.
353353
if access {
354+
// Adjust range to be relative to allocation start (rather than to `place`).
355+
let mut range_in_alloc = range;
356+
range_in_alloc.start += base_offset;
357+
354358
tree_borrows.perform_access(
355359
orig_tag,
356-
Some((range_with_offset, AccessKind::Read, diagnostics::AccessCause::Reborrow)),
360+
Some((range_in_alloc, AccessKind::Read, diagnostics::AccessCause::Reborrow)),
357361
this.machine.borrow_tracker.as_ref().unwrap(),
358362
alloc_id,
359363
this.machine.current_span(),
360-
)?
361-
}
362-
363-
// Also inform the data race model (but only if any bytes are actually affected).
364-
if range.size.bytes() > 0 && access {
365-
if let Some(data_race) = alloc_extra.data_race.as_vclocks_ref() {
366-
data_race.read(
367-
alloc_id,
368-
range_with_offset,
369-
NaReadType::Retag,
370-
Some(place.layout.ty),
371-
&this.machine,
372-
)?
364+
)?;
365+
366+
// Also inform the data race model (but only if any bytes are actually affected).
367+
if range.size.bytes() > 0 {
368+
if let Some(data_race) = alloc_extra.data_race.as_vclocks_ref() {
369+
data_race.read(
370+
alloc_id,
371+
range_in_alloc,
372+
NaReadType::Retag,
373+
Some(place.layout.ty),
374+
&this.machine,
375+
)?
376+
}
373377
}
374378
}
375379
interp_ok(())
376380
})?;
377381

378382
// Record the parent-child pair in the tree.
379383
tree_borrows.new_child(
380-
ptr_size,
381384
base_offset,
382385
orig_tag,
383386
new_tag,
384-
new_perm,
385387
perms_map,
388+
// Allow lazily writing to surrounding data if we found an `UnsafeCell`.
389+
if has_unsafe_cell { new_perm.nonfreeze_perm } else { new_perm.freeze_perm },
390+
new_perm.protector.is_some(),
386391
span,
387-
has_unsafe_cell,
388392
)?;
389393
drop(tree_borrows);
390394

src/borrow_tracker/tree_borrows/tree.rs

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ use rustc_data_structures::fx::FxHashSet;
1818
use rustc_span::Span;
1919
use smallvec::SmallVec;
2020

21-
use super::NewPermission;
2221
use crate::borrow_tracker::tree_borrows::Permission;
2322
use crate::borrow_tracker::tree_borrows::diagnostics::{
2423
self, NodeDebugInfo, TbError, TransitionError,
@@ -614,61 +613,64 @@ impl Tree {
614613
}
615614

616615
impl<'tcx> Tree {
617-
/// Insert a new tag in the tree
616+
/// Insert a new tag in the tree.
617+
///
618+
/// `initial_perms` defines the initial permissions for the part of memory
619+
/// that is already considered "initialized" immediately. The ranges in this
620+
/// map are relative to `base_offset`.
621+
/// `default_perm` defines the initial permission for the rest of the allocation.
618622
pub(super) fn new_child(
619623
&mut self,
620-
size: Size,
621624
base_offset: Size,
622625
parent_tag: BorTag,
623626
new_tag: BorTag,
624-
perm: NewPermission,
625-
perms_map: RangeMap<LocationState>,
627+
init_perms: RangeMap<Permission>,
628+
default_uninit_perm: Permission,
629+
protected: bool,
626630
span: Span,
627-
has_unsafe_cell: bool,
628631
) -> InterpResult<'tcx> {
629632
let idx = self.tag_mapping.insert(new_tag);
630633
let parent_idx = self.tag_mapping.get(&parent_tag).unwrap();
631-
// Allow lazily writing to surrounding data if we have a reference to interior mutable data.
632-
let default_initial_perm =
633-
if has_unsafe_cell { perm.nonfreeze_perm } else { perm.freeze_perm };
634-
let prot = perm.protector.is_some();
635634

636-
// SIFA of the frozen part must be weaker than SIFA of the non-frozen part, otherwise
637-
// `self.update_last_accessed_after_retag` will break the SIFA invariant (see `foreign_access_skipping.rs`).
638-
assert!(
639-
perm.freeze_perm.strongest_idempotent_foreign_access(prot)
640-
<= perm.nonfreeze_perm.strongest_idempotent_foreign_access(prot)
641-
);
642-
let strongest_idempotent = default_initial_perm.strongest_idempotent_foreign_access(prot);
635+
let default_strongest_idempotent =
636+
default_uninit_perm.strongest_idempotent_foreign_access(protected);
643637
// Create the node
644638
self.nodes.insert(
645639
idx,
646640
Node {
647641
tag: new_tag,
648642
parent: Some(parent_idx),
649643
children: SmallVec::default(),
650-
default_initial_perm,
651-
default_initial_idempotent_foreign_access: strongest_idempotent,
652-
debug_info: NodeDebugInfo::new(new_tag, default_initial_perm, span),
644+
default_initial_perm: default_uninit_perm,
645+
default_initial_idempotent_foreign_access: default_strongest_idempotent,
646+
debug_info: NodeDebugInfo::new(new_tag, default_uninit_perm, span),
653647
},
654648
);
655649
// Register new_tag as a child of parent_tag
656650
self.nodes.get_mut(parent_idx).unwrap().children.push(idx);
657651

658-
for (Range { start, end }, &perm) in perms_map.iter(Size::from_bytes(0), size) {
652+
for (Range { start, end }, &perm) in init_perms.iter(Size::from_bytes(0), init_perms.size())
653+
{
654+
assert!(perm.is_initial());
659655
for (_perms_range, perms) in self
660656
.rperms
661657
.iter_mut(Size::from_bytes(start) + base_offset, Size::from_bytes(end - start))
662658
{
663-
perms.insert(idx, perm);
659+
perms.insert(
660+
idx,
661+
LocationState::new_init(
662+
perm,
663+
perm.strongest_idempotent_foreign_access(protected),
664+
),
665+
);
664666
}
665667
}
666668

667669
// Inserting the new perms might have broken the SIFA invariant (see `foreign_access_skipping.rs`).
668670
// We now weaken the recorded SIFA for our parents, until the invariant is restored.
669671
// We could weaken them all to `LocalAccess`, but it is more efficient to compute the SIFA
670672
// for the new permission statically, and use that.
671-
self.update_last_accessed_after_retag(parent_idx, strongest_idempotent);
673+
self.update_last_accessed_after_retag(parent_idx, default_strongest_idempotent);
672674

673675
interp_ok(())
674676
}

src/range_map.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ impl<T> RangeMap<T> {
3131
RangeMap { v }
3232
}
3333

34+
pub fn size(&self) -> Size {
35+
let size = self.v.last().map(|x| x.range.end).unwrap_or(0);
36+
Size::from_bytes(size)
37+
}
38+
3439
/// Finds the index containing the given offset.
3540
fn find_offset(&self, offset: u64) -> usize {
3641
self.v
@@ -71,10 +76,7 @@ impl<T> RangeMap<T> {
7176
};
7277
// The first offset that is not included any more.
7378
let end = offset + len;
74-
assert!(
75-
end <= self.v.last().map(|x| x.range.end).unwrap_or(0),
76-
"iterating beyond the bounds of this RangeMap"
77-
);
79+
assert!(end <= self.size().bytes(), "iterating beyond the bounds of this RangeMap");
7880
slice
7981
.iter()
8082
.take_while(move |elem| elem.range.start < end)

0 commit comments

Comments
 (0)