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
SharedReadOnly
there 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: 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
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 Item
s 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 the
Sizerefers to the specific location in the
AllocRange` 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