]> git.lizzy.rs Git - rust.git/commitdiff
Make DepGraph::previous_work_products immutable
authorWesley Wiser <wwiser@gmail.com>
Tue, 8 May 2018 02:30:44 +0000 (22:30 -0400)
committerWesley Wiser <wwiser@gmail.com>
Tue, 8 May 2018 03:17:16 +0000 (23:17 -0400)
Fixes #50501

src/librustc/dep_graph/graph.rs
src/librustc_driver/driver.rs
src/librustc_incremental/persist/load.rs

index 22ab1b15c8b8ed225c7a4016a96f335bf80c2dab..61a7404b08526545885cf054442e697c645bd9b4 100644 (file)
@@ -77,7 +77,7 @@ struct DepGraphData {
     /// 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
     /// this map. We can later look for and extract that data.
-    previous_work_products: RwLock<FxHashMap<WorkProductId, WorkProduct>>,
+    previous_work_products: FxHashMap<WorkProductId, WorkProduct>,
 
     /// Work-products that we generate in this run.
     work_products: RwLock<FxHashMap<WorkProductId, WorkProduct>>,
@@ -90,7 +90,8 @@ struct DepGraphData {
 
 impl DepGraph {
 
-    pub fn new(prev_graph: PreviousDepGraph) -> DepGraph {
+    pub fn new(prev_graph: PreviousDepGraph,
+               prev_work_products: FxHashMap<WorkProductId, WorkProduct>) -> DepGraph {
         // Pre-allocate the fingerprints array. We over-allocate a little so
         // that we hopefully don't have to re-allocate during this compilation
         // session.
@@ -100,7 +101,7 @@ pub fn new(prev_graph: PreviousDepGraph) -> DepGraph {
                                                  (prev_graph_node_count * 115) / 100);
         DepGraph {
             data: Some(Lrc::new(DepGraphData {
-                previous_work_products: RwLock::new(FxHashMap()),
+                previous_work_products: prev_work_products,
                 work_products: RwLock::new(FxHashMap()),
                 dep_node_debug: Lock::new(FxHashMap()),
                 current: Lock::new(CurrentDepGraph::new()),
@@ -460,19 +461,6 @@ pub fn prev_dep_node_index_of(&self, dep_node: &DepNode) -> SerializedDepNodeInd
         self.data.as_ref().unwrap().previous.node_to_index(dep_node)
     }
 
-    /// 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).
-    pub fn insert_previous_work_product(&self, v: &WorkProductId, data: WorkProduct) {
-        debug!("insert_previous_work_product({:?}, {:?})", v, data);
-        self.data
-            .as_ref()
-            .unwrap()
-            .previous_work_products
-            .borrow_mut()
-            .insert(v.clone(), data);
-    }
-
     /// Indicates that we created the given work-product in this run
     /// for `v`. This record will be preserved and loaded in the next
     /// run.
@@ -492,7 +480,7 @@ pub fn previous_work_product(&self, v: &WorkProductId) -> Option<WorkProduct> {
         self.data
             .as_ref()
             .and_then(|data| {
-                data.previous_work_products.borrow().get(v).cloned()
+                data.previous_work_products.get(v).cloned()
             })
     }
 
@@ -504,8 +492,8 @@ pub fn work_products(&self) -> ReadGuard<FxHashMap<WorkProductId, WorkProduct>>
 
     /// Access the map of work-products created during the cached run. Only
     /// used during saving of the dep-graph.
-    pub fn previous_work_products(&self) -> ReadGuard<FxHashMap<WorkProductId, WorkProduct>> {
-        self.data.as_ref().unwrap().previous_work_products.borrow()
+    pub fn previous_work_products(&self) -> &FxHashMap<WorkProductId, WorkProduct> {
+        &self.data.as_ref().unwrap().previous_work_products
     }
 
     #[inline(always)]
index 2fb811eba1e9a197eb6ec0cae4edb099b0a74723..1e74039503d51c5760498d1fd3f8de3f75e7b5d5 100644 (file)
@@ -980,15 +980,16 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(
     let dep_graph = match future_dep_graph {
         None => DepGraph::new_disabled(),
         Some(future) => {
-            let prev_graph = time(sess, "blocked while dep-graph loading finishes", || {
-                future
-                    .open()
-                    .unwrap_or_else(|e| rustc_incremental::LoadResult::Error {
-                        message: format!("could not decode incremental cache: {:?}", e),
-                    })
-                    .open(sess)
-            });
-            DepGraph::new(prev_graph)
+            let (prev_graph, prev_work_products) =
+                time(sess, "blocked while dep-graph loading finishes", || {
+                    future
+                        .open()
+                        .unwrap_or_else(|e| rustc_incremental::LoadResult::Error {
+                            message: format!("could not decode incremental cache: {:?}", e),
+                        })
+                        .open(sess)
+                });
+            DepGraph::new(prev_graph, prev_work_products)
         }
     };
     let hir_forest = time(sess, "lowering ast -> hir", || {
index 44d6e532f79bb4aa67b52c4446ac18dc665d4aef..01186483a6839619c3c72f51b13c2c7925216eef 100644 (file)
@@ -10,7 +10,8 @@
 
 //! Code to save/load the dep-graph from files.
 
-use rustc::dep_graph::{PreviousDepGraph, SerializedDepGraph};
+use rustc_data_structures::fx::FxHashMap;
+use rustc::dep_graph::{PreviousDepGraph, SerializedDepGraph, WorkProduct, WorkProductId};
 use rustc::session::Session;
 use rustc::ty::TyCtxt;
 use rustc::ty::maps::OnDiskCache;
@@ -32,65 +33,22 @@ pub fn dep_graph_tcx_init<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
 
     tcx.allocate_metadata_dep_nodes();
     tcx.precompute_in_scope_traits_hashes();
-
-    if tcx.sess.incr_comp_session_dir_opt().is_none() {
-        // If we are only building with -Zquery-dep-graph but without an actual
-        // incr. comp. session directory, we exit here. Otherwise we'd fail
-        // when trying to load work products.
-        return
-    }
-
-    let work_products_path = work_products_path(tcx.sess);
-    let load_result = load_data(tcx.sess.opts.debugging_opts.incremental_info, &work_products_path);
-
-    if let LoadResult::Ok { data: (work_products_data, start_pos) } = load_result {
-        // Decode the list of work_products
-        let mut work_product_decoder = Decoder::new(&work_products_data[..], start_pos);
-        let work_products: Vec<SerializedWorkProduct> =
-            RustcDecodable::decode(&mut work_product_decoder).unwrap_or_else(|e| {
-                let msg = format!("Error decoding `work-products` from incremental \
-                                   compilation session directory: {}", e);
-                tcx.sess.fatal(&msg[..])
-            });
-
-        for swp in work_products {
-            let mut all_files_exist = true;
-            for &(_, ref file_name) in swp.work_product.saved_files.iter() {
-                let path = in_incr_comp_dir_sess(tcx.sess, file_name);
-                if !path.exists() {
-                    all_files_exist = false;
-
-                    if tcx.sess.opts.debugging_opts.incremental_info {
-                        eprintln!("incremental: could not find file for work \
-                                   product: {}", path.display());
-                    }
-                }
-            }
-
-            if all_files_exist {
-                debug!("reconcile_work_products: all files for {:?} exist", swp);
-                tcx.dep_graph.insert_previous_work_product(&swp.id, swp.work_product);
-            } else {
-                debug!("reconcile_work_products: some file for {:?} does not exist", swp);
-                delete_dirty_work_product(tcx, swp);
-            }
-        }
-    }
 }
 
+type WorkProductMap = FxHashMap<WorkProductId, WorkProduct>;
+
 pub enum LoadResult<T> {
     Ok { data: T },
     DataOutOfDate,
     Error { message: String },
 }
 
-
-impl LoadResult<PreviousDepGraph> {
-    pub fn open(self, sess: &Session) -> PreviousDepGraph {
+impl LoadResult<(PreviousDepGraph, WorkProductMap)> {
+    pub fn open(self, sess: &Session) -> (PreviousDepGraph, WorkProductMap) {
         match self {
             LoadResult::Error { message } => {
                 sess.warn(&message);
-                PreviousDepGraph::new(SerializedDepGraph::new())
+                (PreviousDepGraph::new(SerializedDepGraph::new()), FxHashMap())
             },
             LoadResult::DataOutOfDate => {
                 if let Err(err) = delete_all_session_dir_contents(sess) {
@@ -98,7 +56,7 @@ pub fn open(self, sess: &Session) -> PreviousDepGraph {
                                       incremental compilation session directory contents `{}`: {}.",
                                       dep_graph_path(sess).display(), err));
                 }
-                PreviousDepGraph::new(SerializedDepGraph::new())
+                (PreviousDepGraph::new(SerializedDepGraph::new()), FxHashMap())
             }
             LoadResult::Ok { data } => data
         }
@@ -125,10 +83,10 @@ fn load_data(report_incremental_info: bool, path: &Path) -> LoadResult<(Vec<u8>,
     }
 }
 
-fn delete_dirty_work_product(tcx: TyCtxt,
+fn delete_dirty_work_product(sess: &Session,
                              swp: SerializedWorkProduct) {
     debug!("delete_dirty_work_product({:?})", swp);
-    work_product::delete_workproduct_files(tcx.sess, &swp.work_product);
+    work_product::delete_workproduct_files(sess, &swp.work_product);
 }
 
 /// Either a result that has already be computed or a
@@ -149,7 +107,7 @@ pub fn open(self) -> std::thread::Result<T> {
 
 /// Launch a thread and load the dependency graph in the background.
 pub fn load_dep_graph(sess: &Session) ->
-    MaybeAsync<LoadResult<PreviousDepGraph>>
+    MaybeAsync<LoadResult<(PreviousDepGraph, WorkProductMap)>>
 {
     // Since `sess` isn't `Sync`, we perform all accesses to `sess`
     // before we fire the background thread.
@@ -159,7 +117,7 @@ pub fn load_dep_graph(sess: &Session) ->
     if sess.opts.incremental.is_none() {
         // No incremental compilation.
         return MaybeAsync::Sync(LoadResult::Ok {
-            data: PreviousDepGraph::new(SerializedDepGraph::new())
+            data: (PreviousDepGraph::new(SerializedDepGraph::new()), FxHashMap())
         });
     }
 
@@ -169,6 +127,50 @@ pub fn load_dep_graph(sess: &Session) ->
     let report_incremental_info = sess.opts.debugging_opts.incremental_info;
     let expected_hash = sess.opts.dep_tracking_hash();
 
+    let mut prev_work_products = FxHashMap();
+
+    // If we are only building with -Zquery-dep-graph but without an actual
+    // incr. comp. session directory, we exit here. Otherwise we'd fail
+    // when trying to load work products.
+    if sess.incr_comp_session_dir_opt().is_some() {
+        let work_products_path = work_products_path(sess);
+        let load_result = load_data(report_incremental_info, &work_products_path);
+
+        if let LoadResult::Ok { data: (work_products_data, start_pos) } = load_result {
+            // Decode the list of work_products
+            let mut work_product_decoder = Decoder::new(&work_products_data[..], start_pos);
+            let work_products: Vec<SerializedWorkProduct> =
+                RustcDecodable::decode(&mut work_product_decoder).unwrap_or_else(|e| {
+                    let msg = format!("Error decoding `work-products` from incremental \
+                                    compilation session directory: {}", e);
+                    sess.fatal(&msg[..])
+                });
+
+            for swp in work_products {
+                let mut all_files_exist = true;
+                for &(_, ref file_name) in swp.work_product.saved_files.iter() {
+                    let path = in_incr_comp_dir_sess(sess, file_name);
+                    if !path.exists() {
+                        all_files_exist = false;
+
+                        if sess.opts.debugging_opts.incremental_info {
+                            eprintln!("incremental: could not find file for work \
+                                    product: {}", path.display());
+                        }
+                    }
+                }
+
+                if all_files_exist {
+                    debug!("reconcile_work_products: all files for {:?} exist", swp);
+                    prev_work_products.insert(swp.id, swp.work_product);
+                } else {
+                    debug!("reconcile_work_products: some file for {:?} does not exist", swp);
+                    delete_dirty_work_product(sess, swp);
+                }
+            }
+        }
+    }
+
     MaybeAsync::Async(std::thread::spawn(move || {
         time_ext(time_passes, None, "background load prev dep-graph", move || {
             match load_data(report_incremental_info, &path) {
@@ -195,7 +197,7 @@ pub fn load_dep_graph(sess: &Session) ->
                     let dep_graph = SerializedDepGraph::decode(&mut decoder)
                         .expect("Error reading cached dep-graph");
 
-                    LoadResult::Ok { data: PreviousDepGraph::new(dep_graph) }
+                    LoadResult::Ok { data: (PreviousDepGraph::new(dep_graph), prev_work_products) }
                 }
             }
         })