pub struct Stack {
borrows: Vec<Item>,
unknown_bottom: Option<BorTag>,
cache: StackCache,
unique_range: Range<usize>,
}
Expand description
Extra per-location state.
Fields§
§borrows: Vec<Item>
Used mostly as a stack; never empty. Invariants:
- Above a
SharedReadOnly
there can only be moreSharedReadOnly
. - Except for
Untagged
, no tag occurs in the stack more than once.
unknown_bottom: Option<BorTag>
If this is Some(id)
, then the actual current stack is unknown. This can happen when
wildcard pointers are used to access this location. What we do know is that borrows
are at
the top of the stack, and below it are arbitrarily many items whose tag
is strictly less
than id
.
When the bottom is unknown, borrows
always has a SharedReadOnly
or Unique
at the bottom;
we never have the unknown-to-known boundary in an SRW group.
cache: StackCache
A small LRU cache of searches of the borrow stack.
unique_range: Range<usize>
On a read, we need to disable all Unique
above the granting item. We can avoid most of
this scan by keeping track of the region of the borrow stack that may contain Unique
s.
Implementations§
source§impl<'tcx> Stack
impl<'tcx> Stack
sourcefn verify_cache_consistency(&self)
fn verify_cache_consistency(&self)
Panics if any of the caching mechanisms have broken,
- The StackCache indices don’t refer to the parallel items,
- There are no Unique items outside of first_unique..last_unique
sourcepub(super) fn find_granting(
&mut self,
access: AccessKind,
tag: ProvenanceExtra,
exposed_tags: &FxHashSet<BorTag>
) -> Result<Option<usize>, ()>
pub(super) fn find_granting(
&mut self,
access: AccessKind,
tag: ProvenanceExtra,
exposed_tags: &FxHashSet<BorTag>
) -> Result<Option<usize>, ()>
Find the item granting the given kind of access to the given tag, and return where
it is on the stack. For wildcard tags, the given index is approximate, but if no
index is given it means the match was not in the known part of the stack.
Ok(None)
indicates it matched the “unknown” part of the stack.
Err
indicates it was not found.
fn find_granting_tagged(
&mut self,
access: AccessKind,
tag: BorTag
) -> Option<usize>
fn find_granting_cache(
&mut self,
access: AccessKind,
tag: BorTag
) -> Option<usize>
pub fn insert(&mut self, new_idx: usize, new: Item)
fn insert_cache(&mut self, new_idx: usize, new: Item)
pub fn get(&self, idx: usize) -> Option<Item>
pub fn len(&self) -> usize
pub fn unknown_bottom(&self) -> Option<BorTag>
pub fn set_unknown_bottom(&mut self, tag: BorTag)
sourcepub fn disable_uniques_starting_at(
&mut self,
disable_start: usize,
visitor: impl FnMut(Item) -> InterpResult<'tcx>
) -> InterpResult<'tcx>
pub fn disable_uniques_starting_at(
&mut self,
disable_start: usize,
visitor: impl FnMut(Item) -> InterpResult<'tcx>
) -> InterpResult<'tcx>
Find all Unique
elements in this borrow stack above granting_idx
, pass a copy of them
to the visitor
, then set their Permission
to Disabled
.
sourcepub fn pop_items_after<V: FnMut(Item) -> InterpResult<'tcx>>(
&mut self,
start: usize,
visitor: V
) -> InterpResult<'tcx>
pub fn pop_items_after<V: FnMut(Item) -> InterpResult<'tcx>>(
&mut self,
start: usize,
visitor: V
) -> InterpResult<'tcx>
Produces an iterator which iterates over range
in reverse, and when dropped removes that
range of Item
s from this Stack
.
source§impl<'tcx> Stack
impl<'tcx> Stack
Core per-location operations: access, dealloc, reborrow.
sourcefn find_first_write_incompatible(&self, granting: usize) -> usize
fn find_first_write_incompatible(&self, granting: usize) -> usize
Find the first write-incompatible item above the given one –
i.e, find the height to which the stack will be truncated when writing to granting
.
sourcefn item_invalidated(
item: &Item,
global: &GlobalStateInner,
dcx: &mut DiagnosticCx<'_, '_, '_, 'tcx>,
cause: ItemInvalidationCause
) -> InterpResult<'tcx>
fn item_invalidated(
item: &Item,
global: &GlobalStateInner,
dcx: &mut DiagnosticCx<'_, '_, '_, 'tcx>,
cause: ItemInvalidationCause
) -> InterpResult<'tcx>
The given item was invalidated – check its protectors for whether that will cause UB.
sourcefn access(
&mut self,
access: AccessKind,
tag: ProvenanceExtra,
global: &GlobalStateInner,
dcx: &mut DiagnosticCx<'_, '_, '_, 'tcx>,
exposed_tags: &FxHashSet<BorTag>
) -> InterpResult<'tcx>
fn access(
&mut self,
access: AccessKind,
tag: ProvenanceExtra,
global: &GlobalStateInner,
dcx: &mut DiagnosticCx<'_, '_, '_, 'tcx>,
exposed_tags: &FxHashSet<BorTag>
) -> InterpResult<'tcx>
Test if a memory access
using pointer tagged tag
is granted.
If yes, return the index of the item that granted it.
range
refers the entire operation, and offset
refers to the specific offset into the
allocation that we are currently checking.
sourcefn dealloc(
&mut self,
tag: ProvenanceExtra,
global: &GlobalStateInner,
dcx: &mut DiagnosticCx<'_, '_, '_, 'tcx>,
exposed_tags: &FxHashSet<BorTag>
) -> InterpResult<'tcx>
fn dealloc(
&mut self,
tag: ProvenanceExtra,
global: &GlobalStateInner,
dcx: &mut DiagnosticCx<'_, '_, '_, 'tcx>,
exposed_tags: &FxHashSet<BorTag>
) -> InterpResult<'tcx>
Deallocate a location: Like a write access, but also there must be no active protectors at all because we will remove all items.
sourcefn grant(
&mut self,
derived_from: ProvenanceExtra,
new: Item,
access: Option<AccessKind>,
global: &GlobalStateInner,
dcx: &mut DiagnosticCx<'_, '_, '_, 'tcx>,
exposed_tags: &FxHashSet<BorTag>
) -> InterpResult<'tcx>
fn grant(
&mut self,
derived_from: ProvenanceExtra,
new: Item,
access: Option<AccessKind>,
global: &GlobalStateInner,
dcx: &mut DiagnosticCx<'_, '_, '_, 'tcx>,
exposed_tags: &FxHashSet<BorTag>
) -> InterpResult<'tcx>
Derive a new pointer from one with the given tag.
access
indicates which kind of memory access this retag itself should correspond to.
Trait Implementations§
impl Eq for Stack
Auto Trait Implementations§
impl RefUnwindSafe for Stack
impl Send for Stack
impl Sync for Stack
impl Unpin for Stack
impl UnwindSafe for Stack
Blanket Implementations§
Layout§
Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain repr(...)
attributes. Please see the Rust Reference’s “Type Layout” chapter for details on type layout guarantees.
Size: 560 bytes