Skip to content

Commit 5604fe9

Browse files
committed
Serialize dep nodes in the background
1 parent ed3072d commit 5604fe9

File tree

15 files changed

+305
-161
lines changed

15 files changed

+305
-161
lines changed

src/librustc/dep_graph/graph.rs

Lines changed: 42 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use rustc_data_structures::indexed_vec::{Idx, IndexVec};
55
use smallvec::SmallVec;
66
use rustc_data_structures::sync::{Lrc, Lock, AtomicU32, Ordering};
77
use std::env;
8+
use std::fs::File;
89
use std::hash::Hash;
910
use std::collections::hash_map::Entry;
1011
use crate::ty::{self, TyCtxt};
@@ -17,7 +18,7 @@ use super::debug::EdgeFilter;
1718
use super::dep_node::{DepNode, DepKind, WorkProductId};
1819
use super::query::DepGraphQuery;
1920
use super::safe::DepGraphSafe;
20-
use super::serialized::{SerializedDepGraph, SerializedDepNodeIndex};
21+
use super::serialized::{SerializedDepNodeIndex, Serializer};
2122
use super::prev::PreviousDepGraph;
2223

2324
#[derive(Clone)]
@@ -30,7 +31,7 @@ newtype_index! {
3031
}
3132

3233
impl DepNodeIndex {
33-
const INVALID: DepNodeIndex = DepNodeIndex::MAX;
34+
pub(super) const INVALID: DepNodeIndex = DepNodeIndex::MAX;
3435
}
3536

3637
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
@@ -76,7 +77,7 @@ struct DepGraphData {
7677
dep_node_debug: Lock<FxHashMap<DepNode, String>>,
7778

7879
// Used for testing, only populated when -Zquery-dep-graph is specified.
79-
loaded_from_cache: Lock<FxHashMap<DepNodeIndex, bool>>,
80+
loaded_from_cache: Lock<FxHashMap<DepNode, bool>>,
8081
}
8182

8283
pub fn hash_result<R>(hcx: &mut StableHashingContext<'_>, result: &R) -> Option<Fingerprint>
@@ -90,15 +91,18 @@ where
9091
}
9192

