summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_incremental/src/persist/load.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_incremental/src/persist/load.rs')
-rw-r--r--compiler/rustc_incremental/src/persist/load.rs132
1 files changed, 62 insertions, 70 deletions
diff --git a/compiler/rustc_incremental/src/persist/load.rs b/compiler/rustc_incremental/src/persist/load.rs
index 8d67f6925..2310d0b12 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::{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(&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))
+}