Skip to content

Commit 907c0fe

Browse files
committed
Auto merge of #6573 - ehuss:mtime-on-use-feature, r=dwijnand
Put mtime-on-use behind a feature flag. This places #6477 behind the `-Z mtime-on-use` feature flag. The change to update the mtime each time a crate is used has caused a performance regression on the rust playground (rust-lang/rust#57774). It is using about 241 pre-built crates in a Docker container. Due to the copy-on-write nature of Docker, it can take a significant amount of time to update the timestamps (over 10 seconds on slower systems). cc @Mark-Simulacrum
2 parents 102f747 + 5f6ede2 commit 907c0fe

File tree

3 files changed

+46
-22
lines changed

3 files changed

+46
-22
lines changed

src/cargo/core/compiler/fingerprint.rs

+18-8
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ pub fn prepare_target<'a, 'cfg>(
6565
debug!("fingerprint at: {}", loc.display());
6666

6767
let fingerprint = calculate(cx, unit)?;
68-
let compare = compare_old_fingerprint(&loc, &*fingerprint);
68+
let mtime_on_use = cx.bcx.config.cli_unstable().mtime_on_use;
69+
let compare = compare_old_fingerprint(&loc, &*fingerprint, mtime_on_use);
6970
log_compare(unit, &compare);
7071

7172
// If our comparison failed (e.g. we're going to trigger a rebuild of this
@@ -102,8 +103,10 @@ pub fn prepare_target<'a, 'cfg>(
102103
.filter(|output| output.flavor != FileFlavor::DebugInfo)
103104
.find(|output| {
104105
if output.path.exists() {
105-
// update the mtime so other cleaners know we used it
106-
let _ = filetime::set_file_times(&output.path, t, t);
106+
if mtime_on_use {
107+
// update the mtime so other cleaners know we used it
108+
let _ = filetime::set_file_times(&output.path, t, t);
109+
}
107110
false
108111
} else {
109112
true
@@ -555,7 +558,8 @@ pub fn prepare_build_cmd<'a, 'cfg>(
555558
rustc: util::hash_u64(&cx.bcx.rustc.verbose_version),
556559
..Fingerprint::new()
557560
};
558-
let compare = compare_old_fingerprint(&loc, &fingerprint);
561+
let mtime_on_use = cx.bcx.config.cli_unstable().mtime_on_use;
562+
let compare = compare_old_fingerprint(&loc, &fingerprint, mtime_on_use);
559563
log_compare(unit, &compare);
560564

561565
// When we write out the fingerprint, we may want to actually change the
@@ -688,12 +692,18 @@ pub fn dep_info_loc<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> Pa
688692
.join(&format!("dep-{}", filename(cx, unit)))
689693
}
690694

691-
fn compare_old_fingerprint(loc: &Path, new_fingerprint: &Fingerprint) -> CargoResult<()> {
695+
fn compare_old_fingerprint(
696+
loc: &Path,
697+
new_fingerprint: &Fingerprint,
698+
mtime_on_use: bool,
699+
) -> CargoResult<()> {
692700
let old_fingerprint_short = paths::read(loc)?;
693701

694-
// update the mtime so other cleaners know we used it
695-
let t = FileTime::from_system_time(SystemTime::now());
696-
filetime::set_file_times(loc, t, t)?;
702+
if mtime_on_use {
703+
// update the mtime so other cleaners know we used it
704+
let t = FileTime::from_system_time(SystemTime::now());
705+
filetime::set_file_times(loc, t, t)?;
706+
}
697707

698708
let new_hash = new_fingerprint.hash();
699709

src/cargo/core/features.rs

+2
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ pub struct CliUnstable {
320320
pub package_features: bool,
321321
pub advanced_env: bool,
322322
pub config_profile: bool,
323+
pub mtime_on_use: bool,
323324
}
324325

325326
impl CliUnstable {
@@ -356,6 +357,7 @@ impl CliUnstable {
356357
"package-features" => self.package_features = true,
357358
"advanced-env" => self.advanced_env = true,
358359
"config-profile" => self.config_profile = true,
360+
"mtime-on-use" => self.mtime_on_use = true,
359361
_ => failure::bail!("unknown `-Z` flag specified: {}", k),
360362
}
361363

tests/testsuite/freshness.rs

+26-14
Original file line numberDiff line numberDiff line change
@@ -1193,7 +1193,7 @@ fn simple_deps_cleaner(mut dir: PathBuf, timestamp: filetime::FileTime) {
11931193
}
11941194

11951195
#[test]
1196-
fn simple_deps_cleaner_dose_not_rebuild() {
1196+
fn simple_deps_cleaner_does_not_rebuild() {
11971197
let p = project()
11981198
.file(
11991199
"Cargo.toml",
@@ -1211,8 +1211,11 @@ fn simple_deps_cleaner_dose_not_rebuild() {
12111211
.file("bar/src/lib.rs", "")
12121212
.build();
12131213

1214-
p.cargo("build").run();
1215-
p.cargo("build")
1214+
p.cargo("build -Z mtime-on-use")
1215+
.masquerade_as_nightly_cargo()
1216+
.run();
1217+
p.cargo("build -Z mtime-on-use")
1218+
.masquerade_as_nightly_cargo()
12161219
.env("RUSTFLAGS", "-C target-cpu=native")
12171220
.with_stderr(
12181221
"\
@@ -1228,19 +1231,22 @@ fn simple_deps_cleaner_dose_not_rebuild() {
12281231
if is_coarse_mtime() {
12291232
sleep_ms(1000);
12301233
}
1231-
// This dose not make new files, but it dose update the mtime.
1232-
p.cargo("build")
1234+
// This does not make new files, but it does update the mtime.
1235+
p.cargo("build -Z mtime-on-use")
1236+
.masquerade_as_nightly_cargo()
12331237
.env("RUSTFLAGS", "-C target-cpu=native")
12341238
.with_stderr("[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]")
12351239
.run();
12361240
simple_deps_cleaner(p.target_debug_dir(), timestamp);
12371241
// This should not recompile!
1238-
p.cargo("build")
1242+
p.cargo("build -Z mtime-on-use")
1243+
.masquerade_as_nightly_cargo()
12391244
.env("RUSTFLAGS", "-C target-cpu=native")
12401245
.with_stderr("[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]")
12411246
.run();
12421247
// But this should be cleaned and so need a rebuild
1243-
p.cargo("build")
1248+
p.cargo("build -Z mtime-on-use")
1249+
.masquerade_as_nightly_cargo()
12441250
.with_stderr(
12451251
"\
12461252
[COMPILING] bar v0.0.1 ([..])
@@ -1282,7 +1288,7 @@ fn fingerprint_cleaner(mut dir: PathBuf, timestamp: filetime::FileTime) {
12821288
}
12831289

12841290
#[test]
1285-
fn fingerprint_cleaner_dose_not_rebuild() {
1291+
fn fingerprint_cleaner_does_not_rebuild() {
12861292
let p = project()
12871293
.file(
12881294
"Cargo.toml",
@@ -1300,8 +1306,11 @@ fn fingerprint_cleaner_dose_not_rebuild() {
13001306
.file("bar/src/lib.rs", "")
13011307
.build();
13021308

1303-
p.cargo("build").run();
1304-
p.cargo("build")
1309+
p.cargo("build -Z mtime-on-use")
1310+
.masquerade_as_nightly_cargo()
1311+
.run();
1312+
p.cargo("build -Z mtime-on-use")
1313+
.masquerade_as_nightly_cargo()
13051314
.env("RUSTFLAGS", "-C target-cpu=native")
13061315
.with_stderr(
13071316
"\
@@ -1317,19 +1326,22 @@ fn fingerprint_cleaner_dose_not_rebuild() {
13171326
if is_coarse_mtime() {
13181327
sleep_ms(1000);
13191328
}
1320-
// This dose not make new files, but it dose update the mtime.
1321-
p.cargo("build")
1329+
// This does not make new files, but it does update the mtime.
1330+
p.cargo("build -Z mtime-on-use")
1331+
.masquerade_as_nightly_cargo()
13221332
.env("RUSTFLAGS", "-C target-cpu=native")
13231333
.with_stderr("[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]")
13241334
.run();
13251335
fingerprint_cleaner(p.target_debug_dir(), timestamp);
13261336
// This should not recompile!
1327-
p.cargo("build")
1337+
p.cargo("build -Z mtime-on-use")
1338+
.masquerade_as_nightly_cargo()
13281339
.env("RUSTFLAGS", "-C target-cpu=native")
13291340
.with_stderr("[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]")
13301341
.run();
13311342
// But this should be cleaned and so need a rebuild
1332-
p.cargo("build")
1343+
p.cargo("build -Z mtime-on-use")
1344+
.masquerade_as_nightly_cargo()
13331345
.with_stderr(
13341346
"\
13351347
[COMPILING] bar v0.0.1 ([..])

0 commit comments

Comments
 (0)