Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 55121a9

Browse files
committed
avoid cloning the whole compiletest configuration for every test
1 parent c075691 commit 55121a9

File tree

3 files changed

+50
-31
lines changed

3 files changed

+50
-31
lines changed

src/tools/compiletest/src/common.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use std::process::Command;
88
use std::str::FromStr;
99

1010
use crate::util::{add_dylib_path, PathBufExt};
11-
use lazycell::LazyCell;
11+
use lazycell::AtomicLazyCell;
1212
use serde::de::{Deserialize, Deserializer, Error as _};
1313
use std::collections::{HashMap, HashSet};
1414
use test::{ColorConfig, OutputFormat};
@@ -326,7 +326,7 @@ pub struct Config {
326326
/// Only rerun the tests that result has been modified accoring to Git status
327327
pub only_modified: bool,
328328

329-
pub target_cfg: LazyCell<TargetCfg>,
329+
pub target_cfgs: AtomicLazyCell<TargetCfgs>,
330330

331331
pub nocapture: bool,
332332
}
@@ -340,7 +340,13 @@ impl Config {
340340
}
341341

342342
pub fn target_cfgs(&self) -> &TargetCfgs {
343-
self.target_cfgs.borrow_with(|| TargetCfgs::new(self))
343+
match self.target_cfgs.borrow() {
344+
Some(cfgs) => cfgs,
345+
None => {
346+
let _ = self.target_cfgs.fill(TargetCfgs::new(self));
347+
self.target_cfgs.borrow().unwrap()
348+
}
349+
}
344350
}
345351

