From 8fc37349e32629c8cf84eae97e2e9d80b194de21 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 7 Feb 2024 11:56:38 +0100 Subject: [PATCH] QLibraryStore: cut out the QMap middle-man In Qt 6, QMap is just a shared pointer to a std::map. QLibraryStore::libraryMap is never copied, though, so the implicit sharing that QMap adds on top of std::map is useless. Use the underlying std::map directly. Yes, the std::map API is a bit raw around the edges (std::pair value_type), but we're professionals here. This one saves more than 3.7KiB in TEXT size on optimized AMD64 GCC 11 C++20 Linux builds. As a drive-by, port iterator- to range-based loops, and take advantage of loop variables being real references now. Change-Id: I1a8970b21e34a69d88a122f31699a51fd982feb9 Reviewed-by: Thiago Macieira Reviewed-by: Qt CI Bot --- src/corelib/plugin/qlibrary.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp index 622b244d19..a3ef8e3c52 100644 --- a/src/corelib/plugin/qlibrary.cpp +++ b/src/corelib/plugin/qlibrary.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -30,6 +29,8 @@ #include +#include + QT_BEGIN_NAMESPACE using namespace Qt::StringLiterals; @@ -321,7 +322,7 @@ private: static inline QLibraryStore *instance(); // all members and instance() are protected by qt_library_mutex - typedef QMap LibraryMap; + typedef std::map LibraryMap; LibraryMap libraryMap; }; @@ -341,9 +342,7 @@ inline void QLibraryStore::cleanup() return; // find any libraries that are still loaded but have a no one attached to them - LibraryMap::Iterator it = data->libraryMap.begin(); - for (; it != data->libraryMap.end(); ++it) { - QLibraryPrivate *lib = it.value(); + for (auto &[_, lib] : data->libraryMap) { if (lib->libraryRefCount.loadRelaxed() == 1) { if (lib->libraryUnloadCount.loadRelaxed() > 0) { Q_ASSERT(lib->pHnd.loadRelaxed()); @@ -357,14 +356,13 @@ inline void QLibraryStore::cleanup() lib->unload(); #endif } - delete lib; - it.value() = nullptr; + delete std::exchange(lib, nullptr); } } // dump all objects that remain if (lcDebugLibrary().isDebugEnabled()) { - for (QLibraryPrivate *lib : std::as_const(data->libraryMap)) { + for (auto &[_, lib] : data->libraryMap) { if (lib) qDebug(lcDebugLibrary) << "On QtCore unload," << lib->fileName << "was leaked, with" @@ -440,8 +438,9 @@ inline void QLibraryStore::releaseLibrary(QLibraryPrivate *lib) Q_ASSERT(lib->libraryUnloadCount.loadRelaxed() == 0); if (Q_LIKELY(data) && !lib->fileName.isEmpty()) { - qsizetype n = erase_if(data->libraryMap, [lib](LibraryMap::iterator it) { - return it.value() == lib; + using q20::erase_if; + const auto n = erase_if(data->libraryMap, [lib](const auto &e) { + return e.second == lib; }); Q_ASSERT_X(n, "~QLibrary", "Did not find this library in the library map"); Q_UNUSED(n);