rustc_query_system::dep_graph::graph

Struct CurrentDepGraph

source
pub(super) struct CurrentDepGraph<D: Deps> {
    encoder: GraphEncoder<D>,
    new_node_to_index: Sharded<FxHashMap<DepNode, DepNodeIndex>>,
    prev_index_to_index: Lock<IndexVec<SerializedDepNodeIndex, Option<DepNodeIndex>>>,
    fingerprints: Lock<IndexVec<DepNodeIndex, Option<Fingerprint>>>,
    forbidden_edge: Option<EdgeFilter>,
    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 DepNodes more than once as map keys. The new_node_to_index map only contains nodes 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, new_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: new_node_to_index and data, or prev_index_to_index and data. When manipulating both, we acquire new_node_to_index or prev_index_to_index first, and data second.

Fields§

§encoder: GraphEncoder<D>§new_node_to_index: Sharded<FxHashMap<DepNode, DepNodeIndex>>§prev_index_to_index: Lock<IndexVec<SerializedDepNodeIndex, Option<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.

§anon_id_seed: Fingerprint

Anonymous 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 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>

source

fn new( profiler: &SelfProfilerRef, prev_graph_node_count: usize, encoder: FileEncoder, record_graph: bool, record_stats: bool, previous: Arc<SerializedDepGraph>, ) -> Self

source

fn record_edge( &self, dep_node_index: DepNodeIndex, key: DepNode, fingerprint: Fingerprint, )

source

fn intern_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.

source

fn intern_node( &self, prev_graph: &SerializedDepGraph, key: DepNode, edges: EdgesVec, fingerprint: Option<Fingerprint>, ) -> (DepNodeIndex, Option<(SerializedDepNodeIndex, DepNodeColor)>)

source

fn promote_node_and_deps_to_current( &self, prev_graph: &SerializedDepGraph, prev_index: SerializedDepNodeIndex, ) -> DepNodeIndex

source

fn debug_assert_not_in_new_nodes( &self, prev_graph: &SerializedDepGraph, prev_index: SerializedDepNodeIndex, )

Auto Trait Implementations§

§

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> Aligned for T

source§

const ALIGN: Alignment = _

Alignment of Self.
source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T, R> CollectAndApply<T, R> for T

source§

fn collect_and_apply<I, F>(iter: I, f: F) -> R
where I: Iterator<Item = T>, F: FnOnce(&[T]) -> R,

Equivalent to f(&iter.collect::<Vec<_>>()).

source§

type Output = R

source§

impl<T> Filterable for T

source§

fn filterable( self, filter_name: &'static str, ) -> RequestFilterDataProvider<T, fn(_: DataRequest<'_>) -> bool>

Creates a filterable data provider with the given name for debugging. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> IntoEither for T

source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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 more
source§

impl<T> Same for T

source§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

source§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<I, T, U> Upcast<I, U> for T
where U: UpcastFrom<I, T>,

source§

fn upcast(self, interner: I) -> U

source§

impl<I, T> UpcastFrom<I, T> for T

source§

fn upcast_from(from: T, _tcx: I) -> T

source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

source§

fn vzip(self) -> V

source§

impl<Tcx, T> Value<Tcx> for T
where Tcx: DepContext,

source§

default fn from_cycle_error( tcx: Tcx, cycle_error: &CycleError, _guar: ErrorGuaranteed, ) -> T

source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

impl<'a, T> Captures<'a> for T
where T: ?Sized,

source§

impl<T> ErasedDestructor for T
where T: 'static,

source§

impl<T> MaybeSendSync for T

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