aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2022-04-18 14:39:13 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2022-04-19 04:12:34 +0200
commit950a84c337f317388cf39a3820125e049c598b8d (patch)
treea5c095027d5bf81bf8a33b745ad2ea3be2219771
parent77fc9816696ebed3cc8685a8fdee464799f2a157 (diff)
Optimize header cache some more by storing hash in key
-rw-r--r--libbuild2/cc/compile-rule.cxx22
-rw-r--r--libbuild2/cc/module.hxx24
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.