346352
pub fn target_cfg(&self) -> &TargetCfg {

src/tools/compiletest/src/main.rs

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::util::logv;
1111
use build_helper::git::{get_git_modified_files, get_git_untracked_files};
1212
use core::panic;
1313
use getopts::Options;
14-
use lazycell::LazyCell;
14+
use lazycell::AtomicLazyCell;
1515
use std::collections::BTreeSet;
1616
use std::ffi::OsString;
1717
use std::fs;
@@ -25,6 +25,7 @@ use tracing::*;
2525
use walkdir::WalkDir;
2626

2727
use self::header::{make_test_description, EarlyProps};
28+
use std::sync::Arc;
2829

2930
#[cfg(test)]
3031
mod tests;
@@ -42,7 +43,7 @@ pub mod util;
4243
fn main() {
4344
tracing_subscriber::fmt::init();
4445

45-
let config = parse_config(env::args().collect());
46+
let config = Arc::new(parse_config(env::args().collect()));
4647

4748
if config.valgrind_path.is_none() && config.force_valgrind {
4849
panic!("Can't find Valgrind to run Valgrind tests");
@@ -313,7 +314,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
313314

314315
force_rerun: matches.opt_present("force-rerun"),
315316

316-
target_cfgs: LazyCell::new(),
317+
target_cfgs: AtomicLazyCell::new(),
317318

318319
nocapture: matches.opt_present("nocapture"),
319320
}
@@ -369,7 +370,7 @@ pub fn opt_str2(maybestr: Option<String>) -> String {
369370
}
370371
}
371372

372-
pub fn run_tests(config: Config) {
373+
pub fn run_tests(config: Arc<Config>) {
373374
// If we want to collect rustfix coverage information,
374375
// we first make sure that the coverage file does not exist.
375376
// It will be created later on.
@@ -411,7 +412,7 @@ pub fn run_tests(config: Config) {
411412
};
412413

413414
let mut tests = Vec::new();
414-
for c in &configs {
415+
for c in configs {
415416
let mut found_paths = BTreeSet::new();
416417
make_tests(c, &mut tests, &mut found_paths);
417418
check_overlapping_tests(&found_paths);
@@ -433,7 +434,11 @@ pub fn run_tests(config: Config) {
433434
println!(
434435
"Some tests failed in compiletest suite={}{} mode={} host={} target={}",
435436
config.suite,
436-
config.compare_mode.map(|c| format!(" compare_mode={:?}", c)).unwrap_or_default(),
437+
config
438+
.compare_mode
439+
.as_ref()
440+
.map(|c| format!(" compare_mode={:?}", c))
441+
.unwrap_or_default(),
437442
config.mode,
438443
config.host,
439444
config.target
@@ -453,13 +458,13 @@ pub fn run_tests(config: Config) {
453458
}
454459
}
455460

456-
fn configure_cdb(config: &Config) -> Option<Config> {
461+
fn configure_cdb(config: &Config) -> Option<Arc<Config>> {
457462
config.cdb.as_ref()?;
458463

459-
Some(Config { debugger: Some(Debugger::Cdb), ..config.clone() })
464+
Some(Arc::new(Config { debugger: Some(Debugger::Cdb), ..config.clone() }))
460465
}
461466

462-
fn configure_gdb(config: &Config) -> Option<Config> {
467+
fn configure_gdb(config: &Config) -> Option<Arc<Config>> {
463468
config.gdb_version?;
464469

465470
if config.matches_env("msvc") {
@@ -490,10 +495,10 @@ fn configure_gdb(config: &Config) -> Option<Config> {
490495
env::set_var("RUST_TEST_THREADS", "1");
491496
}
492497

493-
Some(Config { debugger: Some(Debugger::Gdb), ..config.clone() })
498+
Some(Arc::new(Config { debugger: Some(Debugger::Gdb), ..config.clone() }))
494499
}
495500

496-
fn configure_lldb(config: &Config) -> Option<Config> {
501+
fn configure_lldb(config: &Config) -> Option<Arc<Config>> {
497502
config.lldb_python_dir.as_ref()?;
498503

499504
if let Some(350) = config.lldb_version {
@@ -506,7 +511,7 @@ fn configure_lldb(config: &Config) -> Option<Config> {
506511
return None;
507512
}
508513

509-
Some(Config { debugger: Some(Debugger::Lldb), ..config.clone() })
514+
Some(Arc::new(Config { debugger: Some(Debugger::Lldb), ..config.clone() }))
510515
}
511516

512517
pub fn test_opts(config: &Config) -> test::TestOpts {
@@ -541,17 +546,17 @@ pub fn test_opts(config: &Config) -> test::TestOpts {
541546
}
542547

543548
pub fn make_tests(
544-
config: &Config,
549+
config: Arc<Config>,
545550
tests: &mut Vec<test::TestDescAndFn>,
546551
found_paths: &mut BTreeSet<PathBuf>,
547552
) {
548553
debug!("making tests from {:?}", config.src_base.display());
549-
let inputs = common_inputs_stamp(config);
550-
let modified_tests = modified_tests(config, &config.src_base).unwrap_or_else(|err| {
554+
let inputs = common_inputs_stamp(&config);
555+
let modified_tests = modified_tests(&config, &config.src_base).unwrap_or_else(|err| {
551556
panic!("modified_tests got error from dir: {}, error: {}", config.src_base.display(), err)
552557
});
553558
collect_tests_from_dir(
554-
config,
559+
config.clone(),
555560
&config.src_base,
556561
&PathBuf::new(),
557562
&inputs,
@@ -622,7 +627,7 @@ fn modified_tests(config: &Config, dir: &Path) -> Result<Vec<PathBuf>, String> {
622627
}
623628

624629
fn collect_tests_from_dir(
625-
config: &Config,
630+
config: Arc<Config>,
626631
dir: &Path,
627632
relative_dir_path: &Path,
628633
inputs: &Stamp,
@@ -650,7 +655,7 @@ fn collect_tests_from_dir(
650655
// sequential loop because otherwise, if we do it in the
651656
// tests themselves, they race for the privilege of
652657
// creating the directories and sometimes fail randomly.
653-
let build_dir = output_relative_path(config, relative_dir_path);
658+
let build_dir = output_relative_path(&config, relative_dir_path);
654659
fs::create_dir_all(&build_dir).unwrap();
655660

656661
// Add each `.rs` file as a test, and recurse further on any
@@ -666,13 +671,13 @@ fn collect_tests_from_dir(
666671
let paths =
667672
TestPaths { file: file_path, relative_dir: relative_dir_path.to_path_buf() };
668673

669-
tests.extend(make_test(config, &paths, inputs))
674+
tests.extend(make_test(config.clone(), &paths, inputs))
670675
} else if file_path.is_dir() {
671676
let relative_file_path = relative_dir_path.join(file.file_name());
672677
if &file_name != "auxiliary" {
673678
debug!("found directory: {:?}", file_path.display());
674679
collect_tests_from_dir(
675-
config,
680+
config.clone(),
676681
&file_path,
677682
&relative_file_path,
678683
inputs,
@@ -701,14 +706,18 @@ pub fn is_test(file_name: &OsString) -> bool {
701706
!invalid_prefixes.iter().any(|p| file_name.starts_with(p))
702707
}
703708

704-
fn make_test(config: &Config, testpaths: &TestPaths, inputs: &Stamp) -> Vec<test::TestDescAndFn> {
709+
fn make_test(
710+
config: Arc<Config>,
711+
testpaths: &TestPaths,
712+
inputs: &Stamp,
713+
) -> Vec<test::TestDescAndFn> {
705714
let test_path = if config.mode == Mode::RunMake {
706715
// Parse directives in the Makefile
707716
testpaths.file.join("Makefile")
708717
} else {
709718
PathBuf::from(&testpaths.file)
710719
};
711-
let early_props = EarlyProps::from_file(config, &test_path);
720+
let early_props = EarlyProps::from_file(&config, &test_path);
712721

713722
// Incremental tests are special, they inherently cannot be run in parallel.
714723
// `runtest::run` will be responsible for iterating over revisions.
@@ -723,19 +732,22 @@ fn make_test(config: &Config, testpaths: &TestPaths, inputs: &Stamp) -> Vec<test
723732
let src_file =
724733
std::fs::File::open(&test_path).expect("open test file to parse ignores");
725734
let cfg = revision.map(|v| &**v);
726-
let test_name = crate::make_test_name(config, testpaths, revision);
727-
let mut desc = make_test_description(config, test_name, &test_path, src_file, cfg);
735+
let test_name = crate::make_test_name(&config, testpaths, revision);
736+
let mut desc = make_test_description(&config, test_name, &test_path, src_file, cfg);
728737
// Ignore tests that already run and are up to date with respect to inputs.
729738
if !config.force_rerun {
730739
desc.ignore |= is_up_to_date(
731-
config,
740+
&config,
732741
testpaths,
733742
&early_props,
734743
revision.map(|s| s.as_str()),
735744
inputs,
736745
);
737746
}
738-
test::TestDescAndFn { desc, testfn: make_test_closure(config, testpaths, revision) }
747+
test::TestDescAndFn {
748+
desc,
749+
testfn: make_test_closure(config.clone(), testpaths, revision),
750+
}
739751
})
740752
.collect()
741753
}
@@ -869,7 +881,7 @@ fn make_test_name(
869881
}
870882

871883
fn make_test_closure(
872-
config: &Config,
884+
config: Arc<Config>,
873885
testpaths: &TestPaths,
874886
revision: Option<&String>,
875887
) -> test::TestFn {

src/tools/compiletest/src/runtest.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ use std::iter;
3030
use std::path::{Path, PathBuf};
3131
use std::process::{Child, Command, ExitStatus, Output, Stdio};
3232
use std::str;
33+
use std::sync::Arc;
3334

3435
use glob::glob;
3536
use once_cell::sync::Lazy;
@@ -96,7 +97,7 @@ pub fn get_lib_name(lib: &str, dylib: bool) -> String {
9697
}
9798
}
9899

99-
pub fn run(config: Config, testpaths: &TestPaths, revision: Option<&str>) {
100+
pub fn run(config: Arc<Config>, testpaths: &TestPaths, revision: Option<&str>) {
100101
match &*config.target {
101102
"arm-linux-androideabi"
102103
| "armv7-linux-androideabi"

0 commit comments

Comments
 (0)