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
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<SbTag>
) -> Result<Option<usize>, ()>
pub(super) fn find_granting(
&mut self,
access: AccessKind,
tag: ProvenanceExtra,
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,
global: &GlobalStateInner,
dcx: &mut DiagnosticCx<'_, '_, '_, '_, 'tcx>
) -> InterpResult<'tcx>
fn item_popped(
item: &Item,
global: &GlobalStateInner,
dcx: &mut DiagnosticCx<'_, '_, '_, '_, 'tcx>
) -> 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: ProvenanceExtra,
global: &mut GlobalStateInner,
dcx: &mut DiagnosticCx<'_, '_, '_, '_, 'tcx>,
exposed_tags: &FxHashSet<SbTag>
) -> InterpResult<'tcx>
fn access(
&mut self,
access: AccessKind,
tag: ProvenanceExtra,
global: &mut GlobalStateInner,
dcx: &mut DiagnosticCx<'_, '_, '_, '_, 'tcx>,
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: ProvenanceExtra,
global: &GlobalStateInner,
dcx: &mut DiagnosticCx<'_, '_, '_, '_, 'tcx>,
exposed_tags: &FxHashSet<SbTag>
) -> InterpResult<'tcx>
fn dealloc(
&mut self,
tag: ProvenanceExtra,
global: &GlobalStateInner,
dcx: &mut DiagnosticCx<'_, '_, '_, '_, 'tcx>,
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: ProvenanceExtra,
new: Item,
global: &mut GlobalStateInner,
dcx: &mut DiagnosticCx<'_, '_, '_, '_, 'tcx>,
exposed_tags: &FxHashSet<SbTag>
) -> InterpResult<'tcx>
fn grant(
&mut self,
derived_from: ProvenanceExtra,
new: Item,
global: &mut GlobalStateInner,
dcx: &mut DiagnosticCx<'_, '_, '_, '_, 'tcx>,
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 Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<V, T> VZip<V> for Twhere
V: MultiLane<T>,
impl<V, T> VZip<V> for Twhere
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