Change representation of string data in the meta object
Don't store our string data as QByteArrayLiterals anymore, but revert back to simply storing them as an array of char* and offsets into that array. This is required to be able to inline size and begin into QByteArray itself. Once that change is done, we can then avoid creating copies of the string data again. Change-Id: I362a54581caefdb1b3da4a7ab922d37e2e63dc02 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>bb10
parent
746ab4bbd6
commit
e58b44d557
|
|
@ -154,19 +154,29 @@ QT_BEGIN_NAMESPACE
|
|||
static inline const QMetaObjectPrivate *priv(const uint* data)
|
||||
{ return reinterpret_cast<const QMetaObjectPrivate*>(data); }
|
||||
|
||||
static inline const char *rawStringData(const QMetaObject *mo, int index)
|
||||
{
|
||||
Q_ASSERT(priv(mo->d.data)->revision >= 7);
|
||||
uint offset = mo->d.stringdata[2*index];
|
||||
return reinterpret_cast<const char *>(mo->d.stringdata) + offset;
|
||||
}
|
||||
|
||||
static inline const QByteArray stringData(const QMetaObject *mo, int index)
|
||||
{
|
||||
Q_ASSERT(priv(mo->d.data)->revision >= 7);
|
||||
const QByteArrayDataPtr data = { const_cast<QByteArrayData*>(&mo->d.stringdata[index]) };
|
||||
Q_ASSERT(data.ptr->isStatic());
|
||||
Q_ASSERT(data.ptr->allocatedCapacity() == 0);
|
||||
Q_ASSERT(data.ptr->size >= 0);
|
||||
return data;
|
||||
uint offset = mo->d.stringdata[2*index];
|
||||
uint length = mo->d.stringdata[2*index + 1];
|
||||
const char *string = reinterpret_cast<const char *>(mo->d.stringdata) + offset;
|
||||
return QByteArray::fromRawData(string, length);
|
||||
}
|
||||
|
||||
static inline const char *rawStringData(const QMetaObject *mo, int index)
|
||||
static inline const char *rawTypeNameFromTypeInfo(const QMetaObject *mo, uint typeInfo)
|
||||
{
|
||||
return stringData(mo, index).data();
|
||||
if (typeInfo & IsUnresolvedType) {
|
||||
return rawStringData(mo, typeInfo & TypeNameIndexMask);
|
||||
} else {
|
||||
return QMetaType::typeName(typeInfo);
|
||||
}
|
||||
}
|
||||
|
||||
static inline QByteArray typeNameFromTypeInfo(const QMetaObject *mo, uint typeInfo)
|
||||
|
|
@ -180,16 +190,11 @@ static inline QByteArray typeNameFromTypeInfo(const QMetaObject *mo, uint typeIn
|
|||
}
|
||||
}
|
||||
|
||||
static inline const char *rawTypeNameFromTypeInfo(const QMetaObject *mo, uint typeInfo)
|
||||
{
|
||||
return typeNameFromTypeInfo(mo, typeInfo).constData();
|
||||
}
|
||||
|
||||
static inline int typeFromTypeInfo(const QMetaObject *mo, uint typeInfo)
|
||||
{
|
||||
if (!(typeInfo & IsUnresolvedType))
|
||||
return typeInfo;
|
||||
return QMetaType::type(stringData(mo, typeInfo & TypeNameIndexMask));
|
||||
return QMetaType::type(rawStringData(mo, typeInfo & TypeNameIndexMask));
|
||||
}
|
||||
|
||||
class QMetaMethodPrivate : public QMetaMethod
|
||||
|
|
@ -576,7 +581,7 @@ static bool methodMatch(const QMetaObject *m, int handle,
|
|||
if (int(m->d.data[handle + 1]) != argc)
|
||||
return false;
|
||||
|
||||
if (stringData(m, m->d.data[handle]) != name)
|
||||
if (rawStringData(m, m->d.data[handle]) != name)
|
||||
return false;
|
||||
|
||||
int paramsIndex = m->d.data[handle + 2] + 1;
|
||||
|
|
|
|||
|
|
@ -1103,13 +1103,13 @@ int QMetaStringTable::enter(const QByteArray &value)
|
|||
|
||||
int QMetaStringTable::preferredAlignment()
|
||||
{
|
||||
return alignof(QByteArrayData);
|
||||
return alignof(uint);
|
||||
}
|
||||
|
||||
// Returns the size (in bytes) required for serializing this string table.
|
||||
int QMetaStringTable::blobSize() const
|
||||
{
|
||||
int size = m_entries.size() * sizeof(QByteArrayData);
|
||||
int size = m_entries.size() * 2*sizeof(uint);
|
||||
Entries::const_iterator it;
|
||||
for (it = m_entries.constBegin(); it != m_entries.constEnd(); ++it)
|
||||
size += it.key().size() + 1;
|
||||
|
|
@ -1120,14 +1120,12 @@ static void writeString(char *out, int i, const QByteArray &str,
|
|||
const int offsetOfStringdataMember, int &stringdataOffset)
|
||||
{
|
||||
int size = str.size();
|
||||
qptrdiff offset = offsetOfStringdataMember + stringdataOffset
|
||||
- i * sizeof(QByteArrayData);
|
||||
const QByteArrayData data =
|
||||
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(size, offset);
|
||||
int offset = offsetOfStringdataMember + stringdataOffset;
|
||||
uint offsetLen[2] = { uint(offset), uint(size) };
|
||||
|
||||
memcpy(out + i * sizeof(QByteArrayData), &data, sizeof(QByteArrayData));
|
||||
memcpy(out + 2 * i * sizeof(uint), &offsetLen, 2*sizeof(uint));
|
||||
|
||||
memcpy(out + offsetOfStringdataMember + stringdataOffset, str.constData(), size);
|
||||
memcpy(out + offset, str.constData(), size);
|
||||
out[offsetOfStringdataMember + stringdataOffset + size] = '\0';
|
||||
|
||||
stringdataOffset += size + 1;
|
||||
|
|
@ -1141,7 +1139,7 @@ void QMetaStringTable::writeBlob(char *out) const
|
|||
{
|
||||
Q_ASSERT(!(reinterpret_cast<quintptr>(out) & (preferredAlignment()-1)));
|
||||
|
||||
int offsetOfStringdataMember = m_entries.size() * sizeof(QByteArrayData);
|
||||
int offsetOfStringdataMember = m_entries.size() * 2*sizeof(uint);
|
||||
int stringdataOffset = 0;
|
||||
|
||||
// qt_metacast expects the first string in the string table to be the class name.
|
||||
|
|
@ -1282,10 +1280,10 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
|
|||
char *str = reinterpret_cast<char *>(buf + size);
|
||||
if (buf) {
|
||||
if (relocatable) {
|
||||
meta->d.stringdata = reinterpret_cast<const QByteArrayData *>((quintptr)size);
|
||||
meta->d.stringdata = reinterpret_cast<const uint *>((quintptr)size);
|
||||
meta->d.data = reinterpret_cast<uint *>((quintptr)pmetaSize);
|
||||
} else {
|
||||
meta->d.stringdata = reinterpret_cast<const QByteArrayData *>(str);
|
||||
meta->d.stringdata = reinterpret_cast<const uint *>(str);
|
||||
meta->d.data = reinterpret_cast<uint *>(data);
|
||||
}
|
||||
}
|
||||
|
|
@ -1553,7 +1551,7 @@ void QMetaObjectBuilder::fromRelocatableData(QMetaObject *output,
|
|||
quintptr dataOffset = (quintptr)dataMo->d.data;
|
||||
|
||||
output->d.superdata = superclass;
|
||||
output->d.stringdata = reinterpret_cast<const QByteArrayData *>(buf + stringdataOffset);
|
||||
output->d.stringdata = reinterpret_cast<const uint *>(buf + stringdataOffset);
|
||||
output->d.data = reinterpret_cast<const uint *>(buf + dataOffset);
|
||||
output->d.extradata = 0;
|
||||
output->d.relatedMetaObjects = 0;
|
||||
|
|
|
|||
|
|
@ -424,7 +424,7 @@ struct Q_CORE_EXPORT QMetaObject
|
|||
|
||||
struct { // private data
|
||||
SuperData superdata;
|
||||
const QByteArrayData *stringdata;
|
||||
const uint *stringdata;
|
||||
const uint *data;
|
||||
typedef void (*StaticMetacallFunction)(QObject *, QMetaObject::Call, int, void **);
|
||||
StaticMetacallFunction static_metacall;
|
||||
|
|
|
|||
|
|
@ -547,7 +547,7 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
|
|||
obj->d.relatedMetaObjects = 0;
|
||||
obj->d.static_metacall = 0;
|
||||
obj->d.extradata = 0;
|
||||
obj->d.stringdata = reinterpret_cast<const QByteArrayData *>(string_data);
|
||||
obj->d.stringdata = reinterpret_cast<const uint *>(string_data);
|
||||
obj->d.superdata = &QDBusAbstractInterface::staticMetaObject;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -236,7 +236,7 @@ void Generator::generateCode()
|
|||
//
|
||||
const int constCharArraySizeLimit = 65535;
|
||||
fprintf(out, "struct qt_meta_stringdata_%s_t {\n", qualifiedClassNameIdentifier.constData());
|
||||
fprintf(out, " QByteArrayData data[%d];\n", strings.size());
|
||||
fprintf(out, " const uint offsetsAndSize[%d];\n", strings.size()*2);
|
||||
{
|
||||
int stringDataLength = 0;
|
||||
int stringDataCounter = 0;
|
||||
|
|
@ -259,11 +259,8 @@ void Generator::generateCode()
|
|||
// stringdata.stringdata member, and 2) the stringdata.data index of the
|
||||
// QByteArrayData being defined. This calculation relies on the
|
||||
// QByteArrayData::data() implementation returning simply "this + offset".
|
||||
fprintf(out, "#define QT_MOC_LITERAL(idx, ofs, len) \\\n"
|
||||
" Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \\\n"
|
||||
" qptrdiff(offsetof(qt_meta_stringdata_%s_t, stringdata0) + ofs \\\n"
|
||||
" - idx * sizeof(QByteArrayData)) \\\n"
|
||||
" )\n",
|
||||
fprintf(out, "#define QT_MOC_LITERAL(ofs, len) \\\n"
|
||||
" uint(offsetof(qt_meta_stringdata_%s_t, stringdata0) + ofs), len \n",
|
||||
qualifiedClassNameIdentifier.constData());
|
||||
|
||||
fprintf(out, "static const qt_meta_stringdata_%s_t qt_meta_stringdata_%s = {\n",
|
||||
|
|
@ -273,7 +270,7 @@ void Generator::generateCode()
|
|||
int idx = 0;
|
||||
for (int i = 0; i < strings.size(); ++i) {
|
||||
const QByteArray &str = strings.at(i);
|
||||
fprintf(out, "QT_MOC_LITERAL(%d, %d, %d)", i, idx, str.length());
|
||||
fprintf(out, "QT_MOC_LITERAL(%d, %d)", idx, str.length());
|
||||
if (i != strings.size() - 1)
|
||||
fputc(',', out);
|
||||
const QByteArray comment = str.length() > 32 ? str.left(29) + "..." : str;
|
||||
|
|
@ -541,7 +538,7 @@ void Generator::generateCode()
|
|||
fprintf(out, " QMetaObject::SuperData::link<%s::staticMetaObject>(),\n", purestSuperClass.constData());
|
||||
else
|
||||
fprintf(out, " nullptr,\n");
|
||||
fprintf(out, " qt_meta_stringdata_%s.data,\n"
|
||||
fprintf(out, " qt_meta_stringdata_%s.offsetsAndSize,\n"
|
||||
" qt_meta_data_%s,\n", qualifiedClassNameIdentifier.constData(),
|
||||
qualifiedClassNameIdentifier.constData());
|
||||
if (hasStaticMetaCall)
|
||||
|
|
|
|||
|
|
@ -1702,9 +1702,10 @@ void tst_QMetaObjectBuilder::classNameFirstInStringData()
|
|||
builder.setClassName(QByteArrayLiteral("TestClass"));
|
||||
QMetaObject *mo = builder.toMetaObject();
|
||||
|
||||
QByteArrayDataPtr header;
|
||||
header.ptr = const_cast<QByteArrayData*>(mo->d.stringdata);
|
||||
QCOMPARE(QByteArray(header), QByteArrayLiteral("TestClass"));
|
||||
uint offset = mo->d.stringdata[0];
|
||||
uint len = mo->d.stringdata[1];
|
||||
QByteArray className(reinterpret_cast<const char *>(mo->d.stringdata) + offset, len);
|
||||
QCOMPARE(className, QByteArrayLiteral("TestClass"));
|
||||
|
||||
free(mo);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue