Skip to content

Commit

Permalink
QVariant: Do not destroy trivial types
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
Inkane committed Jan 27, 2021
1 parent 00b759a commit bf7b1a2
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/corelib/kernel/qmetatype.h
Original file line number Diff line number Diff line change
Expand Up @@ -2220,7 +2220,7 @@ class QMetaTypeForType

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();
};
Expand Down
9 changes: 7 additions & 2 deletions src/corelib/kernel/qvariant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand Down

0 comments on commit bf7b1a2

Please sign in to comment.