From f7a245b2b6091ef3a5e1193423c7fbbd6fe6a538 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 15 Dec 2020 09:25:19 +0200 Subject: Cache more results of executing programs (compilers, etc) --- libbuild2/bin/guess.cxx | 109 +++++++++++++++++++++++++++++++++++++----------- libbuild2/bin/guess.hxx | 6 +-- libbuild2/bin/init.cxx | 51 ++++++++++------------ 3 files changed, 111 insertions(+), 55 deletions(-) (limited to 'libbuild2/bin') diff --git a/libbuild2/bin/guess.cxx b/libbuild2/bin/guess.cxx index 21936d9..9f15030 100644 --- a/libbuild2/bin/guess.cxx +++ b/libbuild2/bin/guess.cxx @@ -54,7 +54,7 @@ namespace build2 { process_path r ( run_try_search (prog, - true /* init */, + false /* init (cached) */, dir_path () /* fallback */, true /* path_only */, paths)); @@ -80,14 +80,33 @@ namespace build2 dr << info << "use " << var << " to override"; }); - return run_search (prog, true, dir_path (), true); + return run_search (prog, false, dir_path (), true); } - ar_info + // Extracting ar/ranlib information requires running them which can become + // expensive if done repeatedly. So we cache the result. + // + static global_cache ar_cache; + + const ar_info& guess_ar (const path& ar, const path* rl, const char* paths) { tracer trace ("bin::guess_ar"); + // First check the cache. + // + string key; + { + sha256 cs; + cs.append (ar.string ()); + if (rl != nullptr) cs.append (rl->string ()); + if (paths != nullptr) cs.append (paths); + key = cs.string (); + + if (const ar_info* r = ar_cache.find (key)) + return *r; + } + guess_result arr, rlr; process_path arp (search (ar, paths, "config.bin.ar")); @@ -307,24 +326,43 @@ namespace build2 fail << "unable to guess " << *rl << " signature"; } - return ar_info { - move (arp), - move (arr.id), - move (arr.signature), - move (arr.checksum), - move (*arr.version), - - move (rlp), - move (rlr.id), - move (rlr.signature), - move (rlr.checksum)}; + return ar_cache.insert (move (key), + ar_info { + move (arp), + move (arr.id), + move (arr.signature), + move (arr.checksum), + move (*arr.version), + + move (rlp), + move (rlr.id), + move (rlr.signature), + move (rlr.checksum)}); } - ld_info + // Extracting ld information requires running it which can become + // expensive if done repeatedly. So we cache the result. + // + static global_cache ld_cache; + + const ld_info& guess_ld (const path& ld, const char* paths) { tracer trace ("bin::guess_ld"); + // First check the cache. + // + string key; + { + sha256 cs; + cs.append (ld.string ()); + if (paths != nullptr) cs.append (paths); + key = cs.string (); + + if (const ld_info* r = ld_cache.find (key)) + return *r; + } + guess_result r; process_path pp (search (ld, paths, "config.bin.ld")); @@ -484,19 +522,38 @@ namespace build2 if (r.empty ()) fail << "unable to guess " << ld << " signature"; - return ld_info { - move (pp), - move (r.id), - move (r.signature), - move (r.checksum), - move (r.version)}; + return ld_cache.insert (move (key), + ld_info { + move (pp), + move (r.id), + move (r.signature), + move (r.checksum), + move (r.version)}); } - rc_info + // Extracting rc information requires running it which can become + // expensive if done repeatedly. So we cache the result. + // + static global_cache rc_cache; + + const rc_info& guess_rc (const path& rc, const char* paths) { tracer trace ("bin::guess_rc"); + // First check the cache. + // + string key; + { + sha256 cs; + cs.append (rc.string ()); + if (paths != nullptr) cs.append (paths); + key = cs.string (); + + if (const rc_info* r = rc_cache.find (key)) + return *r; + } + guess_result r; process_path pp (search (rc, paths, "config.bin.rc")); @@ -575,8 +632,12 @@ namespace build2 if (r.empty ()) fail << "unable to guess " << rc << " signature"; - return rc_info { - move (pp), move (r.id), move (r.signature), move (r.checksum)}; + return rc_cache.insert (move (key), + rc_info { + move (pp), + move (r.id), + move (r.signature), + move (r.checksum)}); } } } diff --git a/libbuild2/bin/guess.hxx b/libbuild2/bin/guess.hxx index 27bb5ed..9a63fa1 100644 --- a/libbuild2/bin/guess.hxx +++ b/libbuild2/bin/guess.hxx @@ -45,7 +45,7 @@ namespace build2 // The ranlib path can be NULL, in which case no ranlib guessing will be // attemplated and the returned ranlib_* members will be left empty. // - ar_info + const ar_info& guess_ar (const path& ar, const path* ranlib, const char* paths); // ld information. @@ -85,7 +85,7 @@ namespace build2 optional version; }; - ld_info + const ld_info& guess_ld (const path& ld, const char* paths); // rc information. @@ -110,7 +110,7 @@ namespace build2 string checksum; }; - rc_info + const rc_info& guess_rc (const path& rc, const char* paths); } } diff --git a/libbuild2/bin/init.cxx b/libbuild2/bin/init.cxx index 49ba518..6d2d2c2 100644 --- a/libbuild2/bin/init.cxx +++ b/libbuild2/bin/init.cxx @@ -683,7 +683,7 @@ namespace build2 nullptr, config::save_default_commented))); - ar_info ari (guess_ar (ar, ranlib, pat.paths)); + const ar_info& ari (guess_ar (ar, ranlib, pat.paths)); // If this is a configuration with new values, then print the report // at verbosity level 2 and up (-v). @@ -723,33 +723,28 @@ namespace build2 } rs.assign ("bin.ar.path") = - process_path_ex (move (ari.ar_path), "ar", ari.ar_checksum); - rs.assign ("bin.ar.id") = move (ari.ar_id); - rs.assign ("bin.ar.signature") = move (ari.ar_signature); - rs.assign ("bin.ar.checksum") = move (ari.ar_checksum); + process_path_ex (ari.ar_path, "ar", ari.ar_checksum); + rs.assign ("bin.ar.id") = ari.ar_id; + rs.assign ("bin.ar.signature") = ari.ar_signature; + rs.assign ("bin.ar.checksum") = ari.ar_checksum; { - semantic_version& v (ari.ar_version); + const semantic_version& v (ari.ar_version); rs.assign ("bin.ar.version") = v.string (); rs.assign ("bin.ar.version.major") = v.major; rs.assign ("bin.ar.version.minor") = v.minor; rs.assign ("bin.ar.version.patch") = v.patch; - rs.assign ("bin.ar.version.build") = move (v.build); + rs.assign ("bin.ar.version.build") = v.build; } if (ranlib != nullptr) { rs.assign ("bin.ranlib.path") = - process_path_ex (move (ari.ranlib_path), - "ranlib", - ari.ranlib_checksum); - rs.assign ("bin.ranlib.id") = - move (ari.ranlib_id); - rs.assign ("bin.ranlib.signature") = - move (ari.ranlib_signature); - rs.assign ("bin.ranlib.checksum") = - move (ari.ranlib_checksum); + process_path_ex (ari.ranlib_path, "ranlib", ari.ranlib_checksum); + rs.assign ("bin.ranlib.id") = ari.ranlib_id; + rs.assign ("bin.ranlib.signature") = ari.ranlib_signature; + rs.assign ("bin.ranlib.checksum") = ari.ranlib_checksum; } } @@ -826,7 +821,7 @@ namespace build2 path (apply_pattern (ld_d, pat.pattern)), config::save_default_commented))); - ld_info ldi (guess_ld (ld, pat.paths)); + const ld_info& ldi (guess_ld (ld, pat.paths)); // If this is a configuration with new values, then print the report // at verbosity level 2 and up (-v). @@ -859,20 +854,20 @@ namespace build2 } rs.assign ("bin.ld.path") = - process_path_ex (move (ldi.path), "ld", ldi.checksum); - rs.assign ("bin.ld.id") = move (ldi.id); - rs.assign ("bin.ld.signature") = move (ldi.signature); - rs.assign ("bin.ld.checksum") = move (ldi.checksum); + process_path_ex (ldi.path, "ld", ldi.checksum); + rs.assign ("bin.ld.id") = ldi.id; + rs.assign ("bin.ld.signature") = ldi.signature; + rs.assign ("bin.ld.checksum") = ldi.checksum; if (ldi.version) { - semantic_version& v (*ldi.version); + const semantic_version& v (*ldi.version); rs.assign ("bin.ld.version") = v.string (); rs.assign ("bin.ld.version.major") = v.major; rs.assign ("bin.ld.version.minor") = v.minor; rs.assign ("bin.ld.version.patch") = v.patch; - rs.assign ("bin.ld.version.build") = move (v.build); + rs.assign ("bin.ld.version.build") = v.build; } } @@ -979,7 +974,7 @@ namespace build2 path (apply_pattern (rc_d, pat.pattern)), config::save_default_commented))); - rc_info rci (guess_rc (rc, pat.paths)); + const rc_info& rci (guess_rc (rc, pat.paths)); // If this is a configuration with new values, then print the report // at verbosity level 2 and up (-v). @@ -994,10 +989,10 @@ namespace build2 } rs.assign ("bin.rc.path") = - process_path_ex (move (rci.path), "rc", rci.checksum); - rs.assign ("bin.rc.id") = move (rci.id); - rs.assign ("bin.rc.signature") = move (rci.signature); - rs.assign ("bin.rc.checksum") = move (rci.checksum); + process_path_ex (rci.path, "rc", rci.checksum); + rs.assign ("bin.rc.id") = rci.id; + rs.assign ("bin.rc.signature") = rci.signature; + rs.assign ("bin.rc.checksum") = rci.checksum; } return true; -- cgit v1.1