libstdc++-v3/ChangeLog:

        * src/c++20/format.cc (remove_ref): New deleter type.
        (move_to_front): New function.
        (lru_cache): New unique_ptr array.
        (__with_encoding_conversion): Use LRU cache.
---

Tested x86_64-linux.

 libstdc++-v3/src/c++20/format.cc | 36 +++++++++++++++++++++++++++++---
 1 file changed, 33 insertions(+), 3 deletions(-)

diff --git a/libstdc++-v3/src/c++20/format.cc b/libstdc++-v3/src/c++20/format.cc
index ee91c291d38..302664b673d 100644
--- a/libstdc++-v3/src/c++20/format.cc
+++ b/libstdc++-v3/src/c++20/format.cc
@@ -283,6 +283,22 @@ __get_encoding_facet(const locale& loc)
   return static_cast<const __encoding*>(loc._M_impl->_M_facets[id]);
 }
 
+// Deleter for facets
+struct remove_ref {
+  void operator()(locale::facet* p) const { p->_M_remove_reference(); }
+};
+using Cache = array<unique_ptr<__encoding, remove_ref>, 3>;
+Cache lru_cache;
+mutex lru_cache_mx;
+
+void move_to_front(Cache::iterator it)
+{
+  while (it != lru_cache.begin())
+    {
+      --it;
+      it->swap(it[1]);
+    }
+}
 } // namespace
 
 locale
@@ -301,9 +317,23 @@ __with_encoding_conversion(const locale& loc)
      || locenc == text_encoding::unknown)
     return loc;
 
-  auto facetp = std::make_unique<__encoding>(locenc);
-  locale loc2(loc, facetp.get()); // FIXME: PR libstdc++/113704
-  facetp.release();
+  lock_guard<mutex> lock(lru_cache_mx);
+  auto it = lru_cache.begin(), end = lru_cache.end();
+  while (it != end && *it && (*it)->_M_enc != locenc)
+    ++it;
+
+  if (it == end || *it == nullptr) // Cache miss.
+    {
+      if (it == end) // Cache is full, replace the last entry.
+       --it;
+      it->reset(new __encoding(locenc, 1));
+    }
+
+  // Move *it to the front of the cache.
+  move_to_front(it);
+
+  locale loc2(loc, lru_cache[0].get()); // FIXME: PR libstdc++/113704
+
   // FIXME: Ideally we wouldn't need to reallocate this string again,
   // just don't delete[] it in the locale(locale, Facet*) constructor.
   if (const char* name = loc._M_impl->_M_names[0])
-- 
2.47.0

Reply via email to