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 <thiago.macieira@intel.com>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
bb10
Marc Mutz 2024-02-07 11:56:38 +01:00
parent 9a0098f4b3
commit 8fc37349e3
1 changed files with 9 additions and 10 deletions

View File

@ -11,7 +11,6 @@
#include <qfile.h>
#include <qfileinfo.h>
#include <qjsondocument.h>
#include <qmap.h>
#include <qmutex.h>
#include <qoperatingsystemversion.h>
#include <qstringlist.h>
@ -30,6 +29,8 @@
#include <qtcore_tracepoints_p.h>
#include <QtCore/q20map.h>
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<QString, QLibraryPrivate *> LibraryMap;
typedef std::map<QString, QLibraryPrivate *> 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);