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,
pub(super) total_read_count: AtomicU64,
pub(super) 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 DepNodes 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: FingerprintAnonymous DepNodes 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 NodeIds 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 a hash of the number of previous sessions.
total_read_count: AtomicU64These are simple counters that are for profiling and
debugging and only active with debug_assertions.
total_duplicate_read_count: AtomicU64Implementations§
Source§impl<D: Deps> CurrentDepGraph<D>
impl<D: Deps> CurrentDepGraph<D>
fn new( session: &Session, prev_graph_node_count: usize, encoder: FileEncoder, previous: Arc<SerializedDepGraph>, ) -> Self
fn record_edge( &self, dep_node_index: DepNodeIndex, key: DepNode, fingerprint: Fingerprint, )
fn record_node( &self, dep_node_index: DepNodeIndex, key: DepNode, _current_fingerprint: Fingerprint, )
Sourcefn alloc_new_node(
&self,
key: DepNode,
edges: EdgesVec,
current_fingerprint: Fingerprint,
) -> DepNodeIndex
fn alloc_new_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>
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> 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<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