about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2023-09-20 15:38:18 +0200
committerJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2023-09-24 00:30:43 +0200
commitba8d53dc8fd43fac0e539fee9c91fcdd307cc17e (patch)
tree817dd3a08a8731ec7fad4706efd932f5b4f14271
parent13e6f24b9adda67852fb86538541adaa68aff6e8 (diff)
downloadrust-ba8d53dc8fd43fac0e539fee9c91fcdd307cc17e.tar.gz
rust-ba8d53dc8fd43fac0e539fee9c91fcdd307cc17e.zip
Don't use a thread to load the dep graph
-rw-r--r--compiler/rustc_incremental/src/lib.rs2
-rw-r--r--compiler/rustc_incremental/src/persist/load.rs132
-rw-r--r--compiler/rustc_incremental/src/persist/mod.rs3
-rw-r--r--compiler/rustc_incremental/src/persist/save.rs2
-rw-r--r--compiler/rustc_interface/src/queries.rs47
5 files changed, 68 insertions, 118 deletions
diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs
index b9171fad55b..220ea194a6d 100644
--- a/compiler/rustc_incremental/src/lib.rs
+++ b/compiler/rustc_incremental/src/lib.rs
@@ -28,8 +28,8 @@ pub use persist::load_query_result_cache;
 pub use persist::prepare_session_directory;
 pub use persist::save_dep_graph;
 pub use persist::save_work_product_index;
+pub use persist::setup_dep_graph;
 pub use persist::LoadResult;
-pub use persist::{build_dep_graph, load_dep_graph, DepGraphFuture};
 
 use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
 use rustc_fluent_macro::fluent_messages;
diff --git a/compiler/rustc_incremental/src/persist/load.rs b/compiler/rustc_incremental/src/persist/load.rs
index 25e694fa1c1..2310d0b12ef 100644
--- a/compiler/rustc_incremental/src/persist/load.rs
+++ b/compiler/rustc_incremental/src/persist/load.rs
@@ -3,17 +3,19 @@
 use crate::errors;
 use rustc_data_structures::memmap::Mmap;
 use rustc_data_structures::unord::UnordMap;
-use rustc_middle::dep_graph::{DepsType, SerializedDepGraph, WorkProductMap};
+use rustc_middle::dep_graph::{DepGraph, DepsType, SerializedDepGraph, WorkProductMap};
 use rustc_middle::query::on_disk_cache::OnDiskCache;
 use rustc_serialize::opaque::MemDecoder;
 use rustc_serialize::Decodable;
 use rustc_session::config::IncrementalStateAssertion;
-use rustc_session::Session;
+use rustc_session::{Session, StableCrateId};
+use rustc_span::{ErrorGuaranteed, Symbol};
 use std::path::{Path, PathBuf};
 
 use super::data::*;
 use super::file_format;
 use super::fs::*;
+use super::save::build_dep_graph;
 use super::work_product;
 
 #[derive(Debug)]
