Skip to content

Commit

Permalink
Auto merge of #6573 - ehuss:mtime-on-use-feature, r=dwijnand
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Jan 20, 2019
2 parents 102f747 + 5f6ede2 commit 907c0fe
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 22 deletions.
26 changes: 18 additions & 8 deletions src/cargo/core/compiler/fingerprint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ pub fn prepare_target<'a, 'cfg>(
debug!("fingerprint at: {}", loc.display());

let fingerprint = calculate(cx, unit)?;
let compare = compare_old_fingerprint(&loc, &*fingerprint);
let mtime_on_use = cx.bcx.config.cli_unstable().mtime_on_use;
let compare = compare_old_fingerprint(&loc, &*fingerprint, mtime_on_use);
log_compare(unit, &compare);

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

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

fn compare_old_fingerprint(loc: &Path, new_fingerprint: &Fingerprint) -> CargoResult<()> {
fn compare_old_fingerprint(
loc: &Path,
new_fingerprint: &Fingerprint,
mtime_on_use: bool,
) -> CargoResult<()> {
let old_fingerprint_short = paths::read(loc)?;

// update the mtime so other cleaners know we used it
let t = FileTime::from_system_time(SystemTime::now());
filetime::set_file_times(loc, t, t)?;
if mtime_on_use {
// update the mtime so other cleaners know we used it
let t = FileTime::from_system_time(SystemTime::now());
filetime::set_file_times(loc, t, t)?;
}

let new_hash = new_fingerprint.hash();

Expand Down
2 changes: 2 additions & 0 deletions src/cargo/core/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ pub struct CliUnstable {
pub package_features: bool,
pub advanced_env: bool,
pub config_profile: bool,
pub mtime_on_use: bool,
}

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

Expand Down
40 changes: 26 additions & 14 deletions tests/testsuite/freshness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1193,7 +1193,7 @@ fn simple_deps_cleaner(mut dir: PathBuf, timestamp: filetime::FileTime) {
}

#[test]
fn simple_deps_cleaner_dose_not_rebuild() {
fn simple_deps_cleaner_does_not_rebuild() {
let p = project()
.file(
"Cargo.toml",
Expand All @@ -1211,8 +1211,11 @@ fn simple_deps_cleaner_dose_not_rebuild() {
.file("bar/src/lib.rs", "")
.build();

p.cargo("build").run();
p.cargo("build")
p.cargo("build -Z mtime-on-use")
.masquerade_as_nightly_cargo()
.run();
p.cargo("build -Z mtime-on-use")
.masquerade_as_nightly_cargo()
.env("RUSTFLAGS", "-C target-cpu=native")
.with_stderr(
"\
Expand All @@ -1228,19 +1231,22 @@ fn simple_deps_cleaner_dose_not_rebuild() {
if is_coarse_mtime() {
sleep_ms(1000);
}
// This dose not make new files, but it dose update the mtime.
p.cargo("build")
// This does not make new files, but it does update the mtime.
p.cargo("build -Z mtime-on-use")
.masquerade_as_nightly_cargo()
.env("RUSTFLAGS", "-C target-cpu=native")
.with_stderr("[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]")
.run();
simple_deps_cleaner(p.target_debug_dir(), timestamp);
// This should not recompile!
p.cargo("build")
p.cargo("build -Z mtime-on-use")
.masquerade_as_nightly_cargo()
.env("RUSTFLAGS", "-C target-cpu=native")
.with_stderr("[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]")
.run();
// But this should be cleaned and so need a rebuild
p.cargo("build")
p.cargo("build -Z mtime-on-use")
.masquerade_as_nightly_cargo()
.with_stderr(
"\
[COMPILING] bar v0.0.1 ([..])
Expand Down Expand Up @@ -1282,7 +1288,7 @@ fn fingerprint_cleaner(mut dir: PathBuf, timestamp: filetime::FileTime) {
}

#[test]
fn fingerprint_cleaner_dose_not_rebuild() {
fn fingerprint_cleaner_does_not_rebuild() {
let p = project()
.file(
"Cargo.toml",
Expand All @@ -1300,8 +1306,11 @@ fn fingerprint_cleaner_dose_not_rebuild() {
.file("bar/src/lib.rs", "")
.build();

p.cargo("build").run();
p.cargo("build")
p.cargo("build -Z mtime-on-use")
.masquerade_as_nightly_cargo()
.run();
p.cargo("build -Z mtime-on-use")
.masquerade_as_nightly_cargo()
.env("RUSTFLAGS", "-C target-cpu=native")
.with_stderr(
"\
Expand All @@ -1317,19 +1326,22 @@ fn fingerprint_cleaner_dose_not_rebuild() {
if is_coarse_mtime() {
sleep_ms(1000);
}
// This dose not make new files, but it dose update the mtime.
p.cargo("build")
// This does not make new files, but it does update the mtime.
p.cargo("build -Z mtime-on-use")
.masquerade_as_nightly_cargo()
.env("RUSTFLAGS", "-C target-cpu=native")
.with_stderr("[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]")
.run();
fingerprint_cleaner(p.target_debug_dir(), timestamp);
// This should not recompile!
p.cargo("build")
p.cargo("build -Z mtime-on-use")
.masquerade_as_nightly_cargo()
.env("RUSTFLAGS", "-C target-cpu=native")
.with_stderr("[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]")
.run();
// But this should be cleaned and so need a rebuild
p.cargo("build")
p.cargo("build -Z mtime-on-use")
.masquerade_as_nightly_cargo()
.with_stderr(
"\
[COMPILING] bar v0.0.1 ([..])
Expand Down

0 comments on commit 907c0fe

Please sign in to comment.