pub struct Stack {
borrows: Vec<Item>,
unknown_bottom: Option<SbTag>,
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
SharedReadOnlythere can only be moreSharedReadOnly. - Except for
Untagged, no tag occurs in the stack more than once.
unknown_bottom: Option<SbTag>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: StackCacheA 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 Uniques.
Implementations
sourceimpl<'tcx> Stack
impl<'tcx> Stack
sourcepub(super) fn find_granting(
&mut self,
access: AccessKind,
tag: SbTagExtra,
exposed_tags: &FxHashSet<SbTag>
) -> Result<Option<usize>, ()>
pub(super) fn find_granting(
&mut self,
access: AccessKind,
tag: SbTagExtra,
exposed_tags: &FxHashSet<SbTag>
) -> 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: SbTag
) -> Option<usize>
fn find_granting_cache(&mut self, access: AccessKind, tag: SbTag) -> 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<SbTag>
pub fn set_unknown_bottom(&mut self, tag: SbTag)
sourcepub fn disable_uniques_starting_at<V: FnMut(Item) -> InterpResult<'tcx>>(
&mut self,
disable_start: usize,
visitor: V
) -> InterpResult<'tcx>
pub fn disable_uniques_starting_at<V: FnMut(Item) -> InterpResult<'tcx>>(
&mut self,
disable_start: usize,
visitor: V
) -> 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 Items from this Stack.
sourceimpl<'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_popped(
item: &Item,
provoking_access: Option<(SbTagExtra, AllocRange, Size, AccessKind)>,
global: &GlobalStateInner,
alloc_history: &mut AllocHistory
) -> InterpResult<'tcx>
fn item_popped(
item: &Item,
provoking_access: Option<(SbTagExtra, AllocRange, Size, AccessKind)>,
global: &GlobalStateInner,
alloc_history: &mut AllocHistory
) -> InterpResult<'tcx>
Check if the given item is protected.
The provoking_access argument is only used to produce diagnostics.
It is Some when we are granting the contained access for said tag, and it is
None during a deallocation.
Within provoking_access, the AllocRangerefers the entire operation, and theSizerefers to the specific location in theAllocRange` that we are
currently checking.
sourcefn access(
&mut self,
access: AccessKind,
tag: SbTagExtra,
(alloc_id, alloc_range, offset): (AllocId, AllocRange, Size),
global: &mut GlobalStateInner,
current_span: &mut CurrentSpan<'_, '_, 'tcx>,
alloc_history: &mut AllocHistory,
exposed_tags: &FxHashSet<SbTag>
) -> InterpResult<'tcx>
fn access(
&mut self,
access: AccessKind,
tag: SbTagExtra,
(alloc_id, alloc_range, offset): (AllocId, AllocRange, Size),
global: &mut GlobalStateInner,
current_span: &mut CurrentSpan<'_, '_, 'tcx>,
alloc_history: &mut AllocHistory,
exposed_tags: &FxHashSet<SbTag>
) -> 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: SbTagExtra,
(alloc_id, _alloc_range, _offset): (AllocId, AllocRange, Size),
global: &GlobalStateInner,
alloc_history: &mut AllocHistory,
exposed_tags: &FxHashSet<SbTag>
) -> InterpResult<'tcx>
fn dealloc(
&mut self,
tag: SbTagExtra,
(alloc_id, _alloc_range, _offset): (AllocId, AllocRange, Size),
global: &GlobalStateInner,
alloc_history: &mut AllocHistory,
exposed_tags: &FxHashSet<SbTag>
) -> 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: SbTagExtra,
new: Item,
(alloc_id, alloc_range, offset): (AllocId, AllocRange, Size),
global: &mut GlobalStateInner,
current_span: &mut CurrentSpan<'_, '_, 'tcx>,
alloc_history: &mut AllocHistory,
exposed_tags: &FxHashSet<SbTag>
) -> InterpResult<'tcx>
fn grant(
&mut self,
derived_from: SbTagExtra,
new: Item,
(alloc_id, alloc_range, offset): (AllocId, AllocRange, Size),
global: &mut GlobalStateInner,
current_span: &mut CurrentSpan<'_, '_, 'tcx>,
alloc_history: &mut AllocHistory,
exposed_tags: &FxHashSet<SbTag>
) -> InterpResult<'tcx>
Derive a new pointer from one with the given tag.
weak controls whether this operation is weak or strong: weak granting does not act as
an access, and they add the new item directly on top of the one it is derived
from instead of all the way at the top of the stack.
range refers the entire operation, and offset refers to the specific location in
range that we are currently checking.
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
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
impl<V, T> VZip<V> for T where
V: MultiLane<T>,
impl<V, T> VZip<V> for T where
V: MultiLane<T>,
fn vzip(self) -> V
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