summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qmetaobject.cpp
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2024-08-27 21:11:29 -0700
committerThiago Macieira <thiago.macieira@intel.com>2024-10-03 18:54:33 -0700
commit518fa1baf7bbc93b80567691d682ae64032fde76 (patch)
tree0a9d7088a20e0a633187e792e77edb1049b886f3 /src/corelib/kernel/qmetaobject.cpp
parent20b6ebea84997ecd70d37640f68232c60cc7231f (diff)
QMetaMethod: make some QByteArray-returning methods slightly faster
QByteArray::fromRawData() allocates no memory. Since we know that the data range is valid, there's no precondition violation either. But we can only use it for static-lifetime meta objects: those constructed by QMetaObjectBuilder or QtDBus may get deallocated, causing the strings obtained from them to crash on use if they do outlive (unlikely, but not impossible). To differentiate, this commit introduces a new flag to the QMetaObject header and makes use of it in those two places. Come Qt 7, we should change these functions to return QByteArrayView, making the retention of the data in a QByteArray the responsibility of the user. Making the change right now with #if or QTx_ONLY() is ugly, so this commit just leaves a comment. Change-Id: I5aaddbc7ce3fc7a70e15fffd29e276c79d5ef6e4 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Diffstat (limited to 'src/corelib/kernel/qmetaobject.cpp')
-rw-r--r--src/corelib/kernel/qmetaobject.cpp41
1 files changed, 27 insertions, 14 deletions
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index 48197c9d5c7..9e02098ccad 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -136,12 +136,23 @@ static inline QByteArrayView stringDataView(const QMetaObject *mo, int index)
return {string, qsizetype(length)};
}
-static inline QByteArray stringData(const QMetaObject *mo, int index)
+static inline QByteArray stringData(const QMetaObject *mo, QByteArrayView view)
{
- const auto view = stringDataView(mo, index);
+ if (QMetaObjectPrivate::get(mo)->flags & AllocatedMetaObject) {
+ // allocate memory, in case the meta object disappears
+ return view.toByteArray();
+ }
+
+ // don't allocate memory: we assume that the meta object remains loaded
+ // forever (modern C++ libraries can't be unloaded from memory anyway)
return QByteArray::fromRawData(view.data(), view.size());
}
+static inline QByteArray stringData(const QMetaObject *mo, int index)
+{
+ return stringData(mo, stringDataView(mo, index));
+}
+
static inline QByteArrayView typeNameFromTypeInfo(const QMetaObject *mo, uint typeInfo)
{
if (typeInfo & IsUnresolvedType)
@@ -178,7 +189,7 @@ public:
{ return static_cast<const QMetaMethodPrivate *>(q); }
inline QByteArray signature() const;
- inline QByteArray name() const;
+ inline QByteArrayView name() const noexcept;
inline int typesDataIndex() const;
inline const char *rawReturnTypeName() const;
inline int returnType() const;
@@ -189,10 +200,10 @@ public:
inline void getParameterTypes(int *types) const;
inline const QtPrivate::QMetaTypeInterface *returnMetaTypeInterface() const;
inline const QtPrivate::QMetaTypeInterface *const *parameterMetaTypeInterfaces() const;
- inline QByteArray parameterTypeName(int index) const;
+ inline QByteArrayView parameterTypeName(int index) const noexcept;
inline QList<QByteArray> parameterTypes() const;
inline QList<QByteArray> parameterNames() const;
- inline QByteArray tag() const;
+ inline const char *tag() const;
inline int ownMethodIndex() const;
inline int ownConstructorMethodIndex() const;
@@ -1908,10 +1919,10 @@ QByteArray QMetaMethodPrivate::signature() const
return result;
}
-QByteArray QMetaMethodPrivate::name() const
+QByteArrayView QMetaMethodPrivate::name() const noexcept
{
Q_ASSERT(priv(mobj->d.data)->revision >= 7);
- return stringData(mobj, data.name());
+ return stringDataView(mobj, data.name());
}
int QMetaMethodPrivate::typesDataIndex() const
@@ -2022,10 +2033,10 @@ void QMetaMethodPrivate::getParameterTypes(int *types) const
}
}
-QByteArray QMetaMethodPrivate::parameterTypeName(int index) const
+QByteArrayView QMetaMethodPrivate::parameterTypeName(int index) const noexcept
{
int paramsIndex = parametersDataIndex();
- return typeNameFromTypeInfo(mobj, mobj->d.data[paramsIndex + index]).toByteArray();
+ return typeNameFromTypeInfo(mobj, mobj->d.data[paramsIndex + index]);
}
QList<QByteArray> QMetaMethodPrivate::parameterTypes() const
@@ -2054,10 +2065,10 @@ QList<QByteArray> QMetaMethodPrivate::parameterNames() const
return list;
}
-QByteArray QMetaMethodPrivate::tag() const
+const char *QMetaMethodPrivate::tag() const
{
Q_ASSERT(priv(mobj->d.data)->revision >= 7);
- return stringData(mobj, data.tag());
+ return rawStringData(mobj, data.tag());
}
int QMetaMethodPrivate::ownMethodIndex() const
@@ -2099,7 +2110,8 @@ QByteArray QMetaMethod::name() const
{
if (!mobj)
return QByteArray();
- return QMetaMethodPrivate::get(this)->name();
+ // ### Qt 7: change the return type and make noexcept
+ return stringData(mobj, QMetaMethodPrivate::get(this)->name());
}
/*!
@@ -2228,7 +2240,8 @@ QByteArray QMetaMethod::parameterTypeName(int index) const
{
if (!mobj || index < 0 || index >= parameterCount())
return {};
- return QMetaMethodPrivate::get(this)->parameterTypeName(index);
+ // ### Qt 7: change the return type and make noexcept
+ return stringData(mobj, QMetaMethodPrivate::get(this)->parameterTypeName(index));
}
/*!
@@ -2284,7 +2297,7 @@ const char *QMetaMethod::tag() const
{
if (!mobj)
return nullptr;
- return QMetaMethodPrivate::get(this)->tag().constData();
+ return QMetaMethodPrivate::get(this)->tag();
}