Skip to content

Commit 692a477

Browse files
committed
Store dep node result fingerprints in a separate file
1 parent 90d1dc7 commit 692a477

File tree

12 files changed

+412
-324
lines changed

12 files changed

+412
-324
lines changed

src/librustc/dep_graph/graph.rs

Lines changed: 143 additions & 130 deletions
Large diffs are not rendered by default.

src/librustc/dep_graph/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ pub mod cgu_reuse_tracker;
1111
pub use self::dep_tracking_map::{DepTrackingMap, DepTrackingMapConfig};
1212
pub use self::dep_node::{DepNode, DepKind, DepConstructor, WorkProductId, RecoverKey, label_strs};
1313
pub use self::graph::{DepGraph, WorkProduct, DepNodeIndex, DepNodeColor, TaskDeps, hash_result};
14-
pub use self::graph::WorkProductFileKind;
14+
pub use self::graph::{DepGraphArgs, WorkProductFileKind};
1515
pub use self::prev::PreviousDepGraph;
1616
pub use self::query::DepGraphQuery;
1717
pub use self::safe::AssertDepGraphSafe;
1818
pub use self::safe::DepGraphSafe;
19-
pub use self::serialized::{SerializedDepGraph, SerializedDepNodeIndex};
19+
pub use self::serialized::SerializedDepGraph;

src/librustc/dep_graph/prev.rs

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,41 +2,35 @@ use crate::ich::Fingerprint;
22
use rustc_data_structures::fx::FxHashMap;
33
use rustc_data_structures::indexed_vec::IndexVec;
44
use super::dep_node::DepNode;
5-
use super::graph::DepNodeState;
6-
use super::serialized::{SerializedDepGraph, SerializedDepNodeIndex};
5+
use super::graph::DepNodeIndex;
6+
use super::serialized::SerializedDepGraph;
77

8-
#[derive(Debug, /*RustcEncodable, RustcDecodable,*/ Default)]
8+
#[derive(Debug, Default)]
99
pub struct PreviousDepGraph {
1010
/// Maps from dep nodes to their previous index, if any.
11-
index: FxHashMap<DepNode, SerializedDepNodeIndex>,
11+
index: FxHashMap<DepNode, DepNodeIndex>,
1212
/// The set of all DepNodes in the graph
13-
nodes: IndexVec<SerializedDepNodeIndex, DepNode>,
13+
nodes: IndexVec<DepNodeIndex, DepNode>,
1414
/// The set of all Fingerprints in the graph. Each Fingerprint corresponds to
1515
/// the DepNode at the same index in the nodes vector.
16-
fingerprints: IndexVec<SerializedDepNodeIndex, Fingerprint>,
16+
pub(super) fingerprints: IndexVec<DepNodeIndex, Fingerprint>,
1717
/// For each DepNode, stores the list of edges originating from that
1818
/// DepNode. Encoded as a [start, end) pair indexing into edge_list_data,
1919
/// which holds the actual DepNodeIndices of the target nodes.
20-
edge_list_indices: IndexVec<SerializedDepNodeIndex, (u32, u32)>,
20+
edge_list_indices: IndexVec<DepNodeIndex, (u32, u32)>,
2121
/// A flattened list of all edge targets in the graph. Edge sources are
2222
/// implicit in edge_list_indices.
23-
edge_list_data: Vec<SerializedDepNodeIndex>,
24-
/// A set of nodes which are no longer valid.
25-
pub(super) state: IndexVec<SerializedDepNodeIndex, DepNodeState>,
23+
edge_list_data: Vec<DepNodeIndex>,
2624
}
2725