9293
impl DepGraph {
93-
pub fn new(prev_graph: PreviousDepGraph,
94-
prev_work_products: FxHashMap<WorkProductId, WorkProduct>) -> DepGraph {
94+
pub fn new(
95+
prev_graph: PreviousDepGraph,
96+
prev_work_products: FxHashMap<WorkProductId, WorkProduct>,
97+
file: File,
98+
) -> DepGraph {
9599
let prev_graph_node_count = prev_graph.node_count();
96100

97101
DepGraph {
98102
data: Some(Lrc::new(DepGraphData {
99103
previous_work_products: prev_work_products,
100104
dep_node_debug: Default::default(),
101-
current: Lock::new(CurrentDepGraph::new(prev_graph_node_count)),
105+
current: Lock::new(CurrentDepGraph::new(prev_graph_node_count, file)),
102106
emitted_diagnostics: Default::default(),
103107
emitted_diagnostics_cond_var: Condvar::new(),
104108
previous: prev_graph,
@@ -121,6 +125,8 @@ impl DepGraph {
121125
}
122126

123127
pub fn query(&self) -> DepGraphQuery {
128+
// FIXME
129+
panic!()/*
124130
let current_dep_graph = self.data.as_ref().unwrap().current.borrow();
125131
let nodes: Vec<_> = current_dep_graph.data.iter().map(|n| n.node).collect();
126132
let mut edges = Vec::new();
@@ -132,7 +138,7 @@ impl DepGraph {
132138
}
133139
}
134140
135-
DepGraphQuery::new(&nodes[..], &edges[..])
141+
DepGraphQuery::new(&nodes[..], &edges[..])*/
136142
}
137143

138144
pub fn assert_ignored(&self)
@@ -435,9 +441,10 @@ impl DepGraph {
435441
}
436442

437443
#[inline]
438-
pub fn fingerprint_of(&self, dep_node_index: DepNodeIndex) -> Fingerprint {
444+
pub fn fingerprint_of(&self, _dep_node_index: DepNodeIndex) -> Fingerprint {
445+
panic!()/*
439446
let current = self.data.as_ref().expect("dep graph enabled").current.borrow_mut();
440-
current.data[dep_node_index].fingerprint
447+
current.data[dep_node_index].fingerprint*/
441448
}
442449

443450
pub fn prev_fingerprint_of(&self, dep_node: &DepNode) -> Option<Fingerprint> {
@@ -500,41 +507,9 @@ impl DepGraph {
500507
}
501508
}
502509

503-
pub fn serialize(&self) -> SerializedDepGraph {
504-
let current_dep_graph = self.data.as_ref().unwrap().current.borrow();
505-
506-
let fingerprints: IndexVec<SerializedDepNodeIndex, _> =
507-
current_dep_graph.data.iter().map(|d| d.fingerprint).collect();
508-
let nodes: IndexVec<SerializedDepNodeIndex, _> =
509-
current_dep_graph.data.iter().map(|d| d.node).collect();
510-
511-
let total_edge_count: usize = current_dep_graph.data.iter()
512-
.map(|d| d.edges.len())
513-
.sum();
514-
515-
let mut edge_list_indices = IndexVec::with_capacity(nodes.len());
516-
let mut edge_list_data = Vec::with_capacity(total_edge_count);
517-
518-
for (current_dep_node_index, edges) in current_dep_graph.data.iter_enumerated()
519-
.map(|(i, d)| (i, &d.edges)) {
520-
let start = edge_list_data.len() as u32;
521-
// This should really just be a memcpy :/
522-
edge_list_data.extend(edges.iter().map(|i| SerializedDepNodeIndex::new(i.index())));
523-
let end = edge_list_data.len() as u32;
524-
525-
debug_assert_eq!(current_dep_node_index.index(), edge_list_indices.len());
526-
edge_list_indices.push((start, end));
527-
}
528-
529-
debug_assert!(edge_list_data.len() <= ::std::u32::MAX as usize);
530-
debug_assert_eq!(edge_list_data.len(), total_edge_count);
531-
532-
SerializedDepGraph {
533-
nodes,
534-
fingerprints,
535-
edge_list_indices,
536-
edge_list_data,
537-
}
510+
pub fn serialize(&self) {
511+
// FIXME: Can this deadlock?
512+
self.data.as_ref().unwrap().current.lock().serializer.complete()
538513
}
539514

540515
pub fn node_color(&self, dep_node: &DepNode) -> Option<DepNodeColor> {
@@ -870,23 +845,20 @@ impl DepGraph {
870845
}
871846
}
872847

873-
pub fn mark_loaded_from_cache(&self, dep_node_index: DepNodeIndex, state: bool) {
874-
debug!("mark_loaded_from_cache({:?}, {})",
875-
self.data.as_ref().unwrap().current.borrow().data[dep_node_index].node,
876-
state);
848+
pub fn mark_loaded_from_cache(&self, dep_node: DepNode, state: bool) {
849+
debug!("mark_loaded_from_cache({:?}, {})", dep_node, state);
877850

878851
self.data
879852
.as_ref()
880853
.unwrap()
881854
.loaded_from_cache
882855
.borrow_mut()
883-
.insert(dep_node_index, state);
856+
.insert(dep_node, state);
884857
}
885858

886859
pub fn was_loaded_from_cache(&self, dep_node: &DepNode) -> Option<bool> {
887860
let data = self.data.as_ref().unwrap();
888-
let dep_node_index = data.current.borrow().node_to_node_index[dep_node];
889-
data.loaded_from_cache.borrow().get(&dep_node_index).cloned()
861+
data.loaded_from_cache.borrow().get(&dep_node).cloned()
890862
}
891863
}
892864

@@ -935,15 +907,15 @@ pub enum WorkProductFileKind {
935907
BytecodeCompressed,
936908
}
937909

938-
#[derive(Clone)]
939-
struct DepNodeData {
940-
node: DepNode,
941-
edges: SmallVec<[DepNodeIndex; 8]>,
942-
fingerprint: Fingerprint,
910+
#[derive(Clone, Debug)]
911+
pub(super) struct DepNodeData {
912+
pub(super) node: DepNode,
913+
pub(super) edges: SmallVec<[DepNodeIndex; 8]>,
914+
pub(super) fingerprint: Fingerprint,
943915
}
944916

945917
pub(super) struct CurrentDepGraph {
946-
data: IndexVec<DepNodeIndex, DepNodeData>,
918+
nodes: usize,
947919
node_to_node_index: FxHashMap<DepNode, DepNodeIndex>,
948920
#[allow(dead_code)]
949921
forbidden_edge: Option<EdgeFilter>,
@@ -963,10 +935,13 @@ pub(super) struct CurrentDepGraph {
963935

964936
total_read_count: u64,
965937
total_duplicate_read_count: u64,
938+
939+
/// Produces the serialized dep graph for the next session,
940+
serializer: Serializer,
966941
}
967942

968943
impl CurrentDepGraph {
969-
fn new(prev_graph_node_count: usize) -> CurrentDepGraph {
944+
fn new(prev_graph_node_count: usize, file: File) -> CurrentDepGraph {
970945
use std::time::{SystemTime, UNIX_EPOCH};
971946

972947
let duration = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
@@ -996,7 +971,7 @@ impl CurrentDepGraph {
996971
let new_node_count_estimate = (prev_graph_node_count * 102) / 100 + 200;
997972

998973
CurrentDepGraph {
999-
data: IndexVec::with_capacity(new_node_count_estimate),
974+
nodes: 0,
1000975
node_to_node_index: FxHashMap::with_capacity_and_hasher(
1001976
new_node_count_estimate,
1002977
Default::default(),
@@ -1005,6 +980,7 @@ impl CurrentDepGraph {
1005980
forbidden_edge,
1006981
total_read_count: 0,
1007982
total_duplicate_read_count: 0,
983+
serializer: Serializer::new(file),
1008984
}
1009985
}
1010986

@@ -1057,13 +1033,14 @@ impl CurrentDepGraph {
10571033
edges: SmallVec<[DepNodeIndex; 8]>,
10581034
fingerprint: Fingerprint
10591035
) -> (DepNodeIndex, bool) {
1060-
debug_assert_eq!(self.node_to_node_index.len(), self.data.len());
1036+
debug_assert_eq!(self.node_to_node_index.len(), self.nodes);
10611037

10621038
match self.node_to_node_index.entry(dep_node) {
10631039
Entry::Occupied(entry) => (*entry.get(), false),
10641040
Entry::Vacant(entry) => {
1065-
let dep_node_index = DepNodeIndex::new(self.data.len());
1066-
self.data.push(DepNodeData {
1041+
let dep_node_index = DepNodeIndex::new(self.nodes);
1042+
self.nodes += 1;
1043+
self.serializer.serialize(DepNodeData {
10671044
node: dep_node,
10681045
edges,
10691046
fingerprint
@@ -1087,7 +1064,7 @@ impl DepGraphData {
10871064
if task_deps.read_set.insert(source) {
10881065
task_deps.reads.push(source);
10891066

1090-
#[cfg(debug_assertions)]
1067+
/*#[cfg(debug_assertions)]
10911068
{
10921069
if let Some(target) = task_deps.node {
10931070
let graph = self.current.lock();
@@ -1100,7 +1077,7 @@ impl DepGraphData {
11001077
}
11011078
}
11021079
}
1103-
}
1080+
}*/
11041081
} else if cfg!(debug_assertions) {
11051082
self.current.lock().total_duplicate_read_count += 1;
11061083
}
@@ -1111,6 +1088,7 @@ impl DepGraphData {
11111088

11121089
pub struct TaskDeps {
11131090
#[cfg(debug_assertions)]
1091+
#[allow(dead_code)]
11141092
node: Option<DepNode>,
11151093
reads: SmallVec<[DepNodeIndex; 8]>,
11161094
read_set: FxHashSet<DepNodeIndex>,

src/librustc/dep_graph/prev.rs

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,78 @@
11
use crate::ich::Fingerprint;
22
use rustc_data_structures::fx::FxHashMap;
3+
use rustc_data_structures::indexed_vec::IndexVec;
34
use super::dep_node::DepNode;
45
use super::serialized::{SerializedDepGraph, SerializedDepNodeIndex};
56

67
#[derive(Debug, RustcEncodable, RustcDecodable, Default)]
78
pub struct PreviousDepGraph {
8-
data: SerializedDepGraph,
9+
/// Maps from dep nodes to their previous index, if any.
910
index: FxHashMap<DepNode, SerializedDepNodeIndex>,
11+
/// The set of all DepNodes in the graph
12+
nodes: IndexVec<SerializedDepNodeIndex, DepNode>,
13+
/// The set of all Fingerprints in the graph. Each Fingerprint corresponds to
14+
/// the DepNode at the same index in the nodes vector.
15+
fingerprints: IndexVec<SerializedDepNodeIndex, Fingerprint>,
16+
/// For each DepNode, stores the list of edges originating from that
17+
/// DepNode. Encoded as a [start, end) pair indexing into edge_list_data,
18+
/// which holds the actual DepNodeIndices of the target nodes.
19+
edge_list_indices: IndexVec<SerializedDepNodeIndex, (u32, u32)>,
20+
/// A flattened list of all edge targets in the graph. Edge sources are
21+
/// implicit in edge_list_indices.
22+
edge_list_data: Vec<SerializedDepNodeIndex>,
1023
}
1124

1225
impl PreviousDepGraph {
13-
pub fn new(data: SerializedDepGraph) -> PreviousDepGraph {
14-
let index: FxHashMap<_, _> = data.nodes
26+
pub fn new(graph: SerializedDepGraph) -> PreviousDepGraph {
27+
let index: FxHashMap<_, _> = graph.nodes
1528
.iter_enumerated()
16-
.map(|(idx, &dep_node)| (dep_node, idx))
29+
.map(|(idx, dep_node)| (dep_node.node, idx))
1730
.collect();
18-
PreviousDepGraph { data, index }
31+
32+
let fingerprints: IndexVec<SerializedDepNodeIndex, _> =
33+
graph.nodes.iter().map(|d| d.fingerprint).collect();
34+
let nodes: IndexVec<SerializedDepNodeIndex, _> =
35+
graph.nodes.iter().map(|d| d.node).collect();
36+
37+
let total_edge_count: usize = graph.nodes.iter().map(|d| d.deps.len()).sum();
38+
39+
let mut edge_list_indices = IndexVec::with_capacity(nodes.len());
40+
let mut edge_list_data = Vec::with_capacity(total_edge_count);
41+
42+
for (current_dep_node_index, edges) in graph.nodes.iter_enumerated()
43+
.map(|(i, d)| (i, &d.deps)) {
44+
let start = edge_list_data.len() as u32;
45+
edge_list_data.extend(edges.iter().cloned());
46+
let end = edge_list_data.len() as u32;
47+
48+
debug_assert_eq!(current_dep_node_index.index(), edge_list_indices.len());
49+
edge_list_indices.push((start, end));
50+
}
51+
52+
debug_assert!(edge_list_data.len() <= ::std::u32::MAX as usize);
53+
debug_assert_eq!(edge_list_data.len(), total_edge_count);
54+
55+
PreviousDepGraph {
56+
fingerprints,
57+
nodes,
58+
edge_list_indices,
59+
edge_list_data,
60+
index,
61+
}
1962
}
2063

2164
#[inline]
2265
pub fn edge_targets_from(
2366
&self,
2467
dep_node_index: SerializedDepNodeIndex
2568
) -> &[SerializedDepNodeIndex] {
26-
self.data.edge_targets_from(dep_node_index)
69+
let targets = self.edge_list_indices[dep_node_index];
70+
&self.edge_list_data[targets.0 as usize..targets.1 as usize]
2771
}
2872

2973
#[inline]
3074
pub fn index_to_node(&self, dep_node_index: SerializedDepNodeIndex) -> DepNode {
31-
self.data.nodes[dep_node_index]
75+
self.nodes[dep_node_index]
3276
}
3377

3478
#[inline]
@@ -45,14 +89,14 @@ impl PreviousDepGraph {
4589
pub fn fingerprint_of(&self, dep_node: &DepNode) -> Option<Fingerprint> {
4690
self.index
4791
.get(dep_node)
48-
.map(|&node_index| self.data.fingerprints[node_index])
92+
.map(|&node_index| self.fingerprints[node_index])
4993
}
5094

5195
#[inline]
5296
pub fn fingerprint_by_index(&self,
5397
dep_node_index: SerializedDepNodeIndex)
5498
-> Fingerprint {
55-
self.data.fingerprints[dep_node_index]
99+
self.fingerprints[dep_node_index]
56100
}
57101

58102
pub fn node_count(&self) -> usize {

0 commit comments

Comments
 (0)