summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2021-01-26 10:11:20 +0100
committerFabian Kosmale <fabian.kosmale@qt.io>2021-01-27 10:30:26 +0100
commitbf7b1a2aa83ce631879914cb98133e32b20f0104 (patch)
tree3c9a1f07070da16af8df5bd8f03a3fe3633d2475 /src/corelib
parent00b759a8d06dbec42232b1b8748c0725da7ced00 (diff)
QVariant: Do not destroy trivial types
perf indicates that we spend quite some time in ~QVariant in the referenced task's benchmark. With this patch, we significantly reduce the amount of work we do in the destructor for trivial types: Instead of calling an out-of-line function, which does a few checks and then does an indirect call through a function pointer to a do-nothing dtor before freeing the memory, we now simply free the memory. We achieve this by changing QMetaTypeInterface to leave the dtor function pointer null if the type is trivially destructible. Then, in QVariant we use the QMetaTypeInterface directly instead of going through QMetaType. Task-number: QTBUG-90560 Change-Id: Iaf87036710e1680323842e1ba703a5d3d0e5027a Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/kernel/qmetatype.h2
-rw-r--r--src/corelib/kernel/qvariant.cpp9
2 files changed, 8 insertions, 3 deletions
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index cd9b6ad6c6..67bcacd751 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -2220,7 +2220,7 @@ public:
static constexpr QMetaTypeInterface::DtorFn getDtor()
{
- if constexpr (std::is_destructible_v<S>)
+ if constexpr (std::is_destructible_v<S> && !std::is_trivially_destructible_v<S>)
return [](const QMetaTypeInterface *, void *addr) {
reinterpret_cast<S *>(addr)->~S();
};
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index c2ae5fb1dc..036ee42e05 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -270,10 +270,15 @@ static void customConstruct(QVariant::Private *d, const void *copy)
static void customClear(QVariant::Private *d)
{
+ auto iface = reinterpret_cast<QtPrivate::QMetaTypeInterface *>(d->packedType << 2);
+ if (!iface)
+ return;
if (!d->is_shared) {
- d->type().destruct(&d->data);
+ if (iface->dtor)
+ iface->dtor(iface, &d->data);
} else {
- d->type().destruct(d->data.shared->data());
+ if (iface->dtor)
+ iface->dtor(iface, d->data.shared->data());
QVariant::PrivateShared::free(d->data.shared);
}
}