2826
impl PreviousDepGraph {
2927
pub fn new(graph: SerializedDepGraph) -> PreviousDepGraph {
3028
let index: FxHashMap<_, _> = graph.nodes
3129
.iter_enumerated()
32-
.map(|(idx, dep_node)| {
33-
(dep_node.node, SerializedDepNodeIndex::from_u32(idx.as_u32()))
34-
})
30+
.map(|(idx, dep_node)| (dep_node.node, idx))
3531
.collect();
3632

37-
let fingerprints: IndexVec<SerializedDepNodeIndex, _> =
38-
graph.nodes.iter().map(|d| d.fingerprint).collect();
39-
let nodes: IndexVec<SerializedDepNodeIndex, _> =
33+
let nodes: IndexVec<DepNodeIndex, _> =
4034
graph.nodes.iter().map(|d| d.node).collect();
4135

4236
let total_edge_count: usize = graph.nodes.iter().map(|d| d.edges.len()).sum();
@@ -47,9 +41,7 @@ impl PreviousDepGraph {
4741
for (current_dep_node_index, edges) in graph.nodes.iter_enumerated()
4842
.map(|(i, d)| (i, &d.edges)) {
4943
let start = edge_list_data.len() as u32;
50-
edge_list_data.extend(edges.iter().map(|i| {
51-
SerializedDepNodeIndex::from_u32(i.as_u32())
52-
}));
44+
edge_list_data.extend(edges.iter().cloned());
5345
let end = edge_list_data.len() as u32;
5446

5547
debug_assert_eq!(current_dep_node_index.index(), edge_list_indices.len());
@@ -60,36 +52,35 @@ impl PreviousDepGraph {
6052
debug_assert_eq!(edge_list_data.len(), total_edge_count);
6153

6254
PreviousDepGraph {
63-
fingerprints,
55+
fingerprints: graph.fingerprints,
6456
nodes,
6557
edge_list_indices,
6658
edge_list_data,
6759
index,
68-
state: graph.state.convert_index_type(),
6960
}
7061
}
7162

7263
#[inline]
7364
pub fn edge_targets_from(
7465
&self,
75-
dep_node_index: SerializedDepNodeIndex
76-
) -> &[SerializedDepNodeIndex] {
66+
dep_node_index: DepNodeIndex
67+
) -> &[DepNodeIndex] {
7768
let targets = self.edge_list_indices[dep_node_index];
7869
&self.edge_list_data[targets.0 as usize..targets.1 as usize]
7970
}
8071

8172
#[inline]
82-
pub fn index_to_node(&self, dep_node_index: SerializedDepNodeIndex) -> DepNode {
73+
pub fn index_to_node(&self, dep_node_index: DepNodeIndex) -> DepNode {
8374
self.nodes[dep_node_index]
8475
}
8576

8677
#[inline]
87-
pub fn node_to_index(&self, dep_node: &DepNode) -> SerializedDepNodeIndex {
78+
pub fn node_to_index(&self, dep_node: &DepNode) -> DepNodeIndex {
8879
self.index[dep_node]
8980
}
9081

9182
#[inline]
92-
pub fn node_to_index_opt(&self, dep_node: &DepNode) -> Option<SerializedDepNodeIndex> {
83+
pub fn node_to_index_opt(&self, dep_node: &DepNode) -> Option<DepNodeIndex> {
9384
self.index.get(dep_node).cloned()
9485
}
9586

@@ -102,7 +93,7 @@ impl PreviousDepGraph {
10293

10394
#[inline]
10495
pub fn fingerprint_by_index(&self,
105-
dep_node_index: SerializedDepNodeIndex)
96+
dep_node_index: DepNodeIndex)
10697
-> Fingerprint {
10798
self.fingerprints[dep_node_index]
10899
}

src/librustc/dep_graph/serialized.rs

Lines changed: 94 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,86 @@
11
use rustc_data_structures::sync::worker::{Worker, WorkerExecutor};
2-
use rustc_data_structures::sync::Lrc;
2+
use rustc_data_structures::sync::{Lrc, AtomicCell};
33
use rustc_data_structures::{unlikely, cold_path};
4-
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
5-
use rustc_serialize::opaque;
6-
use rustc_serialize::{Decodable, Encodable};
4+
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
5+
use rustc_data_structures::fingerprint::Fingerprint;
6+
use rustc_serialize::{Decodable, Encodable, opaque};
77
use std::mem;
88
use std::fs::File;
99
use std::io::Write;
10+
use crate::dep_graph::dep_node::DepNode;
11+
use super::prev::PreviousDepGraph;
1012
use super::graph::{DepNodeData, DepNodeIndex, DepNodeState};
1113

12-
newtype_index! {
13-
pub struct SerializedDepNodeIndex { .. }
14-
}
15-
16-
impl SerializedDepNodeIndex {
17-
pub fn current(self) -> DepNodeIndex {
18-
DepNodeIndex::from_u32(self.as_u32())
19-
}
20-
}
21-
2214
#[derive(Debug, Default)]
2315
pub struct SerializedDepGraph {
24-
pub(super) nodes: IndexVec<DepNodeIndex, DepNodeData>,
25-
pub(super) state: IndexVec<DepNodeIndex, DepNodeState>,
16+
pub(super) nodes: IndexVec<DepNodeIndex, SerializedDepNodeData>,
17+
pub(super) fingerprints: IndexVec<DepNodeIndex, Fingerprint>,
18+
}
19+
20+
#[derive(Clone, Debug, RustcDecodable, RustcEncodable)]
21+
pub(super) struct SerializedDepNodeData {
22+
pub(super) node: DepNode,
23+
pub(super) edges: Vec<DepNodeIndex>,
2624
}
2725

2826
impl SerializedDepGraph {
29-
pub fn decode(d: &mut opaque::Decoder<'_>) -> Result<Self, String> {
30-
let mut nodes = IndexVec::new();
31-
let mut invalidated_list = Vec::new();
27+
pub fn decode(
28+
d: &mut opaque::Decoder<'_>,
29+
results_d: &mut opaque::Decoder<'_>,
30+
) -> Result<(Self, IndexVec<DepNodeIndex, AtomicCell<DepNodeState>>), String> {
31+
let fingerprints: IndexVec<DepNodeIndex, Fingerprint> = IndexVec::decode(results_d)?;
32+
let mut nodes = IndexVec::with_capacity(fingerprints.len());
33+
let mut state: IndexVec<_, _> = (0..fingerprints.len()).map(|_| {
34+
AtomicCell::new(DepNodeState::Unknown)
35+
}).collect();
3236
loop {
3337
if d.position() == d.data.len() {
3438
break;
3539
}
36-
match Action::decode(d)? {
37-
Action::NewNodes(new_nodes) => {
40+
match SerializedAction::decode(d)? {
41+
SerializedAction::NewNodes(new_nodes) => {
42+
for (i, data) in new_nodes.iter().enumerate() {
43+
// Mark the result of eval_always nodes as invalid so they will
44+
// get executed again.
45+
if unlikely!(data.node.kind.is_eval_always()) {
46+
let idx = DepNodeIndex::new(nodes.len() + i);
47+
state[idx] = AtomicCell::new(DepNodeState::Invalid);
48+
}
49+
}
3850
nodes.extend(new_nodes);
3951
}
40-
Action::UpdateNodes(changed) => {
41-
for (i, data) in changed {
42-
nodes[i] = data;
52+
SerializedAction::UpdateEdges(changed) => {
53+
for (i, edges) in changed {
54+
// Updated results are valid again, except for eval_always nodes
55+
// which always start out invalid.
56+
if likely!(!nodes[i].node.kind.is_eval_always()) {
57+
state[i] = AtomicCell::new(DepNodeState::Unknown);
58+
}
59+
nodes[i].edges = edges;
4360
}
4461
}
45-
Action::InvalidateNodes(nodes) => {
46-
invalidated_list.extend(nodes);
62+
SerializedAction::InvalidateNodes(nodes) => {
63+
for i in nodes {
64+
state[i] = AtomicCell::new(DepNodeState::Invalid);
65+
}
4766
}
4867
}
4968
}
50-
let mut state: IndexVec<_, _> = (0..nodes.len()).map(|_| {
51-
DepNodeState::Unknown
52-
}).collect();
53-
for i in invalidated_list {
54-
state[i] = DepNodeState::Invalidated;
55-
}
56-
Ok(SerializedDepGraph {
69+
Ok((SerializedDepGraph {
5770
nodes,
58-
state,
59-
})
71+
fingerprints,
72+
}, state))
6073
}
6174
}
6275

63-
#[derive(Debug, RustcEncodable, RustcDecodable)]
76+
#[derive(Debug, RustcDecodable, RustcEncodable)]
77+
enum SerializedAction {
78+
NewNodes(Vec<SerializedDepNodeData>),
79+
UpdateEdges(Vec<(DepNodeIndex, Vec<DepNodeIndex>)>),
80+
InvalidateNodes(Vec<DepNodeIndex>)
81+
}
82+
83+
#[derive(Debug)]
6484
enum Action {
6585
NewNodes(Vec<DepNodeData>),
6686
UpdateNodes(Vec<(DepNodeIndex, DepNodeData)>),
@@ -73,36 +93,66 @@ enum Action {
7393
}
7494

7595
struct SerializerWorker {
96+
fingerprints: IndexVec<DepNodeIndex, Fingerprint>,
97+
previous: Lrc<PreviousDepGraph>,
7698
file: File,
7799
}
78100

79101
impl Worker for SerializerWorker {
80102
type Message = (usize, Action);
81-
type Result = ();
103+
type Result = IndexVec<DepNodeIndex, Fingerprint>;
82104

83105
fn message(&mut self, (buffer_size_est, action): (usize, Action)) {
84106
let mut encoder = opaque::Encoder::new(Vec::with_capacity(buffer_size_est * 5));
107+
let action = match action {
108+
Action::UpdateNodes(nodes) => {
109+
SerializedAction::UpdateEdges(nodes.into_iter().filter(|&(i, ref data)| {
110+
self.fingerprints[i] = data.fingerprint;
111+
// Only emit nodes which actually changed
112+
&*data.edges != self.previous.edge_targets_from(i)
113+
}).map(|(i, data)| (i, data.edges.into_iter().collect::<Vec<_>>())).collect())
114+
}
115+
Action::NewNodes(nodes) => {
116+
SerializedAction::NewNodes(nodes.into_iter().map(|data| {
117+
self.fingerprints.push(data.fingerprint);
118+
SerializedDepNodeData {
119+
node: data.node,
120+
edges: data.edges.into_iter().collect(),
121+
}
122+
}).collect())
123+
}
124+
Action::InvalidateNodes(nodes) => SerializedAction::InvalidateNodes(nodes),
125+
};
85126
action.encode(&mut encoder).ok();
86127
self.file.write_all(&encoder.into_inner()).expect("unable to write to temp dep graph");
87128
}
88129

89-
fn complete(self) {}
130+
fn complete(self) -> IndexVec<DepNodeIndex, Fingerprint> {
131+
self.fingerprints
132+
}
90133
}
91134

92135
const BUFFER_SIZE: usize = 800000;
93136

94137
pub struct Serializer {
95138
worker: Lrc<WorkerExecutor<SerializerWorker>>,
139+
node_count: u32,
96140
new_buffer: Vec<DepNodeData>,
97141
new_buffer_size: usize,
98142
updated_buffer: Vec<(DepNodeIndex, DepNodeData)>,
99143
updated_buffer_size: usize,
100144
}
101145

102146
impl Serializer {
103-
pub fn new(file: File) -> Self {
147+
pub fn new(
148+
file: File,
149+
previous: Lrc<PreviousDepGraph>,
150+
) -> Self {
104151
Serializer {
152+
node_count: previous.node_count() as u32,
105153
worker: Lrc::new(WorkerExecutor::new(SerializerWorker {
154+
fingerprints: previous.fingerprints.clone(),
155+
previous,
106156
file,
107157
})),
108158
new_buffer: Vec::with_capacity(BUFFER_SIZE),
@@ -120,7 +170,7 @@ impl Serializer {
120170
}
121171

122172
#[inline]
123-
pub(super) fn serialize_new(&mut self, data: DepNodeData) {
173+
pub(super) fn serialize_new(&mut self, data: DepNodeData) -> DepNodeIndex {
124174
let edges = data.edges.len();
125175
self.new_buffer.push(data);
126176
self.new_buffer_size += 8 + edges;
@@ -129,6 +179,9 @@ impl Serializer {
129179
self.flush_new();
130180
})
131181
}
182+
let index = self.node_count;
183+
self.node_count += 1;
184+
DepNodeIndex::from_u32(index)
132185
}
133186

134187
fn flush_updated(&mut self) {
@@ -153,7 +206,7 @@ impl Serializer {
153206
pub fn complete(
154207
&mut self,
155208
invalidate: Vec<DepNodeIndex>,
156-
) {
209+
) -> IndexVec<DepNodeIndex, Fingerprint> {
157210
if self.new_buffer.len() > 0 {
158211
self.flush_new();
159212
}

src/librustc/query/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::ty::query::QueryDescription;
22
use crate::ty::query::queries;
33
use crate::ty::{self, ParamEnvAnd, Ty, TyCtxt};
44
use crate::ty::subst::SubstsRef;
5-
use crate::dep_graph::SerializedDepNodeIndex;
5+
use crate::dep_graph::DepNodeIndex;
66
use crate::hir::def_id::{CrateNum, DefId, DefIndex};
77
use crate::mir::interpret::GlobalId;
88
use crate::traits;

src/librustc/ty/query/config.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::dep_graph::SerializedDepNodeIndex;
1+
use crate::dep_graph::DepNodeIndex;
22
use crate::dep_graph::DepNode;
33
use crate::hir::def_id::{CrateNum, DefId};
44
use crate::ty::TyCtxt;
@@ -53,7 +53,7 @@ pub(crate) trait QueryDescription<'tcx>: QueryAccessors<'tcx> {
5353
}
5454

5555
fn try_load_from_disk(_: TyCtxt<'_, 'tcx, 'tcx>,
56-
_: SerializedDepNodeIndex)
56+
_: DepNodeIndex)
5757
-> Option<Self::Value> {
5858
bug!("QueryDescription::load_from_disk() called for an unsupported query.")
5959
}
@@ -86,7 +86,7 @@ macro_rules! impl_disk_cacheable_query(
8686

8787
#[inline]
8888
fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
89-
id: SerializedDepNodeIndex)
89+
id: DepNodeIndex)
9090
-> Option<Self::Value> {
9191
tcx.queries.on_disk_cache.try_load_query_result(tcx, id)
9292
}

0 commit comments

Comments
 (0)