aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/ftw
diff options
context:
space:
mode:
authorKent Hansen <kent.hansen@nokia.com>2012-03-05 10:22:37 +0100
committerQt by Nokia <qt-info@nokia.com>2012-03-13 12:58:48 +0100
commit7a5651b4f9fef530e1dc5516899c7f481f4480ef (patch)
treeab90013eb3087e6e2759d914f89bb01292790e0b /src/qml/qml/ftw
parent4dd4c442e15a155ff3784f28d6c1ebc68fe8382e (diff)
Make QFastMetaBuilder generate revision 7 meta-objects
Support for revision <= 6 will go away in Qt5. This commit updates QFMB to match the latest format generated by moc: - Store string table as an array of QByteArrayData (literals) - Store only the meta-method name, not the full signature - Don't store parameter names as a comma-delimited string - Store explicit information about parameters (count, types, names) Since the meta-data can now hold type ids > 256, there is no need to store the names of property/parameter types at all anymore. Change-Id: I487b14d22b2a92d9e6a9aa4e348f4bab181daff4 Reviewed-by: Aaron Kennedy <aaron.kennedy@nokia.com>
Diffstat (limited to 'src/qml/qml/ftw')
-rw-r--r--src/qml/qml/ftw/qfastmetabuilder.cpp147
-rw-r--r--src/qml/qml/ftw/qfastmetabuilder_p.h74
-rw-r--r--src/qml/qml/ftw/qqmlpool_p.h1
3 files changed, 139 insertions, 83 deletions
diff --git a/src/qml/qml/ftw/qfastmetabuilder.cpp b/src/qml/qml/ftw/qfastmetabuilder.cpp
index 00685f8b28..9d956054d9 100644
--- a/src/qml/qml/ftw/qfastmetabuilder.cpp
+++ b/src/qml/qml/ftw/qfastmetabuilder.cpp
@@ -79,7 +79,8 @@ static inline const QFastMetaBuilderHeader *header(const QByteArray &data)
{ return reinterpret_cast<const QFastMetaBuilderHeader*>(data.constData()); }
QFastMetaBuilder::QFastMetaBuilder()
-: m_zeroPtr(0), m_stringData(0), m_stringDataLength(0), m_stringDataAllocated(0)
+ : m_stringData(0), m_stringCount(0), m_stringDataLength(0),
+ m_stringCountAllocated(0), m_stringCountLoaded(0)
{
}
@@ -89,7 +90,8 @@ QFastMetaBuilder::~QFastMetaBuilder()
QFastMetaBuilder::StringRef QFastMetaBuilder::init(int classNameLength,
int propertyCount, int methodCount,
- int signalCount, int classInfoCount)
+ int signalCount, int classInfoCount,
+ int paramDataSize, int *paramIndex)
{
Q_ASSERT(m_data.isEmpty());
Q_ASSERT(classNameLength > 0);
@@ -97,20 +99,29 @@ QFastMetaBuilder::StringRef QFastMetaBuilder::init(int classNameLength,
Q_ASSERT(methodCount >= 0);
Q_ASSERT(signalCount >= 0);
Q_ASSERT(classInfoCount >= 0);
+ Q_ASSERT(paramDataSize >= 0);
+ Q_ASSERT((paramIndex != 0) || (methodCount + signalCount == 0));
int fieldCount = FMBHEADER_FIELD_COUNT +
HEADER_FIELD_COUNT +
propertyCount * (PROPERTY_FIELD_COUNT + PROPERTY_NOTIFY_FIELD_COUNT) +
methodCount * (METHOD_FIELD_COUNT) +
signalCount * (METHOD_FIELD_COUNT) +
+ paramDataSize +
classInfoCount * CLASSINFO_FIELD_COUNT;
+ // Ensure stringdata alignment (void*)
+ fieldCount += fieldCount % (sizeof(void*) / sizeof(uint));
- m_data.resize(fieldCount * sizeof(uint) + classNameLength + 1);
- m_stringData = m_data.data() + m_data.size() - classNameLength - 1;
+ m_stringCount = 2; // class name and zero string
m_stringDataLength = classNameLength + 1;
- m_stringDataAllocated = classNameLength + 1;
- m_stringData[classNameLength] = 0;
- m_zeroPtr = classNameLength;
+ m_data.resize(fieldCount * sizeof(uint) + m_stringCount * sizeof(QByteArrayData) + m_stringDataLength);
+ m_stringCountAllocated = m_stringCount;
+ m_stringData = reinterpret_cast<QByteArrayData *>(m_data.data() + fieldCount * sizeof(uint));
+
+ m_zeroString._b = this;
+ m_zeroString._i = 1;
+ m_zeroString._o = classNameLength;
+ m_zeroString._l = 0;
header(m_data)->fieldCount = fieldCount;
@@ -118,7 +129,7 @@ QFastMetaBuilder::StringRef QFastMetaBuilder::init(int classNameLength,
int dataIndex = HEADER_FIELD_COUNT;
- p->revision = 6;
+ p->revision = 7;
p->className = 0;
// Class infos
@@ -135,6 +146,8 @@ QFastMetaBuilder::StringRef QFastMetaBuilder::init(int classNameLength,
if (p->methodCount) {
p->methodData = dataIndex;
dataIndex += p->methodCount * METHOD_FIELD_COUNT;
+ *paramIndex = dataIndex;
+ dataIndex += paramDataSize;
} else {
p->methodData = 0;
}
@@ -160,6 +173,7 @@ QFastMetaBuilder::StringRef QFastMetaBuilder::init(int classNameLength,
StringRef className;
className._b = this;
+ className._i = 0;
className._o = 0;
className._l = classNameLength;
return className;
@@ -169,12 +183,16 @@ QFastMetaBuilder::StringRef QFastMetaBuilder::init(int classNameLength,
QFastMetaBuilder::StringRef QFastMetaBuilder::newString(int length)
{
Q_ASSERT(length > 0);
+ Q_ASSERT_X(m_stringCountLoaded == 0, Q_FUNC_INFO,
+ "All strings must be created before string loading begins");
StringRef sr;
sr._b = this;
+ sr._i = m_stringCount;
sr._o = m_stringDataLength;
sr._l = length;
+ ++m_stringCount;
m_stringDataLength += length + 1 /* for null terminator */;
return sr;
@@ -190,47 +208,24 @@ void QFastMetaBuilder::setClassInfo(int index, const StringRef &key, const Strin
uint *ptr = fieldPointer(m_data) + p->classInfoData + index * CLASSINFO_FIELD_COUNT;
// classinfo: key, value
- ptr[0] = key.offset(); ptr[1] = value.offset();
+ ptr[0] = key.index(); ptr[1] = value.index();
}
-void QFastMetaBuilder::setProperty(int index, const StringRef &name, const StringRef &type,
- QMetaType::Type mtype, PropertyFlag flags, int notifySignal)
+void QFastMetaBuilder::setProperty(int index, const StringRef &name, int type,
+ PropertyFlag flags, int notifySignal)
{
Q_ASSERT(!m_data.isEmpty());
Q_ASSERT(!name.isEmpty());
- Q_ASSERT(!type.isEmpty());
-
- QMetaObjectPrivate *p = priv(m_data);
- Q_ASSERT(index < p->propertyCount);
-
- uint *ptr = fieldPointer(m_data) + p->propertyData + index * PROPERTY_FIELD_COUNT;
- // properties: name, type, flags
- ptr[0] = name.offset();
- ptr[1] = type.offset();
- if (notifySignal == -1) {
- ptr[2] = mtype << 24;
- ptr[2] |= flags | Scriptable | Readable;
- *(fieldPointer(m_data) + p->propertyData + p->propertyCount * PROPERTY_FIELD_COUNT + index) = 0;
- } else {
- ptr[2] = mtype << 24;
- ptr[2] |= flags | Scriptable | Readable | Notify;
- *(fieldPointer(m_data) + p->propertyData + p->propertyCount * PROPERTY_FIELD_COUNT + index) = notifySignal;
- }
-}
-
-void QFastMetaBuilder::setProperty(int index, const StringRef &name, const StringRef &type,
- QFastMetaBuilder::PropertyFlag flags, int notifySignal)
-{
- Q_ASSERT(!m_data.isEmpty());
- Q_ASSERT(!name.isEmpty() && !type.isEmpty());
+ Q_ASSERT(type != 0);
+ Q_ASSERT(QMetaType::isRegistered(type));
QMetaObjectPrivate *p = priv(m_data);
Q_ASSERT(index < p->propertyCount);
uint *ptr = fieldPointer(m_data) + p->propertyData + index * PROPERTY_FIELD_COUNT;
// properties: name, type, flags
- ptr[0] = name.offset();
- ptr[1] = type.offset();
+ ptr[0] = name.index();
+ ptr[1] = type;
if (notifySignal == -1) {
ptr[2] = flags | Scriptable | Readable;
*(fieldPointer(m_data) + p->propertyData + p->propertyCount * PROPERTY_FIELD_COUNT + index) = 0;
@@ -240,42 +235,72 @@ void QFastMetaBuilder::setProperty(int index, const StringRef &name, const Strin
}
}
-void QFastMetaBuilder::setSignal(int index, const StringRef &signature,
- const StringRef &parameterNames,
- const StringRef &type)
+void QFastMetaBuilder::setSignal(int index, const StringRef &name,
+ int paramIndex, int argc, const int *types,
+ const StringRef *parameterNames,
+ QMetaType::Type type)
{
Q_ASSERT(!m_data.isEmpty());
- Q_ASSERT(!signature.isEmpty());
+ Q_ASSERT(!name.isEmpty());
+ Q_ASSERT(QMetaType::isRegistered(type));
QMetaObjectPrivate *p = priv(m_data);
int mindex = metaObjectIndexForSignal(index);
uint *ptr = fieldPointer(m_data) + p->methodData + mindex * METHOD_FIELD_COUNT;
- // methods: signature, parameters, type, tag, flags
- ptr[0] = signature.offset();
- ptr[1] = parameterNames.isEmpty()?m_zeroPtr:parameterNames.offset();
- ptr[2] = type.isEmpty()?m_zeroPtr:type.offset();
- ptr[3] = m_zeroPtr;
+ // methods: name, arc, parameters, tag, flags
+ ptr[0] = name.index();
+ ptr[1] = argc;
+ ptr[2] = paramIndex;
+ ptr[3] = m_zeroString.index();
ptr[4] = AccessProtected | MethodSignal;
+
+ uint *paramPtr = fieldPointer(m_data) + paramIndex;
+ paramPtr[0] = type;
+ if (argc) {
+ Q_ASSERT(types != 0);
+ Q_ASSERT(parameterNames != 0);
+ for (int i = 0; i < argc; ++i) {
+ Q_ASSERT(types[i] != 0);
+ Q_ASSERT(QMetaType::isRegistered(types[i]));
+ paramPtr[1+i] = types[i];
+ paramPtr[1+argc+i] = parameterNames[i].index();
+ }
+ }
}
-void QFastMetaBuilder::setMethod(int index, const StringRef &signature,
- const StringRef &parameterNames,
- const StringRef &type)
+void QFastMetaBuilder::setMethod(int index, const StringRef &name,
+ int paramIndex, int argc, const int *types,
+ const StringRef *parameterNames,
+ QMetaType::Type type)
{
Q_ASSERT(!m_data.isEmpty());
- Q_ASSERT(!signature.isEmpty());
+ Q_ASSERT(!name.isEmpty());
+ Q_ASSERT(QMetaType::isRegistered(type));
QMetaObjectPrivate *p = priv(m_data);
int mindex = metaObjectIndexForMethod(index);
uint *ptr = fieldPointer(m_data) + p->methodData + mindex * METHOD_FIELD_COUNT;
- // methods: signature, parameters, type, tag, flags
- ptr[0] = signature.offset();
- ptr[1] = parameterNames.isEmpty()?m_zeroPtr:parameterNames.offset();
- ptr[2] = type.isEmpty()?m_zeroPtr:type.offset();
- ptr[3] = m_zeroPtr;
+ // methods: name, arc, parameters, tag, flags
+ ptr[0] = name.index();
+ ptr[1] = argc;
+ ptr[2] = paramIndex;
+ ptr[3] = m_zeroString.index();
ptr[4] = AccessProtected | MethodSlot;
+
+ uint *paramPtr = fieldPointer(m_data) + paramIndex;
+ paramPtr[0] = type;
+ if (argc) {
+ Q_ASSERT(types != 0);
+ Q_ASSERT(parameterNames != 0);
+ for (int i = 0; i < argc; ++i) {
+ Q_ASSERT(types[i] != 0);
+ Q_ASSERT(QMetaType::isRegistered(types[i]));
+ paramPtr[1+i] = types[i];
+ paramPtr[1+argc+i] = parameterNames[i].index();
+ }
+ }
}
int QFastMetaBuilder::metaObjectIndexForSignal(int index) const
@@ -296,10 +321,12 @@ int QFastMetaBuilder::metaObjectIndexForMethod(int index) const
void QFastMetaBuilder::allocateStringData()
{
- if (m_stringDataAllocated < m_stringDataLength) {
- m_data.resize(m_data.size() + m_stringDataLength - m_stringDataAllocated);
- m_stringDataAllocated = m_stringDataLength;
- m_stringData = m_data.data() + header(m_data)->fieldCount * sizeof(uint);
+ if (m_stringCountAllocated < m_stringCount) {
+ m_data.resize(header(m_data)->fieldCount * sizeof(uint)
+ + m_stringCount * sizeof(QByteArrayData) + m_stringDataLength);
+ m_stringCountAllocated = m_stringCount;
+ char *rawStringData = m_data.data() + header(m_data)->fieldCount * sizeof(uint);
+ m_stringData = reinterpret_cast<QByteArrayData *>(rawStringData);
}
}
diff --git a/src/qml/qml/ftw/qfastmetabuilder_p.h b/src/qml/qml/ftw/qfastmetabuilder_p.h
index c1f6a3de5c..16f7b6e749 100644
--- a/src/qml/qml/ftw/qfastmetabuilder_p.h
+++ b/src/qml/qml/ftw/qfastmetabuilder_p.h
@@ -80,13 +80,15 @@ public:
inline bool isEmpty() const;
inline QFastMetaBuilder *builder() const;
- inline int offset() const;
+ inline int index() const;
inline char *data();
inline int length() const;
+ inline void loadByteArrayData();
private:
friend class QFastMetaBuilder;
QFastMetaBuilder *_b;
+ int _i;
int _o;
int _l;
};
@@ -95,7 +97,8 @@ public:
// Returns class name
StringRef init(int classNameLength,
int propertyCount, int methodCount,
- int signalCount, int classInfoCount);
+ int signalCount, int classInfoCount,
+ int paramDataSize, int *paramIndex);
void setClassInfo(int index, const StringRef &key, const StringRef &value);
@@ -106,48 +109,55 @@ public:
Constant = 0x00000400,
Final = 0x00000800
};
- // void setProperty(int index, const StringRef &name, QMetaType::Type type, int notifySignal = -1);
- void setProperty(int index, const StringRef &name, const StringRef &type,
- QMetaType::Type mtype, PropertyFlag flags, int notifySignal = -1);
- void setProperty(int index, const StringRef &name, const StringRef &type,
+ void setProperty(int index, const StringRef &name, int type,
PropertyFlag flags, int notifySignal = -1);
- void setMethod(int index, const StringRef &signature,
- const StringRef &parameterNames = StringRef(),
- const StringRef &type = StringRef());
- void setSignal(int index, const StringRef &signature,
- const StringRef &parameterNames = StringRef(),
- const StringRef &type = StringRef());
+ void setMethod(int index, const StringRef &name, int paramIndex, int argc = 0,
+ const int *types = 0, const StringRef *parameterNames = 0,
+ QMetaType::Type type = QMetaType::Void);
+ void setSignal(int index, const StringRef &name, int paramIndex, int argc = 0,
+ const int *types = 0, const StringRef *parameterNames = 0,
+ QMetaType::Type type = QMetaType::Void);
int metaObjectIndexForSignal(int) const;
int metaObjectIndexForMethod(int) const;
- QByteArray toData() const { return m_data; }
+ QByteArray toData() const {
+ if (m_stringCountLoaded == m_stringCount - 1) {
+ // zero-string is lazily loaded last
+ const_cast<StringRef &>(m_zeroString).loadByteArrayData();
+ }
+ Q_ASSERT(m_stringCountLoaded == m_stringCount);
+ return m_data;
+ }
static void fromData(QMetaObject *, const QMetaObject *parent, const QByteArray &);
private:
friend struct StringRef;
QByteArray m_data;
- int m_zeroPtr;
+ StringRef m_zeroString;
void allocateStringData();
- char *m_stringData;
+ QByteArrayData *m_stringData;
+ int m_stringCount;
int m_stringDataLength;
- int m_stringDataAllocated;
+ int m_stringCountAllocated;
+ int m_stringCountLoaded;
};
QFastMetaBuilder::StringRef::StringRef()
-: _b(0), _o(0), _l(0)
+: _b(0), _i(0), _o(0), _l(0)
{
}
QFastMetaBuilder::StringRef::StringRef(const StringRef &o)
-: _b(o._b), _o(o._o), _l(o._l)
+: _b(o._b), _i(o._i), _o(o._o), _l(o._l)
{
}
QFastMetaBuilder::StringRef &QFastMetaBuilder::StringRef::operator=(const StringRef &o)
{
_b = o._b;
+ _i = o._i;
_o = o._o;
_l = o._l;
return *this;
@@ -163,17 +173,17 @@ QFastMetaBuilder *QFastMetaBuilder::StringRef::builder() const
return _b;
}
-int QFastMetaBuilder::StringRef::offset() const
+int QFastMetaBuilder::StringRef::index() const
{
- return _o;
+ return _i;
}
char *QFastMetaBuilder::StringRef::data()
{
Q_ASSERT(_b);
- if (_b->m_stringDataLength != _b->m_stringDataAllocated)
- _b->allocateStringData();
- return _b->m_stringData + _o;
+ if (_b->m_stringCountAllocated < _b->m_stringCount)
+ _b->allocateStringData();
+ return reinterpret_cast<char *>(&_b->m_stringData[_b->m_stringCount]) + _o;
}
int QFastMetaBuilder::StringRef::length() const
@@ -186,18 +196,36 @@ void QFastMetaBuilder::StringRef::load(const QHashedStringRef &str)
Q_ASSERT(str.utf8length() == _l);
str.writeUtf8(data());
*(data() + _l) = 0;
+ loadByteArrayData();
}
void QFastMetaBuilder::StringRef::load(const QByteArray &str)
{
Q_ASSERT(str.length() == _l);
strcpy(data(), str.constData());
+ loadByteArrayData();
}
void QFastMetaBuilder::StringRef::load(const char *str)
{
Q_ASSERT(strlen(str) == (uint)_l);
strcpy(data(), str);
+ loadByteArrayData();
+}
+
+void QFastMetaBuilder::StringRef::loadByteArrayData()
+{
+ if (_b->m_stringCountAllocated < _b->m_stringCount)
+ _b->allocateStringData();
+ Q_ASSERT(_b->m_stringCountLoaded < _b->m_stringCount);
+
+ int offsetofCstrings = _b->m_stringCount * sizeof(QByteArrayData);
+ qptrdiff offset = offsetofCstrings + _o - _i * sizeof(QByteArrayData);
+
+ const QByteArrayData bad = { Q_REFCOUNT_INITIALIZE_STATIC, _l, 0, 0, offset };
+ memcpy(&_b->m_stringData[_i], &bad, sizeof(QByteArrayData));
+
+ ++_b->m_stringCountLoaded;
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/ftw/qqmlpool_p.h b/src/qml/qml/ftw/qqmlpool_p.h
index e4fa03ce34..8e8f367890 100644
--- a/src/qml/qml/ftw/qqmlpool_p.h
+++ b/src/qml/qml/ftw/qqmlpool_p.h
@@ -132,6 +132,7 @@ public:
Q_ASSERT(index < m_length);
return m_data[index];
};
+ const T *data() const { return m_data; }
private:
friend class QQmlPool;
List(T *d, int l) : m_length(l), m_data(d) {}