Skip to content

Commit 64f2bbd

Browse files
committed
Make copy_cgu_workproducts_to_incr_comp_cache_dir parallel
1 parent 62b7273 commit 64f2bbd

File tree

4 files changed

+69
-64
lines changed

4 files changed

+69
-64
lines changed

src/librustc_codegen_ssa/back/write.rs

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use rustc_data_structures::fx::FxHashMap;
2121
use rustc_data_structures::profiling::SelfProfilerRef;
2222
use rustc_data_structures::profiling::VerboseTimingGuard;
2323
use rustc_data_structures::svh::Svh;
24-
use rustc_data_structures::sync::Lrc;
24+
use rustc_data_structures::sync::{par_partition, Lrc};
2525
use rustc_errors::emitter::Emitter;
2626
use rustc_errors::{DiagnosticId, FatalError, Handler, Level};
2727
use rustc_fs_util::link_or_copy;
@@ -239,7 +239,7 @@ pub struct CodegenContext<B: WriteBackendMethods> {
239239
pub worker: usize,
240240
// The incremental compilation session directory, or None if we are not
241241
// compiling incrementally
242-
pub incr_comp_session_dir: Option<PathBuf>,
242+
pub incr_comp_session_dir: Option<Arc<PathBuf>>,
243243
// Used to update CGU re-use information during the thinlto phase.
244244
pub cgu_reuse_tracker: CguReuseTracker,
245245
// Channel back to the main control thread to send messages to
@@ -473,32 +473,47 @@ fn copy_all_cgu_workproducts_to_incr_comp_cache_dir(
473473
sess: &Session,
474474
compiled_modules: &CompiledModules,
475475
) -> FxHashMap<WorkProductId, WorkProduct> {
476-
let mut work_products = FxHashMap::default();
477-
478476
if sess.opts.incremental.is_none() {
479-
return work_products;
477+
return FxHashMap::default();
480478
}
481479

482-
let _timer = sess.timer("incr_comp_copy_cgu_workproducts");
480+
let _timer = sess.timer("incr_comp_copy_all_cgu_workproducts");
483481

484-
for module in compiled_modules.modules.iter().filter(|m| m.kind == ModuleKind::Regular) {
485-
let mut files = vec![];
482+
let session_dir = sess.incr_comp_session_dir();
486483

487-
if let Some(ref path) = module.object {
488-
files.push((WorkProductFileKind::Object, path.clone()));
489-
}
490-
if let Some(ref path) = module.bytecode {
491-
files.push((WorkProductFileKind::Bytecode, path.clone()));
492-
}
493-
if let Some(ref path) = module.bytecode_compressed {
494-
files.push((WorkProductFileKind::BytecodeCompressed, path.clone()));
495-
}
484+
// Split the modules into 3 parts, which limits usage to 3 threads.
485+
// That seems to be all Windows' file system can handle.
486+
let work_product_chunks = par_partition(&compiled_modules.modules, 3, |chunk| {
487+
chunk
488+
.iter()
489+
.filter(|m| m.kind == ModuleKind::Regular)
490+
.filter_map(|module| {
491+
let mut files = vec![];
496492

497-
if let Some((id, product)) =
498-
copy_cgu_workproducts_to_incr_comp_cache_dir(sess, &module.name, &files)
499-
{
500-
work_products.insert(id, product);
501-
}
493+
if let Some(ref path) = module.object {
494+
files.push((WorkProductFileKind::Object, path.clone()));
495+
}
496+
if let Some(ref path) = module.bytecode {
497+
files.push((WorkProductFileKind::Bytecode, path.clone()));
498+
}
499+
if let Some(ref path) = module.bytecode_compressed {
500+
files.push((WorkProductFileKind::BytecodeCompressed, path.clone()));
501+
}
502+
503+
copy_cgu_workproducts_to_incr_comp_cache_dir(
504+
sess,
505+
&session_dir,
506+
&module.name,
507+
&files,
508+
)
509+
})
510+
.collect::<Vec<_>>()
511+
});
512+
513+
let mut work_products = FxHashMap::default();
514+
515+
for (id, product) in work_product_chunks.into_iter().flat_map(|chunk| chunk.into_iter()) {
516+
work_products.insert(id, product);
502517
}
503518

504519
work_products
@@ -1029,7 +1044,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
10291044
exported_symbols,
10301045
remark: sess.opts.cg.remark.clone(),
10311046
worker: 0,
1032-
incr_comp_session_dir: sess.incr_comp_session_dir_opt().map(|r| r.clone()),
1047+
incr_comp_session_dir: sess.incr_comp_session_dir_opt(),
10331048
cgu_reuse_tracker: sess.cgu_reuse_tracker.clone(),
10341049
coordinator_send,
10351050
diag_emitter: shared_emitter.clone(),

src/librustc_incremental/persist/fs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ pub fn finalize_session_directory(sess: &Session, svh: Svh) {
310310

311311
let _timer = sess.timer("incr_comp_finalize_session_directory");
312312

313-
let incr_comp_session_dir: PathBuf = sess.incr_comp_session_dir().clone();
313+
let incr_comp_session_dir = sess.incr_comp_session_dir();
314314

315315
if sess.has_errors_or_delayed_span_bugs() {
316316
// If there have been any errors during compilation, we don't want to

src/librustc_incremental/persist/work_product.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ use rustc::dep_graph::{WorkProduct, WorkProductFileKind, WorkProductId};
55
use rustc::session::Session;
66
use rustc_fs_util::link_or_copy;
77
use std::fs as std_fs;
8-
use std::path::PathBuf;
8+
use std::path::{Path, PathBuf};
99

1010
pub fn copy_cgu_workproducts_to_incr_comp_cache_dir(
1111
sess: &Session,
12+
session_dir: &Path,
1213
cgu_name: &str,
1314
files: &[(WorkProductFileKind, PathBuf)],
1415
) -> Option<(WorkProductId, WorkProduct)> {
@@ -17,6 +18,8 @@ pub fn copy_cgu_workproducts_to_incr_comp_cache_dir(
1718
return None;
1819
}
1920

21+
let _timer = sess.prof.generic_activity("incr_comp_copy_cgu_workproducts");
22+
2023
let saved_files = files
2124
.iter()
2225
.map(|&(kind, ref path)| {
@@ -26,7 +29,7 @@ pub fn copy_cgu_workproducts_to_incr_comp_cache_dir(
2629
WorkProductFileKind::BytecodeCompressed => "bc.z",
2730
};
2831
let file_name = format!("{}.{}", cgu_name, extension);
29-
let path_in_incr_dir = in_incr_comp_dir_sess(sess, &file_name);
32+
let path_in_incr_dir = session_dir.join(&file_name);
3033
match link_or_copy(path, &path_in_incr_dir) {
3134
Ok(_) => Some((kind, file_name)),
3235
Err(err) => {

src/librustc_session/session.rs

Lines changed: 25 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use rustc_data_structures::profiling::{SelfProfiler, SelfProfilerRef};
3434
use rustc_target::spec::{PanicStrategy, RelroLevel, Target, TargetTriple};
3535

3636
use std;
37-
use std::cell::{self, RefCell};
37+
use std::cell::RefCell;
3838
use std::env;
3939
use std::fmt;
4040
use std::io::Write;
@@ -94,7 +94,7 @@ pub struct Session {
9494
/// macro name and definition span in the source crate.
9595
pub imported_macro_spans: OneThread<RefCell<FxHashMap<Span, (String, Span)>>>,
9696

97-
incr_comp_session: OneThread<RefCell<IncrCompSession>>,
97+
incr_comp_session: Lock<IncrCompSession>,
9898
/// Used for incremental compilation tests. Will only be populated if
9999
/// `-Zquery-dep-graph` is specified.
100100
pub cgu_reuse_tracker: CguReuseTracker,
@@ -599,53 +599,41 @@ impl Session {
599599
)
600600
}
601601

602-
pub fn set_incr_session_load_dep_graph(&self, load: bool) {
603-
let mut incr_comp_session = self.incr_comp_session.borrow_mut();
604-
605-
if let IncrCompSession::Active { ref mut load_dep_graph, .. } = *incr_comp_session {
606-
*load_dep_graph = load;
607-
}
608-
}
609-
610-
pub fn incr_session_load_dep_graph(&self) -> bool {
611-
let incr_comp_session = self.incr_comp_session.borrow();
612-
match *incr_comp_session {
613-
IncrCompSession::Active { load_dep_graph, .. } => load_dep_graph,
614-
_ => false,
615-
}
616-
}
617-
618602
pub fn init_incr_comp_session(
619603
&self,
620604
session_dir: PathBuf,
621605
lock_file: flock::Lock,
622606
load_dep_graph: bool,
623607
) {
624-
let mut incr_comp_session = self.incr_comp_session.borrow_mut();
608+
let mut incr_comp_session = self.incr_comp_session.lock();
625609

626610
if let IncrCompSession::NotInitialized = *incr_comp_session {
627611
} else {
628612
panic!("Trying to initialize IncrCompSession `{:?}`", *incr_comp_session)
629613
}
630614

631-
*incr_comp_session =
632-
IncrCompSession::Active { session_directory: session_dir, lock_file, load_dep_graph };
615+
*incr_comp_session = IncrCompSession::Active {
616+
session_directory: Arc::new(session_dir),
617+
lock_file,
618+
load_dep_graph,
619+
};
633620
}
634621

635622
pub fn finalize_incr_comp_session(&self, new_directory_path: PathBuf) {
636-
let mut incr_comp_session = self.incr_comp_session.borrow_mut();
623+
let mut incr_comp_session = self.incr_comp_session.lock();
637624

638625
if let IncrCompSession::Active { .. } = *incr_comp_session {
639626
} else {
640627
panic!("trying to finalize `IncrCompSession` `{:?}`", *incr_comp_session);
641628
}
642629

643630
// Note: this will also drop the lock file, thus unlocking the directory.
644-
*incr_comp_session = IncrCompSession::Finalized { session_directory: new_directory_path };
631+
*incr_comp_session =
632+
IncrCompSession::Finalized { session_directory: Arc::new(new_directory_path) };
645633
}
646634

647635
pub fn mark_incr_comp_session_as_invalid(&self) {
648-
let mut incr_comp_session = self.incr_comp_session.borrow_mut();
636+
let mut incr_comp_session = self.incr_comp_session.lock();
649637

650638
let session_directory = match *incr_comp_session {
651639
IncrCompSession::Active { ref session_directory, .. } => session_directory.clone(),
@@ -657,22 +645,21 @@ impl Session {
657645
*incr_comp_session = IncrCompSession::InvalidBecauseOfErrors { session_directory };
658646
}
659647

660-
pub fn incr_comp_session_dir(&self) -> cell::Ref<'_, PathBuf> {
661-
let incr_comp_session = self.incr_comp_session.borrow();
662-
cell::Ref::map(incr_comp_session, |incr_comp_session| match *incr_comp_session {
663-
IncrCompSession::NotInitialized => panic!(
664-
"trying to get session directory from `IncrCompSession`: {:?}",
665-
*incr_comp_session,
666-
),
648+
pub fn incr_comp_session_dir(&self) -> Arc<PathBuf> {
649+
let session = self.incr_comp_session.lock();
650+
match *session {
651+
IncrCompSession::NotInitialized => {
652+
panic!("trying to get session directory from `IncrCompSession`: {:?}", *session)
653+
}
667654
IncrCompSession::Active { ref session_directory, .. }
668655
| IncrCompSession::Finalized { ref session_directory }
669656
| IncrCompSession::InvalidBecauseOfErrors { ref session_directory } => {
670-
session_directory
657+
session_directory.clone()
671658
}
672-
})
659+
}
673660
}
674661

675-
pub fn incr_comp_session_dir_opt(&self) -> Option<cell::Ref<'_, PathBuf>> {
662+
pub fn incr_comp_session_dir_opt(&self) -> Option<Arc<PathBuf>> {
676663
self.opts.incremental.as_ref().map(|_| self.incr_comp_session_dir())
677664
}
678665

@@ -1050,7 +1037,7 @@ fn build_session_(
10501037
recursion_limit: Once::new(),
10511038
type_length_limit: Once::new(),
10521039
imported_macro_spans: OneThread::new(RefCell::new(FxHashMap::default())),
1053-
incr_comp_session: OneThread::new(RefCell::new(IncrCompSession::NotInitialized)),
1040+
incr_comp_session: Lock::new(IncrCompSession::NotInitialized),
10541041
cgu_reuse_tracker,
10551042
prof,
10561043
perf_stats: PerfStats {
@@ -1188,14 +1175,14 @@ pub enum IncrCompSession {
11881175
NotInitialized,
11891176
/// This is the state during which the session directory is private and can
11901177
/// be modified.
1191-
Active { session_directory: PathBuf, lock_file: flock::Lock, load_dep_graph: bool },
1178+
Active { session_directory: Arc<PathBuf>, lock_file: flock::Lock, load_dep_graph: bool },
11921179
/// This is the state after the session directory has been finalized. In this
11931180
/// state, the contents of the directory must not be modified any more.
1194-
Finalized { session_directory: PathBuf },
1181+
Finalized { session_directory: Arc<PathBuf> },
11951182
/// This is an error state that is reached when some compilation error has
11961183
/// occurred. It indicates that the contents of the session directory must
11971184
/// not be used, since they might be invalid.
1198-
InvalidBecauseOfErrors { session_directory: PathBuf },
1185+
InvalidBecauseOfErrors { session_directory: Arc<PathBuf> },
11991186
}
12001187

12011188
pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! {

0 commit comments

Comments
 (0)