QGenericUnixTheme: reduce unnecessary relocations

Instead of static constexpr QL1SV objects (which force the compiler to
allocate storage for them and therefore cause relocations), use inline
functions or mere automatic objects (which don't).

We'd normally call the inline functions fooKey() { return "foo"_L1; },
but since one of them "foo"s ends with "Key" already, put them into a
namespace instead, the name of which is taken from the comment that
used to introduce the static constexpr objects in the old code.

For the QL1SVs in the ctor: port them to QStringLiterals, because
their only use is to pass them to a function taking const QString&, so
this saves allocations. There never was a need to make these objects
static, as constexpr would be enough to force the compiler to
constant-fold them.

Unlike my earlier advice about how to create an empty QString most
efficiently, don't keep using ""_L1, use u""_s. This is because
there's no shared empty QString in Qt 6 anymore. It might still make
sense to add a more light-weight way to create an empty QString,
esp. one which is not referencing local data, but QString::_empty, to
extend the lifetime of the payload until QtCore unload time, but that
is outside the scope of the current patch.

Difference:
  qgenericunixthemes.cpp.o:
- 0000000000000000 l     O .data.rel.ro.local     0000000000000010 QGenericUnixThemeDBusListener::QGenericUnixThemeDBusListener()::signal
- 0000000000000040 l     O .data.rel.ro.local     0000000000000010 QGenericUnixThemeDBusListener::QGenericUnixThemeDBusListener()::interface
- 0000000000000080 l     O .data.rel.ro.local     0000000000000010 QGenericUnixThemeDBusListener::QGenericUnixThemeDBusListener()::path
  00000000000000c0 l     O .data.rel.ro.local     0000000000000010 QGenericUnixThemeDBusListener::QGenericUnixThemeDBusListener()::service
  0000000000000000 l    d  .data.rel.ro.local._ZTV24QGenericUnixThemePrivate      0000000000000000 .data.rel.ro.local._ZTV24QGenericUnixThemePrivate
  0000000000000000 l    d  .data.rel.ro.local._ZTV16QKdeThemePrivate      0000000000000000 .data.rel.ro.local._ZTV16QKdeThemePrivate
  0000000000000000 l    d  .data.rel.ro.local._ZTV18QGnomeThemePrivate    0000000000000000 .data.rel.ro.local._ZTV18QGnomeThemePrivate
  0000000000000000 l    d  .data.rel.ro.local._ZN13QMetaSequence12MetaSequenceI5QListIN2Qt3KeyEEE5valueE  0000000000000000 .data.rel.ro.local._ZN13QMetaSequence12MetaSequenceI5QListIN2Qt3KeyEEE5valueE
  0000000000000000 l    d  .data.rel.ro.local     0000000000000000 .data.rel.ro.local
- 0000000000000000 l    d  .data.rel.ro.local._ZN29QGenericUnixThemeDBusListener6s_rootE  0000000000000000 .data.rel.ro.local._ZN29QGenericUnixThemeDBusListener6s_rootE
- 0000000000000000 l    d  .data.rel.ro.local._ZN29QGenericUnixThemeDBusListener9s_signalsE       0000000000000000 .data.rel.ro.local._ZN29QGenericUnixThemeDBusListener9s_signalsE
- 0000000000000000 l    d  .data.rel.ro.local._ZN29QGenericUnixThemeDBusListener9s_settingE       0000000000000000 .data.rel.ro.local._ZN29QGenericUnixThemeDBusListener9s_settingE
- 0000000000000000 l    d  .data.rel.ro.local._ZN29QGenericUnixThemeDBusListener10s_providerE     0000000000000000 .data.rel.ro.local._ZN29QGenericUnixThemeDBusListener10s_providerE
- 0000000000000000 l    d  .data.rel.ro.local._ZN29QGenericUnixThemeDBusListener9s_dbusKeyE       0000000000000000 .data.rel.ro.local._ZN29QGenericUnixThemeDBusListener9s_dbusKeyE
- 0000000000000000 l    d  .data.rel.ro.local._ZN29QGenericUnixThemeDBusListener14s_dbusLocationE 0000000000000000 .data.rel.ro.local._ZN29QGenericUnixThemeDBusListener14s_dbusLocationE
  0000000000000000 l    d  .data.rel.ro.local._ZN9QtPrivate25QMetaTypeInterfaceWrapperIvE8metaTypeE       0000000000000000 .data.rel.ro.local._ZN9QtPrivate25QMetaTypeInterfaceWrapperIvE8metaTypeE
  0000000000000000 u     O .data.rel.ro.local._ZN13QMetaSequence12MetaSequenceI5QListIN2Qt3KeyEEE5valueE  00000000000000d8 QMetaSequence::MetaSequence<QList<Qt::Key> >::value
  0000000000000000  w    O .data.rel.ro.local._ZTV24QGenericUnixThemePrivate      0000000000000020 .hidden vtable for QGenericUnixThemePrivate
  0000000000000000  w    O .data.rel.ro.local._ZTV18QGnomeThemePrivate    0000000000000020 .hidden vtable for QGnomeThemePrivate
  0000000000000000  w    O .data.rel.ro.local._ZTV16QKdeThemePrivate      0000000000000020 .hidden vtable for QKdeThemePrivate
- 0000000000000000 u     O .data.rel.ro.local._ZN29QGenericUnixThemeDBusListener6s_rootE  0000000000000010 .hidden QGenericUnixThemeDBusListener::s_root
- 0000000000000000 u     O .data.rel.ro.local._ZN29QGenericUnixThemeDBusListener9s_signalsE       0000000000000010 .hidden QGenericUnixThemeDBusListener::s_signals
- 0000000000000000 u     O .data.rel.ro.local._ZN29QGenericUnixThemeDBusListener14s_dbusLocationE 0000000000000010 .hidden QGenericUnixThemeDBusListener::s_dbusLocation
- 0000000000000000 u     O .data.rel.ro.local._ZN29QGenericUnixThemeDBusListener9s_dbusKeyE       0000000000000010 .hidden QGenericUnixThemeDBusListener::s_dbusKey
- 0000000000000000 u     O .data.rel.ro.local._ZN29QGenericUnixThemeDBusListener10s_providerE     0000000000000010 .hidden QGenericUnixThemeDBusListener::s_provider
- 0000000000000000 u     O .data.rel.ro.local._ZN29QGenericUnixThemeDBusListener9s_settingE       0000000000000010 .hidden QGenericUnixThemeDBusListener::s_setting
- 0000000000000000 u     O .data.rel.ro.local._ZN9QtPrivate25QMetaTypeInterfaceWrapperIvE8metaTypeE       0000000000000070 .hidden QtPrivate::QMetaTypeInterfaceWrapper<void>::metaType
  RELOCATION RECORDS FOR [.data.rel.ro.local._ZTV24QGenericUnixThemePrivate]:
  RELOCATION RECORDS FOR [.data.rel.ro.local._ZTV16QKdeThemePrivate]:
  RELOCATION RECORDS FOR [.data.rel.ro.local._ZTV18QGnomeThemePrivate]:
  RELOCATION RECORDS FOR [.data.rel.ro.local._ZN13QMetaSequence12MetaSequenceI5QListIN2Qt3KeyEEE5valueE]:
- RELOCATION RECORDS FOR [.data.rel.ro.local._ZN29QGenericUnixThemeDBusListener6s_rootE]:
- RELOCATION RECORDS FOR [.data.rel.ro.local._ZN29QGenericUnixThemeDBusListener9s_signalsE]:
- RELOCATION RECORDS FOR [.data.rel.ro.local._ZN29QGenericUnixThemeDBusListener9s_settingE]:
- RELOCATION RECORDS FOR [.data.rel.ro.local._ZN29QGenericUnixThemeDBusListener10s_providerE]:
- RELOCATION RECORDS FOR [.data.rel.ro.local._ZN29QGenericUnixThemeDBusListener9s_dbusKeyE]:
- RELOCATION RECORDS FOR [.data.rel.ro.local._ZN29QGenericUnixThemeDBusListener14s_dbusLocationE]:
  RELOCATION RECORDS FOR [.data.rel.ro.local._ZN9QtPrivate25QMetaTypeInterfaceWrapperIvE8metaTypeE]:

See
  https://stackoverflow.com/questions/19067010/finding-where-relocations-originate/19338343#19338343
for the script to generate this output.

See https://www.akkadia.org/drepper/dsohowto.pdf Section 1.6 for why
we care.

Amends 0328e4297e339de8a2acd84979c667936f6fadf8.

Pick-to: 6.8 6.5
Task-number: QTBUG-100536
Change-Id: I1fd65e3ed5bceeb2a49141834dbd12f4bf42cc8c
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
(cherry picked from commit 1370ecf293b258ba74a1187c5bbf8e1a192765e4)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Marc Mutz 2025-03-06 12:04:39 +01:00 committed by Qt Cherry-pick Bot
parent 72fddb0935
commit ece3fefdd0

View File

@ -181,14 +181,6 @@ private:
ChangeSignal() {}
};
// Json keys
static constexpr QLatin1StringView s_dbusLocation = QLatin1StringView("DBusLocation");
static constexpr QLatin1StringView s_dbusKey = QLatin1StringView("DBusKey");
static constexpr QLatin1StringView s_provider = QLatin1StringView("Provider");
static constexpr QLatin1StringView s_setting = QLatin1StringView("Setting");
static constexpr QLatin1StringView s_signals = QLatin1StringView("DbusSignals");
static constexpr QLatin1StringView s_root = QLatin1StringView("Qt.qpa.DBusSignals");
QFlatMap <DBusKey, ChangeSignal> m_signalMap;
void init(const QString &service, const QString &path,
@ -200,6 +192,17 @@ private:
void saveJson(const QString &fileName) const;
};
namespace {
namespace JsonKeys {
constexpr auto dbusLocation() { return "DBusLocation"_L1; }
constexpr auto dbusKey() { return "DBusKey"_L1; }
constexpr auto provider() { return "Provider"_L1; }
constexpr auto setting() { return "Setting"_L1; }
constexpr auto dbusSignals() { return "DbusSignals"_L1; }
constexpr auto root() { return "Qt.qpa.DBusSignals"_L1; }
} // namespace JsonKeys
}
QGenericUnixThemeDBusListener::QGenericUnixThemeDBusListener(const QString &service,
const QString &path, const QString &interface, const QString &signal)
{
@ -208,10 +211,10 @@ QGenericUnixThemeDBusListener::QGenericUnixThemeDBusListener(const QString &serv
QGenericUnixThemeDBusListener::QGenericUnixThemeDBusListener()
{
static constexpr QLatin1StringView service("");
static constexpr QLatin1StringView path("/org/freedesktop/portal/desktop");
static constexpr QLatin1StringView interface("org.freedesktop.portal.Settings");
static constexpr QLatin1StringView signal("SettingChanged");
const auto service = u""_s;
const auto path = u"/org/freedesktop/portal/desktop"_s;
const auto interface = u"org.freedesktop.portal.Settings"_s;
const auto signal = u"SettingChanged"_s;
init (service, path, interface, signal);
}
@ -273,26 +276,26 @@ void QGenericUnixThemeDBusListener::loadJson(const QString &fileName)
QJsonParseError error;
QJsonDocument doc = QJsonDocument::fromJson(file.readAll(), &error);
CHECK((error.error == QJsonParseError::NoError), error.errorString());
CHECK(doc.isObject(), "Parse Error: Expected root object" << s_root);
CHECK(doc.isObject(), "Parse Error: Expected root object" << JsonKeys::root());
const QJsonObject &root = doc.object();
CHECK(root.contains(s_root), "Parse Error: Expected root object" << s_root);
CHECK(root[s_root][s_signals].isArray(), "Parse Error: Expected array" << s_signals);
CHECK(root.contains(JsonKeys::root()), "Parse Error: Expected root object" << JsonKeys::root());
CHECK(root[JsonKeys::root()][JsonKeys::dbusSignals()].isArray(), "Parse Error: Expected array" << JsonKeys::dbusSignals());
const QJsonArray &sigs = root[s_root][s_signals].toArray();
CHECK((sigs.count() > 0), "Parse Error: Found empty array" << s_signals);
const QJsonArray &sigs = root[JsonKeys::root()][JsonKeys::dbusSignals()].toArray();
CHECK((sigs.count() > 0), "Parse Error: Found empty array" << JsonKeys::dbusSignals());
for (auto sig = sigs.constBegin(); sig != sigs.constEnd(); ++sig) {
CHECK(sig->isObject(), "Parse Error: Expected object array" << s_signals);
CHECK(sig->isObject(), "Parse Error: Expected object array" << JsonKeys::dbusSignals());
const QJsonObject &obj = sig->toObject();
CHECK(obj.contains(s_dbusLocation), "Parse Error: Expected key" << s_dbusLocation);
CHECK(obj.contains(s_dbusKey), "Parse Error: Expected key" << s_dbusKey);
CHECK(obj.contains(s_provider), "Parse Error: Expected key" << s_provider);
CHECK(obj.contains(s_setting), "Parse Error: Expected key" << s_setting);
const QString &location = obj[s_dbusLocation].toString();
const QString &key = obj[s_dbusKey].toString();
const QString &providerString = obj[s_provider].toString();
const QString &settingString = obj[s_setting].toString();
CHECK(obj.contains(JsonKeys::dbusLocation()), "Parse Error: Expected key" << JsonKeys::dbusLocation());
CHECK(obj.contains(JsonKeys::dbusKey()), "Parse Error: Expected key" << JsonKeys::dbusKey());
CHECK(obj.contains(JsonKeys::provider()), "Parse Error: Expected key" << JsonKeys::provider());
CHECK(obj.contains(JsonKeys::setting()), "Parse Error: Expected key" << JsonKeys::setting());
const QString &location = obj[JsonKeys::dbusLocation()].toString();
const QString &key = obj[JsonKeys::dbusKey()].toString();
const QString &providerString = obj[JsonKeys::provider()].toString();
const QString &settingString = obj[JsonKeys::setting()].toString();
PARSE(provider, Provider, providerString);
PARSE(setting, Setting, settingString);
const DBusKey dkey(location, key);
@ -336,18 +339,18 @@ void QGenericUnixThemeDBusListener::saveJson(const QString &fileName) const
const DBusKey &dkey = sig.key();
const ChangeSignal &csig = sig.value();
QJsonObject obj;
obj[s_dbusLocation] = dkey.location;
obj[s_dbusKey] = dkey.key;
obj[s_provider] = QLatin1StringView(QMetaEnum::fromType<Provider>()
obj[JsonKeys::dbusLocation()] = dkey.location;
obj[JsonKeys::dbusKey()] = dkey.key;
obj[JsonKeys::provider()] = QLatin1StringView(QMetaEnum::fromType<Provider>()
.valueToKey(static_cast<int>(csig.provider)));
obj[s_setting] = QLatin1StringView(QMetaEnum::fromType<Setting>()
obj[JsonKeys::setting()] = QLatin1StringView(QMetaEnum::fromType<Setting>()
.valueToKey(static_cast<int>(csig.setting)));
sigs.append(obj);
}
QJsonObject obj;
obj[s_signals] = sigs;
obj[JsonKeys::dbusSignals()] = sigs;
QJsonObject root;
root[s_root] = obj;
root[JsonKeys::root()] = obj;
QJsonDocument doc(root);
file.write(doc.toJson());
file.close();