@@ -10,7 +10,7 @@ use std::io::IsTerminal;
1010use std:: path:: { Path , PathBuf , absolute} ;
1111use std:: process:: Command ;
1212use std:: str:: FromStr ;
13- use std:: sync:: OnceLock ;
13+ use std:: sync:: { Arc , Mutex , OnceLock } ;
1414use std:: { cmp, env, fs} ;
1515
1616use build_helper:: ci:: CiEnv ;
@@ -415,6 +415,9 @@ pub struct Config {
415415
416416 /// Command for visual diff display, e.g. `diff-tool --color=always`.
417417 pub compiletest_diff_tool : Option < String > ,
418+
419+ /// Cache for determining path modifications
420+ pub path_modification_cache : Arc < Mutex < HashMap < Vec < & ' static str > , PathFreshness > > > ,
418421}
419422
420423#[ derive( Clone , Debug , Default ) ]
@@ -3130,17 +3133,34 @@ impl Config {
31303133 }
31313134
31323135 /// Returns true if any of the `paths` have been modified locally.
3133- pub fn has_changes_from_upstream ( & self , paths : & [ & str ] ) -> bool {
3136+ pub fn has_changes_from_upstream ( & self , paths : & [ & ' static str ] ) -> bool {
31343137 match self . check_path_modifications ( paths) {
31353138 PathFreshness :: LastModifiedUpstream { .. } => false ,
31363139 PathFreshness :: HasLocalModifications { .. } | PathFreshness :: MissingUpstream => true ,
31373140 }
31383141 }
31393142
31403143 /// Checks whether any of the given paths have been modified w.r.t. upstream.
3141- pub fn check_path_modifications ( & self , paths : & [ & str ] ) -> PathFreshness {
3142- check_path_modifications ( Some ( & self . src ) , & self . git_config ( ) , paths, CiEnv :: current ( ) )
3144+ pub fn check_path_modifications ( & self , paths : & [ & ' static str ] ) -> PathFreshness {
3145+ // Checking path modifications through git can be relatively expensive (>100ms).
3146+ // We do not assume that the sources would change during bootstrap's execution,
3147+ // so we can cache the results here.
3148+ // Note that we do not use a static variable for the cache, because it would cause problems
3149+ // in tests that create separate `Config` instsances.
3150+ self . path_modification_cache
3151+ . lock ( )
31433152 . unwrap ( )
3153+ . entry ( paths. to_vec ( ) )
3154+ . or_insert_with ( || {
3155+ check_path_modifications (
3156+ Some ( & self . src ) ,
3157+ & self . git_config ( ) ,
3158+ paths,
3159+ CiEnv :: current ( ) ,
3160+ )
3161+ . unwrap ( )
3162+ } )
3163+ . clone ( )
31443164 }
31453165}
31463166
0 commit comments