Skip to content

Commit

Permalink
Auto merge of rust-lang#2711 - RalfJung:btrack, r=RalfJung
Browse files Browse the repository at this point in the history
slight simplifications for borrow tracking

and some renaming for consistency
  • Loading branch information
bors committed Dec 2, 2022
2 parents 89dd322 + b12ce55 commit 4a64902
Show file tree
Hide file tree
Showing 9 changed files with 62 additions and 84 deletions.
52 changes: 29 additions & 23 deletions src/tools/miri/src/borrow_tracker/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ impl fmt::Debug for BorTag {
}
}

/// Per-frame data for borrow tracking
/// Per-call-stack-frame data for borrow tracking
#[derive(Debug)]
pub struct FrameExtra {
pub struct FrameState {
/// The ID of the call this frame corresponds to.
pub call_id: CallId,

Expand All @@ -72,7 +72,7 @@ pub struct FrameExtra {
pub protected_tags: SmallVec<[BorTag; 2]>,
}

impl VisitTags for FrameExtra {
impl VisitTags for FrameState {
fn visit_tags(&self, _visit: &mut dyn FnMut(BorTag)) {
// `protected_tags` are fine to GC.
}
Expand Down Expand Up @@ -190,17 +190,17 @@ impl GlobalStateInner {
id
}

pub fn new_frame(&mut self, machine: &MiriMachine<'_, '_>) -> FrameExtra {
pub fn new_frame(&mut self, machine: &MiriMachine<'_, '_>) -> FrameState {
let call_id = self.next_call_id;
trace!("new_frame: Assigning call ID {}", call_id);
if self.tracked_call_ids.contains(&call_id) {
machine.emit_diagnostic(NonHaltingDiagnostic::CreatedCallId(call_id));
}
self.next_call_id = NonZeroU64::new(call_id.get() + 1).unwrap();
FrameExtra { call_id, protected_tags: SmallVec::new() }
FrameState { call_id, protected_tags: SmallVec::new() }
}

pub fn end_call(&mut self, frame: &machine::FrameData<'_>) {
pub fn end_call(&mut self, frame: &machine::FrameExtra<'_>) {
for tag in &frame
.borrow_tracker
.as_ref()
Expand Down Expand Up @@ -253,10 +253,10 @@ impl GlobalStateInner {
alloc_size: Size,
kind: MemoryKind<machine::MiriMemoryKind>,
machine: &MiriMachine<'_, '_>,
) -> AllocExtra {
) -> AllocState {
match self.borrow_tracker_method {
BorrowTrackerMethod::StackedBorrows =>
AllocExtra::StackedBorrows(Box::new(RefCell::new(Stacks::new_allocation(
AllocState::StackedBorrows(Box::new(RefCell::new(Stacks::new_allocation(
id, alloc_size, self, kind, machine,
)))),
}
Expand Down Expand Up @@ -292,24 +292,30 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {

/// Extra per-allocation data for borrow tracking
#[derive(Debug, Clone)]
pub enum AllocExtra {
pub enum AllocState {
/// Data corresponding to Stacked Borrows
StackedBorrows(Box<RefCell<stacked_borrows::AllocExtra>>),
StackedBorrows(Box<RefCell<stacked_borrows::AllocState>>),
}

impl AllocExtra {
pub fn assert_sb(&self) -> &RefCell<stacked_borrows::AllocExtra> {
match self {
AllocExtra::StackedBorrows(ref sb) => sb,
impl machine::AllocExtra {
#[track_caller]
pub fn borrow_tracker_sb(&self) -> &RefCell<stacked_borrows::AllocState> {
match self.borrow_tracker {
Some(AllocState::StackedBorrows(ref sb)) => sb,
_ => panic!("expected Stacked Borrows borrow tracking, got something else"),
}
}

pub fn assert_sb_mut(&mut self) -> &mut RefCell<stacked_borrows::AllocExtra> {
match self {
AllocExtra::StackedBorrows(ref mut sb) => sb,
#[track_caller]
pub fn borrow_tracker_sb_mut(&mut self) -> &mut RefCell<stacked_borrows::AllocState> {
match self.borrow_tracker {
Some(AllocState::StackedBorrows(ref mut sb)) => sb,
_ => panic!("expected Stacked Borrows borrow tracking, got something else"),
}
}
}

impl AllocState {
pub fn before_memory_read<'tcx>(
&self,
alloc_id: AllocId,
Expand All @@ -318,7 +324,7 @@ impl AllocExtra {
machine: &MiriMachine<'_, 'tcx>,
) -> InterpResult<'tcx> {
match self {
AllocExtra::StackedBorrows(sb) =>
AllocState::StackedBorrows(sb) =>
sb.borrow_mut().before_memory_read(alloc_id, prov_extra, range, machine),
}
}
Expand All @@ -331,7 +337,7 @@ impl AllocExtra {
machine: &mut MiriMachine<'_, 'tcx>,
) -> InterpResult<'tcx> {
match self {
AllocExtra::StackedBorrows(sb) =>
AllocState::StackedBorrows(sb) =>
sb.get_mut().before_memory_write(alloc_id, prov_extra, range, machine),
}
}
Expand All @@ -344,22 +350,22 @@ impl AllocExtra {
machine: &mut MiriMachine<'_, 'tcx>,
) -> InterpResult<'tcx> {
match self {
AllocExtra::StackedBorrows(sb) =>
AllocState::StackedBorrows(sb) =>
sb.get_mut().before_memory_deallocation(alloc_id, prov_extra, range, machine),
}
}

pub fn remove_unreachable_tags(&self, tags: &FxHashSet<BorTag>) {
match self {
AllocExtra::StackedBorrows(sb) => sb.borrow_mut().remove_unreachable_tags(tags),
AllocState::StackedBorrows(sb) => sb.borrow_mut().remove_unreachable_tags(tags),
}
}
}

impl VisitTags for AllocExtra {
impl VisitTags for AllocState {
fn visit_tags(&self, visit: &mut dyn FnMut(BorTag)) {
match self {
AllocExtra::StackedBorrows(sb) => sb.visit_tags(visit),
AllocState::StackedBorrows(sb) => sb.visit_tags(visit),
}
}
}
40 changes: 6 additions & 34 deletions src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ mod stack;
pub use stack::Stack;
pub mod diagnostics;

pub type AllocExtra = Stacks;
pub type AllocState = Stacks;

/// Extra per-allocation state.
#[derive(Clone, Debug)]
Expand Down Expand Up @@ -500,10 +500,6 @@ impl Stacks {
})?;
Ok(())
}

fn expose_tag(&mut self, tag: BorTag) {
self.exposed_tags.insert(tag);
}
}

/// Retagging/reborrowing. There is some policy in here, such as which permissions
Expand Down Expand Up @@ -567,10 +563,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
// uncovers a non-supported `extern static`.
let extra = this.get_alloc_extra(alloc_id)?;
let mut stacked_borrows = extra
.borrow_tracker
.as_ref()
.expect("We should have borrow tracking data")
.assert_sb()
.borrow_tracker_sb()
.borrow_mut();
// Note that we create a *second* `DiagnosticCxBuilder` below for the actual retag.
// FIXME: can this be done cleaner?
Expand Down Expand Up @@ -681,12 +674,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
// We have to use shared references to alloc/memory_extra here since
// `visit_freeze_sensitive` needs to access the global state.
let alloc_extra = this.get_alloc_extra(alloc_id)?;
let mut stacked_borrows = alloc_extra
.borrow_tracker
.as_ref()
.expect("We should have borrow tracking data")
.assert_sb()
.borrow_mut();
let mut stacked_borrows = alloc_extra.borrow_tracker_sb().borrow_mut();
this.visit_freeze_sensitive(place, size, |mut range, frozen| {
// Adjust range.
range.start += base_offset;
Expand Down Expand Up @@ -736,12 +724,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
// Note that this asserts that the allocation is mutable -- but since we are creating a
// mutable pointer, that seems reasonable.
let (alloc_extra, machine) = this.get_alloc_extra_mut(alloc_id)?;
let stacked_borrows = alloc_extra
.borrow_tracker
.as_mut()
.expect("We should have borrow tracking data")
.assert_sb_mut()
.get_mut();
let stacked_borrows = alloc_extra.borrow_tracker_sb_mut().get_mut();
let item = Item::new(new_tag, perm, protect.is_some());
let range = alloc_range(base_offset, size);
let global = machine.borrow_tracker.as_ref().unwrap().borrow();
Expand Down Expand Up @@ -993,13 +976,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
// uncovers a non-supported `extern static`.
let alloc_extra = this.get_alloc_extra(alloc_id)?;
trace!("Stacked Borrows tag {tag:?} exposed in {alloc_id:?}");
alloc_extra
.borrow_tracker
.as_ref()
.expect("We should have borrow tracking data")
.assert_sb()
.borrow_mut()
.expose_tag(tag);
alloc_extra.borrow_tracker_sb().borrow_mut().exposed_tags.insert(tag);
}
AllocKind::Function | AllocKind::VTable | AllocKind::Dead => {
// No stacked borrows on these allocations.
Expand All @@ -1011,12 +988,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
fn print_stacks(&mut self, alloc_id: AllocId) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
let alloc_extra = this.get_alloc_extra(alloc_id)?;
let stacks = alloc_extra
.borrow_tracker
.as_ref()
.expect("We should have borrow tracking data")
.assert_sb()
.borrow();
let stacks = alloc_extra.borrow_tracker_sb().borrow();
for (range, stack) in stacks.stacks.iter_all() {
print!("{range:?}: [");
if let Some(bottom) = stack.unknown_bottom() {
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/src/concurrency/data_race.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ use super::{
weak_memory::EvalContextExt as _,
};

pub type AllocExtra = VClockAlloc;
pub type AllocState = VClockAlloc;

/// Valid atomic read-write orderings, alias of atomic::Ordering (not non-exhaustive).
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
Expand Down
14 changes: 7 additions & 7 deletions src/tools/miri/src/concurrency/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ pub struct Thread<'mir, 'tcx> {
thread_name: Option<Vec<u8>>,

/// The virtual call stack.
stack: Vec<Frame<'mir, 'tcx, Provenance, FrameData<'tcx>>>,
stack: Vec<Frame<'mir, 'tcx, Provenance, FrameExtra<'tcx>>>,

/// The function to call when the stack ran empty, to figure out what to do next.
/// Conceptually, this is the interpreter implementation of the things that happen 'after' the
Expand Down Expand Up @@ -232,7 +232,7 @@ impl VisitTags for Thread<'_, '_> {
}
}

impl VisitTags for Frame<'_, '_, Provenance, FrameData<'_>> {
impl VisitTags for Frame<'_, '_, Provenance, FrameExtra<'_>> {
fn visit_tags(&self, visit: &mut dyn FnMut(BorTag)) {
let Frame {
return_place,
Expand Down Expand Up @@ -385,20 +385,20 @@ impl<'mir, 'tcx: 'mir> ThreadManager<'mir, 'tcx> {
}

/// Borrow the stack of the active thread.
pub fn active_thread_stack(&self) -> &[Frame<'mir, 'tcx, Provenance, FrameData<'tcx>>] {
pub fn active_thread_stack(&self) -> &[Frame<'mir, 'tcx, Provenance, FrameExtra<'tcx>>] {
&self.threads[self.active_thread].stack
}

/// Mutably borrow the stack of the active thread.
fn active_thread_stack_mut(
&mut self,
) -> &mut Vec<Frame<'mir, 'tcx, Provenance, FrameData<'tcx>>> {
) -> &mut Vec<Frame<'mir, 'tcx, Provenance, FrameExtra<'tcx>>> {
&mut self.threads[self.active_thread].stack
}

pub fn all_stacks(
&self,
) -> impl Iterator<Item = &[Frame<'mir, 'tcx, Provenance, FrameData<'tcx>>]> {
) -> impl Iterator<Item = &[Frame<'mir, 'tcx, Provenance, FrameExtra<'tcx>>]> {
self.threads.iter().map(|t| &t.stack[..])
}

Expand Down Expand Up @@ -921,15 +921,15 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
}

#[inline]
fn active_thread_stack(&self) -> &[Frame<'mir, 'tcx, Provenance, FrameData<'tcx>>] {
fn active_thread_stack(&self) -> &[Frame<'mir, 'tcx, Provenance, FrameExtra<'tcx>>] {
let this = self.eval_context_ref();
this.machine.threads.active_thread_stack()
}

#[inline]
fn active_thread_stack_mut(
&mut self,
) -> &mut Vec<Frame<'mir, 'tcx, Provenance, FrameData<'tcx>>> {
) -> &mut Vec<Frame<'mir, 'tcx, Provenance, FrameExtra<'tcx>>> {
let this = self.eval_context_mut();
this.machine.threads.active_thread_stack_mut()
}
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/src/concurrency/weak_memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ use super::{
vector_clock::{VClock, VTimestamp, VectorIdx},
};

pub type AllocExtra = StoreBufferAlloc;
pub type AllocState = StoreBufferAlloc;

// Each store buffer must be bounded otherwise it will grow indefinitely.
// However, bounding the store buffer means restricting the amount of weak
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -988,7 +988,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
self.stack()[frame_idx].current_span()
}

fn stack(&self) -> &[Frame<'mir, 'tcx, Provenance, machine::FrameData<'tcx>>] {
fn stack(&self) -> &[Frame<'mir, 'tcx, Provenance, machine::FrameExtra<'tcx>>] {
self.threads.active_thread_stack()
}

Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ pub use crate::eval::{
pub use crate::helpers::EvalContextExt as _;
pub use crate::intptrcast::ProvenanceMode;
pub use crate::machine::{
AllocExtra, FrameData, MiriInterpCx, MiriInterpCxExt, MiriMachine, MiriMemoryKind,
AllocExtra, FrameExtra, MiriInterpCx, MiriInterpCxExt, MiriMachine, MiriMemoryKind,
PrimitiveLayouts, Provenance, ProvenanceExtra, PAGE_SIZE, STACK_ADDR, STACK_SIZE,
};
pub use crate::mono_hash_map::MonoHashMap;
Expand Down
Loading

0 comments on commit 4a64902

Please sign in to comment.