diff options
author | Kent Hansen <kent.hansen@nokia.com> | 2012-03-05 10:22:37 +0100 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-03-13 12:58:48 +0100 |
commit | 7a5651b4f9fef530e1dc5516899c7f481f4480ef (patch) | |
tree | ab90013eb3087e6e2759d914f89bb01292790e0b /src/qml/qml/ftw | |
parent | 4dd4c442e15a155ff3784f28d6c1ebc68fe8382e (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.cpp | 147 | ||||
-rw-r--r-- | src/qml/qml/ftw/qfastmetabuilder_p.h | 74 | ||||
-rw-r--r-- | src/qml/qml/ftw/qqmlpool_p.h | 1 |
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 ¶meterNames, - 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 ¶meterNames, - 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 ¶meterNames = StringRef(), - const StringRef &type = StringRef()); - void setSignal(int index, const StringRef &signature, - const StringRef ¶meterNames = 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) {} |