Skip to content

Commit 9743f63

Browse files
committed
Serialize dep nodes in the background
1 parent 1fb3ff1 commit 9743f63

File tree

15 files changed

+305
-162
lines changed

15 files changed

+305
-162
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>
@@ -91,15 +92,18 @@ where
9192

9293
impl DepGraph {
9394

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

98102
DepGraph {
99103
data: Some(Lrc::new(DepGraphData {
100104
previous_work_products: prev_work_products,
101105
dep_node_debug: Default::default(),
102-
current: Lock::new(CurrentDepGraph::new(prev_graph_node_count)),
106+
current: Lock::new(CurrentDepGraph::new(prev_graph_node_count, file)),
103107
emitted_diagnostics: Default::default(),
104108
emitted_diagnostics_cond_var: Condvar::new(),
105109
previous: prev_graph,
@@ -122,6 +126,8 @@ impl DepGraph {
122126
}
123127

124128
pub fn query(&self) -> DepGraphQuery {
129+
// FIXME
130+
panic!()/*
125131
let current_dep_graph = self.data.as_ref().unwrap().current.borrow();
126132
let nodes: Vec<_> = current_dep_graph.data.iter().map(|n| n.node).collect();
127133
let mut edges = Vec::new();
@@ -133,7 +139,7 @@ impl DepGraph {
133139
}
134140
}
135141
136-
DepGraphQuery::new(&nodes[..], &edges[..])
142+
DepGraphQuery::new(&nodes[..], &edges[..])*/
137143
}
138144

139145
pub fn assert_ignored(&self)
@@ -436,9 +442,10 @@ impl DepGraph {
436442
}
437443

438444
#[inline]
439-
pub fn fingerprint_of(&self, dep_node_index: DepNodeIndex) -> Fingerprint {
445+
pub fn fingerprint_of(&self, _dep_node_index: DepNodeIndex) -> Fingerprint {
446+
panic!()/*
440447
let current = self.data.as_ref().expect("dep graph enabled").current.borrow_mut();
441-
current.data[dep_node_index].fingerprint
448+
current.data[dep_node_index].fingerprint*/
442449
}
443450

444451
pub fn prev_fingerprint_of(&self, dep_node: &DepNode) -> Option<Fingerprint> {
@@ -501,41 +508,9 @@ impl DepGraph {
501508
}
502509
}
503510

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

541516
pub fn node_color(&self, dep_node: &DepNode) -> Option<DepNodeColor> {
@@ -871,23 +846,20 @@ impl DepGraph {
871846
}
872847
}
873848

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

879852
self.data
880853
.as_ref()
881854
.unwrap()
882855
.loaded_from_cache
883856
.borrow_mut()
884-
.insert(dep_node_index, state);
857+
.insert(dep_node, state);
885858
}
886859

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

@@ -936,15 +908,15 @@ pub enum WorkProductFileKind {
936908
BytecodeCompressed,
937909
}
938910

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

946918
pub(super) struct CurrentDepGraph {
947-
data: IndexVec<DepNodeIndex, DepNodeData>,
919+
nodes: usize,
948920
node_to_node_index: FxHashMap<DepNode, DepNodeIndex>,
949921
#[allow(dead_code)]
950922
forbidden_edge: Option<EdgeFilter>,
@@ -964,10 +936,13 @@ pub(super) struct CurrentDepGraph {
964936

965937
total_read_count: u64,
966938
total_duplicate_read_count: u64,
939+
940+
/// Produces the serialized dep graph for the next session,
941+
serializer: Serializer,
967942
}
968943

969944
impl CurrentDepGraph {
970-
fn new(prev_graph_node_count: usize) -> CurrentDepGraph {
945+
fn new(prev_graph_node_count: usize, file: File) -> CurrentDepGraph {
971946
use std::time::{SystemTime, UNIX_EPOCH};
972947

973948
let duration = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
@@ -997,7 +972,7 @@ impl CurrentDepGraph {
997972
let new_node_count_estimate = (prev_graph_node_count * 102) / 100 + 200;
998973

999974
CurrentDepGraph {
1000-
data: IndexVec::with_capacity(new_node_count_estimate),
975+
nodes: 0,
1001976
node_to_node_index: FxHashMap::with_capacity_and_hasher(
1002977
new_node_count_estimate,
1003978
Default::default(),
@@ -1006,6 +981,7 @@ impl CurrentDepGraph {
1006981
forbidden_edge,
1007982
total_read_count: 0,
1008983
total_duplicate_read_count: 0,
984+
serializer: Serializer::new(file),
1009985
}
1010986
}
1011987

@@ -1058,13 +1034,14 @@ impl CurrentDepGraph {
10581034
edges: SmallVec<[DepNodeIndex; 8]>,
10591035
fingerprint: Fingerprint
10601036
) -> (DepNodeIndex, bool) {
1061-
debug_assert_eq!(self.node_to_node_index.len(), self.data.len());
1037+
debug_assert_eq!(self.node_to_node_index.len(), self.nodes);
10621038

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

1091-
#[cfg(debug_assertions)]
1068+
/*#[cfg(debug_assertions)]
10921069
{
10931070
if let Some(target) = task_deps.node {
10941071
let graph = self.current.lock();
@@ -1101,7 +1078,7 @@ impl DepGraphData {
11011078
}
11021079
}
11031080
}
1104-
}
1081+
}*/
11051082
} else if cfg!(debug_assertions) {
11061083
self.current.lock().total_duplicate_read_count += 1;
11071084
}
@@ -1112,6 +1089,7 @@ impl DepGraphData {
11121089

11131090
pub struct TaskDeps {
11141091
#[cfg(debug_assertions)]
1092+
#[allow(dead_code)]
11151093
node: Option<DepNode>,
11161094
reads: SmallVec<[DepNodeIndex; 8]>,
11171095
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)