Skip to content

Commit bd8e9b0

Browse files
committed
Auto merge of #39109 - michaelwoerister:incr-comp-cache-cleanup, r=nikomatsakis
incr.comp.: Delete orphaned work-products. The new partitioning scheme uncovered a hole in our incr. comp. cache directory garbage collection. So far, we relied on unneeded work products being deleted during the initial cache invalidation phase. However, we the new scheme, we get object files/work products that only contain code from upstream crates. Sometimes this code is not needed anymore (because all callers have been removed from the source) but because nothing that actually influences the contents of these work products had changed, we never deleted them from disk. r? @nikomatsakis
2 parents aedebfe + fe025d4 commit bd8e9b0

File tree

6 files changed

+51
-12
lines changed

6 files changed

+51
-12
lines changed

src/librustc/dep_graph/graph.rs

+6
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,12 @@ impl DepGraph {
126126
pub fn work_products(&self) -> Ref<FxHashMap<Arc<WorkProductId>, WorkProduct>> {
127127
self.data.work_products.borrow()
128128
}
129+
130+
/// Access the map of work-products created during the cached run. Only
131+
/// used during saving of the dep-graph.
132+
pub fn previous_work_products(&self) -> Ref<FxHashMap<Arc<WorkProductId>, WorkProduct>> {
133+
self.data.previous_work_products.borrow()
134+
}
129135
}
130136

131137
/// A "work product" is an intermediate result that we save into the

src/librustc_incremental/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,4 @@ pub use persist::save_trans_partition;
5757
pub use persist::save_work_products;
5858
pub use persist::in_incr_comp_dir;
5959
pub use persist::finalize_session_directory;
60+
pub use persist::delete_workproduct_files;

src/librustc_incremental/persist/load.rs

+2-12
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ use rustc::ty::TyCtxt;
1818
use rustc_data_structures::fx::{FxHashSet, FxHashMap};
1919
use rustc_serialize::Decodable as RustcDecodable;
2020
use rustc_serialize::opaque::Decoder;
21-
use std::fs;
2221
use std::path::{Path};
2322

2423
use IncrementalHashesMap;
@@ -29,6 +28,7 @@ use super::dirty_clean;
2928
use super::hash::*;
3029
use super::fs::*;
3130
use super::file_format;
31+
use super::work_product;
3232

3333
pub type DirtyNodes = FxHashSet<DepNode<DefPathIndex>>;
3434

@@ -322,17 +322,7 @@ fn reconcile_work_products<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
322322
fn delete_dirty_work_product(tcx: TyCtxt,
323323
swp: SerializedWorkProduct) {
324324
debug!("delete_dirty_work_product({:?})", swp);
325-
for &(_, ref file_name) in &swp.work_product.saved_files {
326-
let path = in_incr_comp_dir_sess(tcx.sess, file_name);
327-
match fs::remove_file(&path) {
328-
Ok(()) => { }
329-
Err(err) => {
330-
tcx.sess.warn(
331-
&format!("file-system error deleting outdated file `{}`: {}",
332-
path.display(), err));
333-
}
334-
}
335-
}
325+
work_product::delete_workproduct_files(tcx.sess, &swp.work_product);
336326
}
337327

338328
fn load_prev_metadata_hashes(tcx: TyCtxt,

src/librustc_incremental/persist/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,4 @@ pub use self::load::load_dep_graph;
2929
pub use self::save::save_dep_graph;
3030
pub use self::save::save_work_products;
3131
pub use self::work_product::save_trans_partition;
32+
pub use self::work_product::delete_workproduct_files;

src/librustc_incremental/persist/save.rs

+26
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ use super::preds::*;
3030
use super::fs::*;
3131
use super::dirty_clean;
3232
use super::file_format;
33+
use super::work_product;
3334
use calculate_svh::IchHasher;
3435

3536
pub fn save_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
@@ -84,6 +85,31 @@ pub fn save_work_products(sess: &Session) {
8485
let _ignore = sess.dep_graph.in_ignore();
8586
let path = work_products_path(sess);
8687
save_in(sess, path, |e| encode_work_products(sess, e));
88+
89+
// We also need to clean out old work-products, as not all of them are
90+
// deleted during invalidation. Some object files don't change their
91+
// content, they are just not needed anymore.
92+
let new_work_products = sess.dep_graph.work_products();
93+
let previous_work_products = sess.dep_graph.previous_work_products();
94+
95+
for (id, wp) in previous_work_products.iter() {
96+
if !new_work_products.contains_key(id) {
97+
work_product::delete_workproduct_files(sess, wp);
98+
debug_assert!(wp.saved_files.iter().all(|&(_, ref file_name)| {
99+
!in_incr_comp_dir_sess(sess, file_name).exists()
100+
}));
101+
}
102+
}
103+
104+
// Check that we did not delete one of the current work-products:
105+
debug_assert!({
106+
new_work_products.iter()
107+
.flat_map(|(_, wp)| wp.saved_files
108+
.iter()
109+
.map(|&(_, ref name)| name))
110+
.map(|name| in_incr_comp_dir_sess(sess, name))
111+
.all(|path| path.exists())
112+
});
87113
}
88114

89115
fn save_in<F>(sess: &Session, path_buf: PathBuf, encode: F)

src/librustc_incremental/persist/work_product.rs

+15
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use rustc::session::config::OutputType;
1717
use rustc::util::fs::link_or_copy;
1818
use std::path::PathBuf;
1919
use std::sync::Arc;
20+
use std::fs as std_fs;
2021

2122
pub fn save_trans_partition(sess: &Session,
2223
cgu_name: &str,
@@ -61,3 +62,17 @@ pub fn save_trans_partition(sess: &Session,
6162

6263
sess.dep_graph.insert_work_product(&work_product_id, work_product);
6364
}
65+
66+
pub fn delete_workproduct_files(sess: &Session, work_product: &WorkProduct) {
67+
for &(_, ref file_name) in &work_product.saved_files {
68+
let path = in_incr_comp_dir_sess(sess, file_name);
69+
match std_fs::remove_file(&path) {
70+
Ok(()) => { }
71+
Err(err) => {
72+
sess.warn(
73+
&format!("file-system error deleting outdated file `{}`: {}",
74+
path.display(), err));
75+
}
76+
}
77+
}
78+
}

0 commit comments

Comments
 (0)