about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Woerister <michaelwoerister@posteo>2017-09-25 12:25:41 +0200
committerMichael Woerister <michaelwoerister@posteo>2017-10-02 15:36:47 +0200
commita948be81cda8ed8145f4e1d7cf6b0a59efb8e240 (patch)
tree8932dbb9b67105d18ac9ecbb7bec54979998a687
parent9ae6ed78acf9dc865e2300a7db556389eed9692d (diff)
downloadrust-a948be81cda8ed8145f4e1d7cf6b0a59efb8e240.tar.gz
rust-a948be81cda8ed8145f4e1d7cf6b0a59efb8e240.zip
incr.comp.: Determine red/green state of every new node.
-rw-r--r--src/librustc/dep_graph/graph.rs57
-rw-r--r--src/librustc/dep_graph/prev.rs7
-rw-r--r--src/librustc_incremental/persist/dirty_clean.rs4
3 files changed, 56 insertions, 12 deletions
diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs
index d9770db9d69..f76f9279e5b 100644
--- a/src/librustc/dep_graph/graph.rs
+++ b/src/librustc/dep_graph/graph.rs
@@ -59,6 +59,13 @@ impl DepNodeIndex {
     };
 }
 
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+pub enum DepNodeColor {
+    Red,
+    Green,
+    Gray
+}
+
 struct DepGraphData {
     /// The old, initial encoding of the dependency graph. This will soon go
     /// away.
@@ -74,6 +81,8 @@ struct DepGraphData {
     /// nodes and edges as well as all fingerprints of nodes that have them.
     previous: PreviousDepGraph,
 
+    colors: RefCell<FxHashMap<DepNode, DepNodeColor>>,
+
     /// When we load, there may be `.o` files, cached mir, or other such
     /// things available to us. If we find that they are not dirty, we
     /// load the path to the file storing those work-products here into
@@ -97,6 +106,7 @@ impl DepGraph {
                 dep_node_debug: RefCell::new(FxHashMap()),
                 current: RefCell::new(CurrentDepGraph::new()),
                 previous: prev_graph,
+                colors: RefCell::new(FxHashMap()),
             })),
             fingerprints: Rc::new(RefCell::new(FxHashMap())),
         }
@@ -192,11 +202,23 @@ impl DepGraph {
             let mut stable_hasher = StableHasher::new();
             result.hash_stable(&mut hcx, &mut stable_hasher);
 
+            let current_fingerprint = stable_hasher.finish();
+
             assert!(self.fingerprints
                         .borrow_mut()
-                        .insert(key, stable_hasher.finish())
+                        .insert(key, current_fingerprint)
                         .is_none());
 
+            let prev_fingerprint = data.previous.fingerprint_of(&key);
+
+            let color = if Some(current_fingerprint) == prev_fingerprint {
+                DepNodeColor::Green
+            } else {
+                DepNodeColor::Red
+            };
+
+            assert!(data.colors.borrow_mut().insert(key, color).is_none());
+
             (result, DepNodeIndex {
                 legacy: dep_node_index_legacy,
                 new: dep_node_index_new,
@@ -228,7 +250,16 @@ impl DepGraph {
             data.current.borrow_mut().push_anon_task();
             let result = op();
             let dep_node_index_legacy = data.edges.borrow_mut().pop_anon_task(dep_kind);
-            let dep_node_index_new = data.current.borrow_mut().pop_anon_task(dep_kind);
+            let (new_dep_node, dep_node_index_new) = data.current
+                                                         .borrow_mut()
+                                                         .pop_anon_task(dep_kind);
+            if let Some(new_dep_node) = new_dep_node {
+                assert!(data.colors
+                            .borrow_mut()
+                            .insert(new_dep_node, DepNodeColor::Red)
+                            .is_none());
+            }
+
             (result, DepNodeIndex {
                 legacy: dep_node_index_legacy,
                 new: dep_node_index_new,
@@ -275,10 +306,22 @@ impl DepGraph {
         self.fingerprints.borrow()[dep_node]
     }
 
-    pub fn prev_fingerprint_of(&self, dep_node: &DepNode) -> Fingerprint {
+    pub fn prev_fingerprint_of(&self, dep_node: &DepNode) -> Option<Fingerprint> {
         self.data.as_ref().unwrap().previous.fingerprint_of(dep_node)
     }
 
+    pub fn node_color(&self, dep_node: &DepNode) -> DepNodeColor {
+        match self.data.as_ref().unwrap().colors.borrow().get(dep_node) {
+            Some(&color) => {
+                debug_assert!(color != DepNodeColor::Gray);
+                color
+            }
+            None => {
+                DepNodeColor::Gray
+            }
+        }
+    }
+
     /// Indicates that a previous work product exists for `v`. This is
     /// invoked during initial start-up based on what nodes are clean
     /// (and what files exist in the incr. directory).
@@ -485,7 +528,7 @@ impl CurrentDepGraph {
         });
     }
 
-    fn pop_anon_task(&mut self, kind: DepKind) -> DepNodeIndexNew {
+    fn pop_anon_task(&mut self, kind: DepKind) -> (Option<DepNode>, DepNodeIndexNew) {
         let popped_node = self.task_stack.pop().unwrap();
 
         if let OpenTask::Anon {
@@ -514,10 +557,10 @@ impl CurrentDepGraph {
             };
 
             if let Some(&index) = self.node_to_node_index.get(&target_dep_node) {
-                return index;
+                (None, index)
+            } else {
+                (Some(target_dep_node), self.alloc_node(target_dep_node, reads))
             }
-
-            self.alloc_node(target_dep_node, reads)
         } else {
             bug!("pop_anon_task() - Expected anonymous task to be popped")
         }
diff --git a/src/librustc/dep_graph/prev.rs b/src/librustc/dep_graph/prev.rs
index 882ca0414cc..0236f9c2292 100644
--- a/src/librustc/dep_graph/prev.rs
+++ b/src/librustc/dep_graph/prev.rs
@@ -39,8 +39,9 @@ impl PreviousDepGraph {
             .for_each(|&index| f(&self.data.nodes[index]));
     }
 
-    pub fn fingerprint_of(&self, dep_node: &DepNode) -> Fingerprint {
-        let node_index = self.index[dep_node];
-        self.data.nodes[node_index].1
+    pub fn fingerprint_of(&self, dep_node: &DepNode) -> Option<Fingerprint> {
+        self.index
+            .get(dep_node)
+            .map(|&node_index| self.data.nodes[node_index].1)
     }
 }
diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs
index a6d39a91863..33a9cb58c51 100644
--- a/src/librustc_incremental/persist/dirty_clean.rs
+++ b/src/librustc_incremental/persist/dirty_clean.rs
@@ -122,7 +122,7 @@ impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> {
         let current_fingerprint = self.tcx.dep_graph.fingerprint_of(&dep_node);
         let prev_fingerprint = self.tcx.dep_graph.prev_fingerprint_of(&dep_node);
 
-        if current_fingerprint == prev_fingerprint {
+        if Some(current_fingerprint) == prev_fingerprint {
             let dep_node_str = self.dep_node_str(&dep_node);
             self.tcx.sess.span_err(
                 item_span,
@@ -136,7 +136,7 @@ impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> {
         let current_fingerprint = self.tcx.dep_graph.fingerprint_of(&dep_node);
         let prev_fingerprint = self.tcx.dep_graph.prev_fingerprint_of(&dep_node);
 
-        if current_fingerprint != prev_fingerprint {
+        if Some(current_fingerprint) != prev_fingerprint {
             let dep_node_str = self.dep_node_str(&dep_node);
             self.tcx.sess.span_err(
                 item_span,