diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2022-04-18 14:39:13 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2022-04-19 04:12:34 +0200 |
commit | 950a84c337f317388cf39a3820125e049c598b8d (patch) | |
tree | a5c095027d5bf81bf8a33b745ad2ea3be2219771 | |
parent | 77fc9816696ebed3cc8685a8fdee464799f2a157 (diff) |
Optimize header cache some more by storing hash in key
-rw-r--r-- | libbuild2/cc/compile-rule.cxx | 22 | ||||
-rw-r--r-- | libbuild2/cc/module.hxx | 24 |
2 files changed, 42 insertions, 4 deletions
diff --git a/libbuild2/cc/compile-rule.cxx b/libbuild2/cc/compile-rule.cxx index 2faa711..c72c94c 100644 --- a/libbuild2/cc/compile-rule.cxx +++ b/libbuild2/cc/compile-rule.cxx @@ -2906,7 +2906,10 @@ namespace build2 // First check the cache. // - if (fp.absolute ()) + config_module::header_key hk; + + bool e (fp.absolute ()); + if (e) { if (!norm) { @@ -2914,14 +2917,19 @@ namespace build2 norm = true; } + hk.file = move (fp); + hk.hash = hash<path> () (hk.file); + slock l (hc.header_map_mutex); - auto i (hc.header_map.find (fp)); + auto i (hc.header_map.find (hk)); if (i != hc.header_map.end ()) { //cache_hit.fetch_add (1, memory_order_relaxed); return make_pair (i->second, false); } + fp = move (hk.file); + //cache_mis.fetch_add (1, memory_order_relaxed); } @@ -2957,10 +2965,18 @@ namespace build2 // if (r.first != nullptr) { + hk.file = move (fp); + + // Calculate the hash if we haven't yet and re-calculate it if the + // path has changed (header has been remapped). + // + if (!e || r.second) + hk.hash = hash<path> () (hk.file); + const file* f; { ulock l (hc.header_map_mutex); - auto p (hc.header_map.emplace (move (fp), r.first)); + auto p (hc.header_map.emplace (move (hk), r.first)); f = p.second ? nullptr : p.first->second; } diff --git a/libbuild2/cc/module.hxx b/libbuild2/cc/module.hxx index ee9349a..2a8611b 100644 --- a/libbuild2/cc/module.hxx +++ b/libbuild2/cc/module.hxx @@ -86,8 +86,30 @@ namespace build2 // sharing it for the entire weak amalgamation. // public: + // Keep the hash in the key. This way we can compute it outside of the + // lock. + // + struct header_key + { + path file; + size_t hash; + + friend bool + operator== (const header_key& x, const header_key& y) + { + return x.file == y.file; // Note: hash was already compared. + } + }; + + struct header_key_hasher + { + size_t operator() (const header_key& k) const {return k.hash;} + }; + mutable shared_mutex header_map_mutex; - mutable std::unordered_map<path, const file*> header_map; + mutable std::unordered_map<header_key, + const file*, + header_key_hasher> header_map; private: // Defined in gcc.cxx. |