From 215ec38624818c4df9889c702fecb10c33b646ee Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 15 Nov 2018 18:15:05 +0100 Subject: [PATCH] track call IDs --- src/lib.rs | 20 ++++++++++++-- src/stacked_borrows.rs | 61 ++++++++++++++++++++++++++++++++---------- 2 files changed, 65 insertions(+), 16 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 591cf5766234..3211f9c5bd95 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -289,7 +289,7 @@ impl<'tcx> Evaluator<'tcx> { env_vars: HashMap::default(), tls: TlsData::default(), validate, - stacked_borrows: stacked_borrows::State::new(), + stacked_borrows: stacked_borrows::State::default(), } } } @@ -301,7 +301,8 @@ type MiriEvalContext<'a, 'mir, 'tcx> = EvalContext<'a, 'mir, 'tcx, Evaluator<'tc impl<'a, 'mir, 'tcx> Machine<'a, 'mir, 'tcx> for Evaluator<'tcx> { type MemoryKinds = MiriMemoryKind; - type MemoryExtra = (); + type FrameExtra = stacked_borrows::CallId; + type MemoryExtra = stacked_borrows::MemoryState; type AllocExtra = stacked_borrows::Stacks; type PointerTag = Borrow; @@ -538,4 +539,19 @@ impl<'a, 'mir, 'tcx> Machine<'a, 'mir, 'tcx> for Evaluator<'tcx> { ecx.retag(fn_entry, place) } } + + #[inline(always)] + fn stack_push( + ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>, + ) -> EvalResult<'tcx, stacked_borrows::CallId> { + Ok(ecx.memory().extra.borrow_mut().new_call()) + } + + #[inline(always)] + fn stack_pop( + ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>, + extra: stacked_borrows::CallId, + ) -> EvalResult<'tcx> { + Ok(ecx.memory().extra.borrow_mut().end_call(extra)) + } } diff --git a/src/stacked_borrows.rs b/src/stacked_borrows.rs index 22ec6ffe6f50..067e3bb8445f 100644 --- a/src/stacked_borrows.rs +++ b/src/stacked_borrows.rs @@ -1,4 +1,6 @@ use std::cell::RefCell; +use std::collections::HashSet; +use std::rc::Rc; use rustc::ty::{self, layout::Size}; use rustc::hir::{Mutability, MutMutable, MutImmutable}; @@ -10,6 +12,7 @@ use crate::{ }; pub type Timestamp = u64; +pub type CallId = u64; /// Information about which kind of borrow was used to create the reference this is tagged /// with. @@ -80,15 +83,6 @@ pub struct Stack { frozen_since: Option, // virtual frozen "item" on top of the stack } -impl Default for Stack { - fn default() -> Self { - Stack { - borrows: vec![BorStackItem::Shr], - frozen_since: None, - } - } -} - impl Stack { #[inline(always)] pub fn is_frozen(&self) -> bool { @@ -107,17 +101,50 @@ pub enum RefKind { Raw, } +/// Extra global state in the memory, available to the memory access hooks +#[derive(Debug)] +pub struct BarrierTracking { + next_id: CallId, + active_calls: HashSet, +} +pub type MemoryState = Rc>; + +impl Default for BarrierTracking { + fn default() -> Self { + BarrierTracking { + next_id: 0, + active_calls: HashSet::default(), + } + } +} + +impl BarrierTracking { + pub fn new_call(&mut self) -> CallId { + let id = self.next_id; + trace!("new_call: Assigning ID {}", id); + self.active_calls.insert(id); + self.next_id += 1; + id + } + + pub fn end_call(&mut self, id: CallId) { + assert!(self.active_calls.remove(&id)); + } +} + /// Extra global machine state #[derive(Clone, Debug)] pub struct State { clock: Timestamp } -impl State { - pub fn new() -> State { +impl Default for State { + fn default() -> Self { State { clock: 0 } } +} +impl State { fn increment_clock(&mut self) -> Timestamp { let val = self.clock; self.clock = val + 1; @@ -130,6 +157,7 @@ impl State { pub struct Stacks { // Even reading memory can have effects on the stack, so we need a `RefCell` here. stacks: RefCell>, + barrier_tracking: MemoryState, } /// Core per-location operations: deref, access, create. @@ -358,11 +386,16 @@ impl<'tcx> Stacks { } /// Hooks and glue -impl AllocationExtra for Stacks { +impl AllocationExtra for Stacks { #[inline(always)] - fn memory_allocated<'tcx>(size: Size, _extra: &()) -> Self { + fn memory_allocated<'tcx>(size: Size, extra: &MemoryState) -> Self { + let stack = Stack { + borrows: vec![BorStackItem::Shr], + frozen_since: None, + }; Stacks { - stacks: RefCell::new(RangeMap::new(size, Stack::default())) + stacks: RefCell::new(RangeMap::new(size, stack)), + barrier_tracking: Rc::clone(extra), } }