summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qmetatype.h
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2022-06-17 23:32:33 -0700
committerThiago Macieira <thiago.macieira@intel.com>2022-06-28 15:07:41 -0700
commitc474825945a418ae9d8494c80b6803b6279e0cf5 (patch)
treeb0a1fe0fd8134f64ce4f81f2911a88218ee61af7 /src/corelib/kernel/qmetatype.h
parentdbf58407cb7f87b8d75ffd4e8af1393e80f30873 (diff)
QMetaType: move the built-in QMetaTypeInterfaces to read-only segments
The presence of the mutable causes the const object to lose its constness, so declaring as const wasn't helpful. But we can't drop the const wholesale for MSVC right now because it mangles the variable's type in the external name. For all other compilers, we drop it for user-defined types, which is a no-op but is semantically correct because QMetaType needs to modify those objects. Aside from a few const_cast (marked with comments), nothing else changes. For types with built-in type IDs, however, the QMetaTypeInterface is now fully const... or would be if it weren't full of relocations. It does move the lot from the .data section to the .data.rel.ro section. After this change, QtCore and QtGui have: QtCore QtGui .data.rel.ro 57 23 .data, exported 17 39 .data, private 94 193 sizeof(QtPrivate::QMetaTypeInterface) = 112 on 64-bit platforms (but GCC issues ".align 32", so they effectively occupy 128 bytes) Change-Id: Id0fb9ab0089845ee8843fffd16f9a35bfafebf77 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/corelib/kernel/qmetatype.h')
-rw-r--r--src/corelib/kernel/qmetatype.h25
1 files changed, 23 insertions, 2 deletions
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index a2639c1dfa..82d799ac41 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -225,6 +225,20 @@ struct QMetaObject;
namespace QtPrivate
{
+class QMetaTypeInterface;
+
+// MSVC is the only supported compiler that includes the type of a variable in
+// its mangled form, so it's not binary-compatible to drop the const in
+// QMetaTypeInterfaceWrapper::metaType for it, which means we must keep the
+// mutable field until Qt 7.
+#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) || defined(QT_BOOTSTRAPPED) || !defined(Q_CC_MSVC)
+# define QMTI_MUTABLE
+using NonConstMetaTypeInterface = QMetaTypeInterface;
+#else
+# define QMTI_MUTABLE mutable
+using NonConstMetaTypeInterface = const QMetaTypeInterface;
+#endif
+
class QMetaTypeInterface
{
public:
@@ -232,7 +246,7 @@ public:
ushort alignment;
uint size;
uint flags;
- mutable QBasicAtomicInt typeId;
+ QMTI_MUTABLE QBasicAtomicInt typeId;
using MetaObjectFn = const QMetaObject *(*)(const QMetaTypeInterface *);
MetaObjectFn metaObjectFn;
@@ -261,6 +275,7 @@ public:
using LegacyRegisterOp = void (*)();
LegacyRegisterOp legacyRegisterOp;
};
+#undef QMTI_MUTABLE
/*!
This template is used for implicit conversion from type From to type To.
@@ -2326,7 +2341,13 @@ public:
template<typename T>
struct QMetaTypeInterfaceWrapper
{
- static inline constexpr const QMetaTypeInterface metaType = {
+ // if the type ID for T is known at compile-time, then we can declare
+ // the QMetaTypeInterface object const; otherwise, we declare it as
+ // non-const and the .typeId is updated by QMetaType::idHelper().
+ static constexpr bool IsConstMetaTypeInterface = !!BuiltinMetaType<T>::value;
+ using InterfaceType = std::conditional_t<IsConstMetaTypeInterface, const QMetaTypeInterface, NonConstMetaTypeInterface>;
+
+ static inline InterfaceType metaType = {
/*.revision=*/ 0,
/*.alignment=*/ alignof(T),
/*.size=*/ sizeof(T),