pub(super) struct CurrentDepGraph<D: Deps> {
encoder: GraphEncoder<D>,
anon_node_to_index: ShardedHashMap<DepNode, DepNodeIndex>,
fingerprints: Lock<IndexVec<DepNodeIndex, Option<Fingerprint>>>,
forbidden_edge: Option<EdgeFilter>,
nodes_in_current_session: Option<Lock<FxHashMap<DepNode, DepNodeIndex>>>,
anon_id_seed: Fingerprint,
total_read_count: AtomicU64,
total_duplicate_read_count: AtomicU64,
}
Expand description
CurrentDepGraph
stores the dependency graph for the current session. It
will be populated as we run queries or tasks. We never remove nodes from the
graph: they are only added.
The nodes in it are identified by a DepNodeIndex
. We avoid keeping the nodes
in memory. This is important, because these graph structures are some of the
largest in the compiler.
For this reason, we avoid storing DepNode
s more than once as map
keys. The anon_node_to_index
map only contains nodes of anonymous queries not in the previous
graph, and we map nodes in the previous graph to indices via a two-step
mapping. SerializedDepGraph
maps from DepNode
to SerializedDepNodeIndex
,
and the prev_index_to_index
vector (which is more compact and faster than
using a map) maps from SerializedDepNodeIndex
to DepNodeIndex
.
This struct uses three locks internally. The data
, anon_node_to_index
,
and prev_index_to_index
fields are locked separately. Operations that take
a DepNodeIndex
typically just access the data
field.
We only need to manipulate at most two locks simultaneously:
anon_node_to_index
and data
, or prev_index_to_index
and data
. When
manipulating both, we acquire anon_node_to_index
or prev_index_to_index
first, and data
second.
Fields§
§encoder: GraphEncoder<D>
§anon_node_to_index: ShardedHashMap<DepNode, DepNodeIndex>
§fingerprints: Lock<IndexVec<DepNodeIndex, Option<Fingerprint>>>
This is used to verify that fingerprints do not change between the creation of a node and its recomputation.
forbidden_edge: Option<EdgeFilter>
Used to trap when a specific edge is added to the graph.
This is used for debug purposes and is only active with debug_assertions
.
nodes_in_current_session: Option<Lock<FxHashMap<DepNode, DepNodeIndex>>>
Used to verify the absence of hash collisions among DepNodes.
This field is only Some
if the -Z incremental_verify_ich
option is present
or if debug_assertions
are enabled.
The map contains all DepNodes that have been allocated in the current session so far.
anon_id_seed: Fingerprint
Anonymous DepNode
s are nodes whose IDs we compute from the list of
their edges. This has the beneficial side-effect that multiple anonymous
nodes can be coalesced into one without changing the semantics of the
dependency graph. However, the merging of nodes can lead to a subtle
problem during red-green marking: The color of an anonymous node from
the current session might “shadow” the color of the node with the same
ID from the previous session. In order to side-step this problem, we make
sure that anonymous NodeId
s allocated in different sessions don’t overlap.
This is implemented by mixing a session-key into the ID fingerprint of
each anon node. The session-key is just a random number generated when
the DepGraph
is created.
total_read_count: AtomicU64
These are simple counters that are for profiling and
debugging and only active with debug_assertions
.
total_duplicate_read_count: AtomicU64
Implementations§
Source§impl<D: Deps> CurrentDepGraph<D>
impl<D: Deps> CurrentDepGraph<D>
fn new( session: &Session, prev_graph_node_count: usize, encoder: FileEncoder, record_graph: bool, record_stats: bool, previous: Arc<SerializedDepGraph>, ) -> Self
fn record_edge( &self, dep_node_index: DepNodeIndex, key: DepNode, fingerprint: Fingerprint, )
Sourcefn alloc_node(
&self,
key: DepNode,
edges: EdgesVec,
current_fingerprint: Fingerprint,
) -> DepNodeIndex
fn alloc_node( &self, key: DepNode, edges: EdgesVec, current_fingerprint: Fingerprint, ) -> DepNodeIndex
Writes the node to the current dep-graph and allocates a DepNodeIndex
for it.
Assumes that this is a node that has no equivalent in the previous dep-graph.
fn debug_assert_not_in_new_nodes( &self, prev_graph: &SerializedDepGraph, prev_index: SerializedDepNodeIndex, )
Auto Trait Implementations§
impl<D> DynSend for CurrentDepGraph<D>where
D: DynSend,
impl<D> DynSync for CurrentDepGraph<D>where
D: DynSend,
impl<D> !Freeze for CurrentDepGraph<D>
impl<D> !RefUnwindSafe for CurrentDepGraph<D>
impl<D> Send for CurrentDepGraph<D>where
D: Send,
impl<D> !Sync for CurrentDepGraph<D>
impl<D> Unpin for CurrentDepGraph<D>where
D: Unpin,
impl<D> !UnwindSafe for CurrentDepGraph<D>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T, R> CollectAndApply<T, R> for T
impl<T, R> CollectAndApply<T, R> for T
Source§impl<T> Filterable for T
impl<T> Filterable for T
Source§fn filterable(
self,
filter_name: &'static str,
) -> RequestFilterDataProvider<T, fn(_: DataRequest<'_>) -> bool>
fn filterable( self, filter_name: &'static str, ) -> RequestFilterDataProvider<T, fn(_: DataRequest<'_>) -> bool>
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<I, T, U> Upcast<I, U> for Twhere
U: UpcastFrom<I, T>,
impl<I, T, U> Upcast<I, U> for Twhere
U: UpcastFrom<I, T>,
Source§impl<I, T> UpcastFrom<I, T> for T
impl<I, T> UpcastFrom<I, T> for T
fn upcast_from(from: T, _tcx: I) -> T
Source§impl<Tcx, T> Value<Tcx> for Twhere
Tcx: DepContext,
impl<Tcx, T> Value<Tcx> for Twhere
Tcx: DepContext,
default fn from_cycle_error( tcx: Tcx, cycle_error: &CycleError, _guar: ErrorGuaranteed, ) -> T
Source§impl<T> WithSubscriber for T
impl<T> WithSubscriber for T
Source§fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
Source§fn with_current_subscriber(self) -> WithDispatch<Self>
fn with_current_subscriber(self) -> WithDispatch<Self>
impl<T> ErasedDestructor for Twhere
T: 'static,
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: 512 bytes