Module rustc_middle::dep_graph::dep_node [−][src]
Nodes in the dependency graph.
A node in the dependency graph is represented by a DepNode.
A DepNode consists of a DepKind (which
specifies the kind of thing it represents, like a piece of HIR, MIR, etc.)
and a Fingerprint, a 128-bit hash value, the exact meaning of which
depends on the node’s DepKind. Together, the kind and the fingerprint
fully identify a dependency node, even across multiple compilation sessions.
In other words, the value of the fingerprint does not depend on anything
that is specific to a given compilation session, like an unpredictable
interning key (e.g., NodeId, DefId, Symbol) or the numeric value of a
pointer. The concept behind this could be compared to how git commit hashes
uniquely identify a given commit. The fingerprinting approach has
a few advantages:
- A
DepNodecan simply be serialized to disk and loaded in another session without the need to do any “rebasing” (like we have to do for Spans and NodeIds) or “retracing” (like we had to do forDefIdin earlier implementations of the dependency graph). - A
Fingerprintis just a bunch of bits, which allowsDepNodeto implementCopy,Sync,Send,Freeze, etc. - Since we just have a bit pattern,
DepNodecan be mapped from disk into memory without any post-processing (e.g., “abomination-style” pointer reconstruction). - Because a
DepNodeis self-contained, we can instantiateDepNodesthat refer to things that do not exist anymore. In previous implementationsDepNodecontained aDefId. ADepNodereferring to something that had been removed between the previous and the current compilation session could not be instantiated because the current compilation session contained noDefIdfor thing that had been removed.
DepNode definition happens in the define_dep_nodes!() macro. This macro
defines the DepKind enum. Each DepKind has its own parameters that are
needed at runtime in order to construct a valid DepNode fingerprint.
However, only CompileCodegenUnit is constructed explicitly (with
make_compile_codegen_unit).
Because the macro sees what parameters a given DepKind requires, it can
“infer” some properties for each kind of DepNode:
- Whether a
DepNodeof a given kind has any parameters at all. SomeDepNodes could represent global concepts with only one value. - Whether it is possible, in principle, to reconstruct a query key from a
given
DepNode. ManyDepKinds only require a singleDefIdparameter, in which case it is possible to map the node’s fingerprint back to theDefIdit was computed from. In other cases, too much information gets lost during fingerprint computation.
make_compile_codegen_unit, together with DepNode::new(), ensures that only
valid DepNode instances can be constructed. For example, the API does not
allow for constructing parameterless DepNodes with anything other
than a zeroed out fingerprint. More generally speaking, it relieves the
user of the DepNode API of having to know how to compute the expected
fingerprint for a given set of node parameters.
Modules
| dep_kind | |
| label_strs | Contains variant => str representations for constructing DepNode groups for tests. |
Structs
| DepKindStruct | This struct stores metadata about each DepKind. |
Enums
| DepKind | This enum serves as an index into the |
Statics
| DEP_KINDS |
Traits
| DepContext | |
| DepNodeExt | |
| DepNodeParams |
Functions
| dep_kind_from_label_string | |
| make_compile_codegen_unit |
Type Definitions
| DepNode |