Skip to content

Commit 62b7273

Browse files
committed
Run link_binary_remove_temps in the background
1 parent 1e02626 commit 62b7273

File tree

4 files changed

+62
-46
lines changed

4 files changed

+62
-46
lines changed

src/librustc_codegen_llvm/lib.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ use rustc::ty::{self, TyCtxt};
4444
use rustc::util::common::ErrorReported;
4545
use rustc_codegen_ssa::ModuleCodegen;
4646
use rustc_codegen_utils::codegen_backend::CodegenBackend;
47+
use rustc_data_structures::sync::Lrc;
4748

4849
mod back {
4950
pub mod archive;
@@ -271,7 +272,7 @@ impl CodegenBackend for LlvmCodegenBackend {
271272
fn join_codegen_and_link(
272273
&self,
273274
ongoing_codegen: Box<dyn Any>,
274-
sess: &Session,
275+
sess: &Lrc<Session>,
275276
dep_graph: &DepGraph,
276277
outputs: &OutputFilenames,
277278
) -> Result<(), ErrorReported> {
@@ -298,9 +299,11 @@ impl CodegenBackend for LlvmCodegenBackend {
298299
return Ok(());
299300
}
300301

302+
let codegen_results = Lrc::new(codegen_results);
303+
301304
// Run the linker on any artifacts that resulted from the LLVM run.
302305
// This should produce either a finished executable or library.
303-
sess.time("link_crate", || {
306+
let cleanup_future = sess.time("link_crate", || {
304307
use crate::back::archive::LlvmArchiveBuilder;
305308
use rustc_codegen_ssa::back::link::link_binary;
306309

@@ -311,13 +314,16 @@ impl CodegenBackend for LlvmCodegenBackend {
311314
outputs,
312315
&codegen_results.crate_name.as_str(),
313316
target_cpu,
314-
);
317+
)
315318
});
316319

317320
// Now that we won't touch anything in the incremental compilation directory
318321
// any more, we can finalize it (which involves renaming it)
319322
rustc_incremental::finalize_session_directory(sess, codegen_results.crate_hash);
320323

324+
// Join the cleanup future so it drops the `Lrc<Session>` it holds.
325+
cleanup_future.join();
326+
321327
Ok(())
322328
}
323329
}

src/librustc_codegen_ssa/back/link.rs

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ use rustc::session::search_paths::PathKind;
88
/// need out of the shared crate context before we get rid of it.
99
use rustc::session::{filesearch, Session};
1010
use rustc_data_structures::fx::FxHashSet;
11+
use rustc_data_structures::sync::future::Future;
12+
use rustc_data_structures::sync::Lrc;
1113
use rustc_fs_util::fix_windows_verbatim_for_gcc;
1214
use rustc_hir::def_id::CrateNum;
1315
use rustc_span::symbol::Symbol;
@@ -47,12 +49,12 @@ pub fn remove(sess: &Session, path: &Path) {
4749
/// Performs the linkage portion of the compilation phase. This will generate all
4850
/// of the requested outputs for this compilation session.
4951
pub fn link_binary<'a, B: ArchiveBuilder<'a>>(
50-
sess: &'a Session,
51-
codegen_results: &CodegenResults,
52+
sess: &'a Lrc<Session>,
53+
codegen_results: &Lrc<CodegenResults>,
5254
outputs: &OutputFilenames,
5355
crate_name: &str,
5456
target_cpu: &str,
55-
) {
57+
) -> Future<'static, ()> {
5658
let _timer = sess.timer("link_binary");
5759
let output_metadata = sess.opts.output_types.contains_key(&OutputType::Metadata);
5860
for &crate_type in sess.crate_types.borrow().iter() {
@@ -122,34 +124,40 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(
122124
}
123125

124126
// Remove the temporary object file and metadata if we aren't saving temps
125-
sess.time("link_binary_remove_temps", || {
126-
if !sess.opts.cg.save_temps {
127-
if sess.opts.output_types.should_codegen()
128-
&& !preserve_objects_for_their_debuginfo(sess)
129-
{
130-
for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) {
131-
remove(sess, obj);
127+
let sess = sess.clone();
128+
let codegen_results = codegen_results.clone();
129+
Future::spawn(move || {
130+
let sess = &*sess;
131+
sess.time("link_binary_remove_temps", || {
132+
if !sess.opts.cg.save_temps {
133+
if sess.opts.output_types.should_codegen()
134+
&& !preserve_objects_for_their_debuginfo(sess)
135+
{
136+
for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) {
137+
remove(sess, obj);
138+
}
132139
}
133-
}
134-
for obj in codegen_results.modules.iter().filter_map(|m| m.bytecode_compressed.as_ref())
135-
{
136-
remove(sess, obj);
137-
}
138-
if let Some(ref metadata_module) = codegen_results.metadata_module {
139-
if let Some(ref obj) = metadata_module.object {
140+
for obj in
141+
codegen_results.modules.iter().filter_map(|m| m.bytecode_compressed.as_ref())
142+
{
140143
remove(sess, obj);
141144
}
142-
}
143-
if let Some(ref allocator_module) = codegen_results.allocator_module {
144-
if let Some(ref obj) = allocator_module.object {
145-
remove(sess, obj);
145+
if let Some(ref metadata_module) = codegen_results.metadata_module {
146+
if let Some(ref obj) = metadata_module.object {
147+
remove(sess, obj);
148+
}
146149
}
147-
if let Some(ref bc) = allocator_module.bytecode_compressed {
148-
remove(sess, bc);
150+
if let Some(ref allocator_module) = codegen_results.allocator_module {
151+
if let Some(ref obj) = allocator_module.object {
152+
remove(sess, obj);
153+
}
154+
if let Some(ref bc) = allocator_module.bytecode_compressed {
155+
remove(sess, bc);
156+
}
149157
}
150158
}
151-
}
152-
});
159+
});
160+
})
153161
}
154162

155163
// The third parameter is for env vars, used on windows to set up the

src/librustc_codegen_utils/codegen_backend.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use rustc::session::Session;
1515
use rustc::ty::query::Providers;
1616
use rustc::ty::TyCtxt;
1717
use rustc::util::common::ErrorReported;
18+
use rustc_data_structures::sync::Lrc;
1819
use rustc_span::symbol::Symbol;
1920

2021
pub use rustc_data_structures::sync::MetadataRef;
@@ -46,7 +47,7 @@ pub trait CodegenBackend {
4647
fn join_codegen_and_link(
4748
&self,
4849
ongoing_codegen: Box<dyn Any>,
49-
sess: &Session,
50+
sess: &Lrc<Session>,
5051
dep_graph: &DepGraph,
5152
outputs: &OutputFilenames,
5253
) -> Result<(), ErrorReported>;

src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,33 @@ extern crate rustc;
44
extern crate rustc_codegen_utils;
55
#[macro_use]
66
extern crate rustc_data_structures;
7-
extern crate rustc_hir;
8-
extern crate rustc_target;
97
extern crate rustc_driver;
8+
extern crate rustc_hir;
109
extern crate rustc_span;
10+
extern crate rustc_target;
1111

12-
use std::any::Any;
13-
use std::sync::Arc;
14-
use std::path::Path;
15-
use rustc_span::symbol::Symbol;
16-
use rustc::session::Session;
12+
use rustc::dep_graph::DepGraph;
13+
use rustc::middle::cstore::{EncodedMetadata, MetadataLoader, MetadataLoaderDyn};
1714
use rustc::session::config::OutputFilenames;
18-
use rustc::ty::TyCtxt;
15+
use rustc::session::Session;
1916
use rustc::ty::query::Providers;
20-
use rustc::middle::cstore::{EncodedMetadata, MetadataLoader, MetadataLoaderDyn};
21-
use rustc::dep_graph::DepGraph;
17+
use rustc::ty::TyCtxt;
2218
use rustc::util::common::ErrorReported;
2319
use rustc_codegen_utils::codegen_backend::CodegenBackend;
24-
use rustc_data_structures::sync::MetadataRef;
2520
use rustc_data_structures::owning_ref::OwningRef;
21+
use rustc_data_structures::sync::{Lrc, MetadataRef};
22+
use rustc_span::symbol::Symbol;
2623
use rustc_target::spec::Target;
24+
use std::any::Any;
25+
use std::path::Path;
26+
use std::sync::Arc;
2727

2828
pub struct NoLlvmMetadataLoader;
2929

3030
impl MetadataLoader for NoLlvmMetadataLoader {
3131
fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result<MetadataRef, String> {
32-
let buf = std::fs::read(filename).map_err(|e| format!("metadata file open err: {:?}", e))?;
32+
let buf =
33+
std::fs::read(filename).map_err(|e| format!("metadata file open err: {:?}", e))?;
3334
let buf: OwningRef<Vec<u8>, [u8]> = OwningRef::new(buf);
3435
Ok(rustc_erase_owner!(buf.map_owner_box()))
3536
}
@@ -74,21 +75,21 @@ impl CodegenBackend for TheBackend {
7475
fn join_codegen_and_link(
7576
&self,
7677
ongoing_codegen: Box<dyn Any>,
77-
sess: &Session,
78+
sess: &Lrc<Session>,
7879
_dep_graph: &DepGraph,
7980
outputs: &OutputFilenames,
8081
) -> Result<(), ErrorReported> {
81-
use std::io::Write;
8282
use rustc::session::config::CrateType;
8383
use rustc_codegen_utils::link::out_filename;
84-
let crate_name = ongoing_codegen.downcast::<Symbol>()
84+
use std::io::Write;
85+
let crate_name = ongoing_codegen
86+
.downcast::<Symbol>()
8587
.expect("in join_codegen_and_link: ongoing_codegen is not a Symbol");
8688
for &crate_type in sess.opts.crate_types.iter() {
8789
if crate_type != CrateType::Rlib {
8890
sess.fatal(&format!("Crate type is {:?}", crate_type));
8991
}
90-
let output_name =
91-
out_filename(sess, crate_type, &outputs, &*crate_name.as_str());
92+
let output_name = out_filename(sess, crate_type, &outputs, &*crate_name.as_str());
9293
let mut out_file = ::std::fs::File::create(output_name).unwrap();
9394
write!(out_file, "This has been \"compiled\" successfully.").unwrap();
9495
}

0 commit comments

Comments
 (0)