@@ -72,21 +74,12 @@ impl<T: Default> LoadResult<T> {
 }
 
 fn load_data(path: &Path, sess: &Session) -> LoadResult<(Mmap, usize)> {
-    load_data_no_sess(
+    match file_format::read_file(
         path,
         sess.opts.unstable_opts.incremental_info,
         sess.is_nightly_build(),
         sess.cfg_version,
-    )
-}
-
-fn load_data_no_sess(
-    path: &Path,
-    report_incremental_info: bool,
-    is_nightly_build: bool,
-    cfg_version: &'static str,
-) -> LoadResult<(Mmap, usize)> {
-    match file_format::read_file(path, report_incremental_info, is_nightly_build, cfg_version) {
+    ) {
         Ok(Some(data_and_pos)) => LoadResult::Ok { data: data_and_pos },
         Ok(None) => {
             // The file either didn't exist or was produced by an incompatible
@@ -102,39 +95,12 @@ fn delete_dirty_work_product(sess: &Session, swp: SerializedWorkProduct) {
     work_product::delete_workproduct_files(sess, &swp.work_product);
 }
 
-/// Either a result that has already be computed or a
-/// handle that will let us wait until it is computed
-/// by a background thread.
-pub enum MaybeAsync<T> {
-    Sync(T),
-    Async(std::thread::JoinHandle<T>),
-}
-
-impl<T> MaybeAsync<LoadResult<T>> {
-    /// Accesses the data returned in [`LoadResult::Ok`] in an asynchronous way if possible.
-    pub fn open(self) -> LoadResult<T> {
-        match self {
-            MaybeAsync::Sync(result) => result,
-            MaybeAsync::Async(handle) => {
-                handle.join().unwrap_or_else(|e| LoadResult::DecodeIncrCache(e))
-            }
-        }
-    }
-}
-
-/// An asynchronous type for computing the dependency graph.
-pub type DepGraphFuture = MaybeAsync<LoadResult<(SerializedDepGraph, WorkProductMap)>>;
-
-/// Launch a thread and load the dependency graph in the background.
-pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
-    // Since `sess` isn't `Sync`, we perform all accesses to `sess`
-    // before we fire the background thread.
-
+fn load_dep_graph(sess: &Session) -> LoadResult<(SerializedDepGraph, WorkProductMap)> {
     let prof = sess.prof.clone();
 
     if sess.opts.incremental.is_none() {
         // No incremental compilation.
-        return MaybeAsync::Sync(LoadResult::Ok { data: Default::default() });
+        return LoadResult::Ok { data: Default::default() };
     }
 
     let _timer = sess.prof.generic_activity("incr_comp_prepare_load_dep_graph");
@@ -142,7 +108,6 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
     // Calling `sess.incr_comp_session_dir()` will panic if `sess.opts.incremental.is_none()`.
     // Fortunately, we just checked that this isn't the case.
     let path = dep_graph_path(&sess);
-    let report_incremental_info = sess.opts.unstable_opts.incremental_info;
     let expected_hash = sess.opts.dep_tracking_hash(false);
 
     let mut prev_work_products = UnordMap::default();
@@ -180,40 +145,35 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
         }
     }
 
-    let is_nightly_build = sess.is_nightly_build();
-    let cfg_version = sess.cfg_version;
-
-    MaybeAsync::Async(std::thread::spawn(move || {
-        let _prof_timer = prof.generic_activity("incr_comp_load_dep_graph");
+    let _prof_timer = prof.generic_activity("incr_comp_load_dep_graph");
 
-        match load_data_no_sess(&path, report_incremental_info, is_nightly_build, cfg_version) {
-            LoadResult::DataOutOfDate => LoadResult::DataOutOfDate,
-            LoadResult::LoadDepGraph(path, err) => LoadResult::LoadDepGraph(path, err),
-            LoadResult::DecodeIncrCache(err) => LoadResult::DecodeIncrCache(err),
-            LoadResult::Ok { data: (bytes, start_pos) } => {
-                let mut decoder = MemDecoder::new(&bytes, start_pos);
-                let prev_commandline_args_hash = u64::decode(&mut decoder);
+    match load_data(&path, sess) {
+        LoadResult::DataOutOfDate => LoadResult::DataOutOfDate,
+        LoadResult::LoadDepGraph(path, err) => LoadResult::LoadDepGraph(path, err),
+        LoadResult::DecodeIncrCache(err) => LoadResult::DecodeIncrCache(err),
+        LoadResult::Ok { data: (bytes, start_pos) } => {
+            let mut decoder = MemDecoder::new(&bytes, start_pos);
+            let prev_commandline_args_hash = u64::decode(&mut decoder);
 
-                if prev_commandline_args_hash != expected_hash {
-                    if report_incremental_info {
-                        eprintln!(
-                            "[incremental] completely ignoring cache because of \
+            if prev_commandline_args_hash != expected_hash {
+                if sess.opts.unstable_opts.incremental_info {
+                    eprintln!(
+                        "[incremental] completely ignoring cache because of \
                                     differing commandline arguments"
-                        );
-                    }
-                    // We can't reuse the cache, purge it.
-                    debug!("load_dep_graph_new: differing commandline arg hashes");
-
-                    // No need to do any further work
-                    return LoadResult::DataOutOfDate;
+                    );
                 }
+                // We can't reuse the cache, purge it.
+                debug!("load_dep_graph_new: differing commandline arg hashes");
 
-                let dep_graph = SerializedDepGraph::decode::<DepsType>(&mut decoder);
-
-                LoadResult::Ok { data: (dep_graph, prev_work_products) }
+                // No need to do any further work
+                return LoadResult::DataOutOfDate;
             }
+
+            let dep_graph = SerializedDepGraph::decode::<DepsType>(&mut decoder);
+
+            LoadResult::Ok { data: (dep_graph, prev_work_products) }
         }
-    }))
+    }
 }
 
 /// Attempts to load the query result cache from disk
@@ -235,3 +195,35 @@ pub fn load_query_result_cache(sess: &Session) -> Option<OnDiskCache<'_>> {
         _ => Some(OnDiskCache::new_empty(sess.source_map())),
     }
 }
+
+/// Setups the dependency graph by loading an existing graph from disk and set up streaming of a
+/// new graph to an incremental session directory.
+pub fn setup_dep_graph(
+    sess: &Session,
+    crate_name: Symbol,
+    stable_crate_id: StableCrateId,
+) -> Result<DepGraph, ErrorGuaranteed> {
+    // `load_dep_graph` can only be called after `prepare_session_directory`.
+    prepare_session_directory(sess, crate_name, stable_crate_id)?;
+
+    let res = sess.opts.build_dep_graph().then(|| load_dep_graph(sess));
+
+    if sess.opts.incremental.is_some() {
+        sess.time("incr_comp_garbage_collect_session_directories", || {
+            if let Err(e) = garbage_collect_session_directories(sess) {
+                warn!(
+                    "Error while trying to garbage collect incremental \
+                     compilation cache directory: {}",
+                    e
+                );
+            }
+        });
+    }
+
+    Ok(res
+        .and_then(|result| {
+            let (prev_graph, prev_work_products) = result.open(sess);
+            build_dep_graph(sess, prev_graph, prev_work_products)
+        })
+        .unwrap_or_else(DepGraph::new_disabled))
+}
diff --git a/compiler/rustc_incremental/src/persist/mod.rs b/compiler/rustc_incremental/src/persist/mod.rs
index 1336189bc0d..fdecaca5a2d 100644
--- a/compiler/rustc_incremental/src/persist/mod.rs
+++ b/compiler/rustc_incremental/src/persist/mod.rs
@@ -16,9 +16,8 @@ pub use fs::in_incr_comp_dir;
 pub use fs::in_incr_comp_dir_sess;
 pub use fs::prepare_session_directory;
 pub use load::load_query_result_cache;
+pub use load::setup_dep_graph;
 pub use load::LoadResult;
-pub use load::{load_dep_graph, DepGraphFuture};
-pub use save::build_dep_graph;
 pub use save::save_dep_graph;
 pub use save::save_work_product_index;
 pub use work_product::copy_cgu_workproduct_to_incr_comp_cache_dir;
diff --git a/compiler/rustc_incremental/src/persist/save.rs b/compiler/rustc_incremental/src/persist/save.rs
index 7719482890e..210da751d95 100644
--- a/compiler/rustc_incremental/src/persist/save.rs
+++ b/compiler/rustc_incremental/src/persist/save.rs
@@ -147,7 +147,7 @@ fn encode_query_cache(tcx: TyCtxt<'_>, encoder: FileEncoder) -> FileEncodeResult
 /// execution, the new dependency information is not kept in memory but directly
 /// output to this file. `save_dep_graph` then finalizes the staging dep-graph
 /// and moves it to the permanent dep-graph path
-pub fn build_dep_graph(
+pub(crate) fn build_dep_graph(
     sess: &Session,
     prev_graph: SerializedDepGraph,
     prev_work_products: WorkProductMap,
diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs
index 449d7a29590..fe253febfc7 100644
--- a/compiler/rustc_interface/src/queries.rs
+++ b/compiler/rustc_interface/src/queries.rs
@@ -10,7 +10,7 @@ use rustc_data_structures::svh::Svh;
 use rustc_data_structures::sync::{AppendOnlyIndexVec, FreezeLock, Lrc, OnceLock, WorkerLocal};
 use rustc_hir::def_id::{StableCrateId, CRATE_DEF_ID, LOCAL_CRATE};
 use rustc_hir::definitions::Definitions;
-use rustc_incremental::DepGraphFuture;
+use rustc_incremental::setup_dep_graph;
 use rustc_metadata::creader::CStore;
 use rustc_middle::arena::Arena;
 use rustc_middle::dep_graph::DepGraph;
@@ -19,7 +19,6 @@ use rustc_session::config::{self, CrateType, OutputFilenames, OutputType};
 use rustc_session::cstore::Untracked;
 use rustc_session::{output::find_crate_name, Session};
 use rustc_span::symbol::sym;
-use rustc_span::Symbol;
 use std::any::Any;
 use std::cell::{RefCell, RefMut};
 use std::sync::Arc;
@@ -132,43 +131,6 @@ impl<'tcx> Queries<'tcx> {
         })
     }
 
-    fn dep_graph_future(
-        &self,
-        crate_name: Symbol,
-        stable_crate_id: StableCrateId,
-    ) -> Result<Option<DepGraphFuture>> {
-        let sess = self.session();
-
-        // `load_dep_graph` can only be called after `prepare_session_directory`.
-        rustc_incremental::prepare_session_directory(sess, crate_name, stable_crate_id)?;
-        let res = sess.opts.build_dep_graph().then(|| rustc_incremental::load_dep_graph(sess));
-
-        if sess.opts.incremental.is_some() {
-            sess.time("incr_comp_garbage_collect_session_directories", || {
-                if let Err(e) = rustc_incremental::garbage_collect_session_directories(sess) {
-                    warn!(
-                        "Error while trying to garbage collect incremental \
-                         compilation cache directory: {}",
-                        e
-                    );
-                }
-            });
-        }
-
-        Ok(res)
-    }
-
-    fn dep_graph(&self, dep_graph_future: Option<DepGraphFuture>) -> DepGraph {
-        dep_graph_future
-            .and_then(|future| {
-                let sess = self.session();
-                let (prev_graph, prev_work_products) =
-                    sess.time("blocked_on_dep_graph_loading", || future.open().open(sess));
-                rustc_incremental::build_dep_graph(sess, prev_graph, prev_work_products)
-            })
-            .unwrap_or_else(DepGraph::new_disabled)
-    }
-
     pub fn global_ctxt(&'tcx self) -> Result<QueryResult<'_, &'tcx GlobalCtxt<'tcx>>> {
         self.gcx.compute(|| {
             let sess = self.session();
@@ -184,10 +146,7 @@ impl<'tcx> Queries<'tcx> {
                 sess.opts.cg.metadata.clone(),
                 sess.cfg_version,
             );
-
-            // Compute the dependency graph (in the background). We want to do this as early as
-            // possible, to give the DepGraph maximum time to load before `dep_graph` is called.
-            let dep_graph_future = self.dep_graph_future(crate_name, stable_crate_id)?;
+            let dep_graph = setup_dep_graph(sess, crate_name, stable_crate_id)?;
 
             let lint_store = Lrc::new(passes::create_lint_store(
                 sess,
@@ -210,7 +169,7 @@ impl<'tcx> Queries<'tcx> {
                 crate_types,
                 stable_crate_id,
                 lint_store,
-                self.dep_graph(dep_graph_future),
+                dep_graph,
                 untracked,
                 &self.gcx_cell,
                 &self.arena,