@@ -11,7 +11,7 @@ use std::io::IsTerminal;
11
11
use std:: path:: { Path , PathBuf , absolute} ;
12
12
use std:: process:: Command ;
13
13
use std:: str:: FromStr ;
14
- use std:: sync:: OnceLock ;
14
+ use std:: sync:: { Arc , Mutex , OnceLock } ;
15
15
use std:: { cmp, env, fs} ;
16
16
17
17
use build_helper:: ci:: CiEnv ;
@@ -422,6 +422,9 @@ pub struct Config {
422
422
pub compiletest_use_stage0_libtest : bool ,
423
423
424
424
pub is_running_on_ci : bool ,
425
+
426
+ /// Cache for determining path modifications
427
+ pub path_modification_cache : Arc < Mutex < HashMap < Vec < & ' static str > , PathFreshness > > > ,
425
428
}
426
429
427
430
#[ derive( Clone , Debug , Default ) ]
@@ -3294,17 +3297,34 @@ impl Config {
3294
3297
}
3295
3298
3296
3299
/// Returns true if any of the `paths` have been modified locally.
3297
- pub fn has_changes_from_upstream ( & self , paths : & [ & str ] ) -> bool {
3300
+ pub fn has_changes_from_upstream ( & self , paths : & [ & ' static str ] ) -> bool {
3298
3301
match self . check_path_modifications ( paths) {
3299
3302
PathFreshness :: LastModifiedUpstream { .. } => false ,
3300
3303
PathFreshness :: HasLocalModifications { .. } | PathFreshness :: MissingUpstream => true ,
3301
3304
}
3302
3305
}
3303
3306
3304
3307
/// Checks whether any of the given paths have been modified w.r.t. upstream.
3305
- pub fn check_path_modifications ( & self , paths : & [ & str ] ) -> PathFreshness {
3306
- check_path_modifications ( Some ( & self . src ) , & self . git_config ( ) , paths, CiEnv :: current ( ) )
3308
+ pub fn check_path_modifications ( & self , paths : & [ & ' static str ] ) -> PathFreshness {
3309
+ // Checking path modifications through git can be relatively expensive (>100ms).
3310
+ // We do not assume that the sources would change during bootstrap's execution,
3311
+ // so we can cache the results here.
3312
+ // Note that we do not use a static variable for the cache, because it would cause problems
3313
+ // in tests that create separate `Config` instsances.
3314
+ self . path_modification_cache
3315
+ . lock ( )
3307
3316
. unwrap ( )
3317
+ . entry ( paths. to_vec ( ) )
3318
+ . or_insert_with ( || {
3319
+ check_path_modifications (
3320
+ Some ( & self . src ) ,
3321
+ & self . git_config ( ) ,
3322
+ paths,
3323
+ CiEnv :: current ( ) ,
3324
+ )
3325
+ . unwrap ( )
3326
+ } )
3327
+ . clone ( )
3308
3328
}
3309
3329
3310
3330
/// Checks if the given target is the same as the host target.
0 commit comments