/// 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>>,
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.
(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()),
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.
self.data
.as_ref()
.and_then(|data| {
- data.previous_work_products.borrow().get(v).cloned()
+ data.previous_work_products.get(v).cloned()
})
}
/// 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)]
//! 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;
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) {
incremental compilation session directory contents `{}`: {}.",
dep_graph_path(sess).display(), err));
}
- PreviousDepGraph::new(SerializedDepGraph::new())
+ (PreviousDepGraph::new(SerializedDepGraph::new()), FxHashMap())
}
LoadResult::Ok { data } => data
}
}
}
-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
/// 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.
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())
});
}
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) {
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) }
}
}
})