diff options
-rw-r--r-- | src/qml/qml/qqmldata_p.h | 37 | ||||
-rw-r--r-- | src/qml/qml/qqmlengine.cpp | 40 |
2 files changed, 44 insertions, 33 deletions
diff --git a/src/qml/qml/qqmldata_p.h b/src/qml/qml/qqmldata_p.h index d9a69a9ca3..dce75c51aa 100644 --- a/src/qml/qml/qqmldata_p.h +++ b/src/qml/qml/qqmldata_p.h @@ -129,14 +129,16 @@ public: quint32 parentFrozen:1; quint32 dummy:21; - // When bindingBitsSize < 32, we store the binding bit flags inside - // bindingBitsValue. When we need more than 32 bits, we allocated + // When bindingBitsSize < sizeof(ptr), we store the binding bit flags inside + // bindingBitsValue. When we need more than sizeof(ptr) bits, we allocated // sufficient space and use bindingBits to point to it. int bindingBitsSize; + typedef quintptr BindingBitsType; union { - quint32 *bindingBits; - quint32 bindingBitsValue; + BindingBitsType *bindingBits; + BindingBitsType bindingBitsValue; }; + enum { MaxInlineBits = sizeof(BindingBitsType) * 8 }; struct NotifyList { quint64 connectionMask; @@ -236,6 +238,17 @@ private: mutable QQmlDataExtended *extendedData; void flushPendingBindingImpl(QQmlPropertyIndex index); + + Q_ALWAYS_INLINE bool hasBitSet(int bit) const + { + if (bindingBitsSize <= bit) + return false; + + if (bindingBitsSize == MaxInlineBits) + return bindingBitsValue & (BindingBitsType(1) << bit); + else + return bindingBits[bit / MaxInlineBits] & (BindingBitsType(1) << (bit % MaxInlineBits)); + } }; bool QQmlData::wasDeleted(QObject *object) @@ -281,20 +294,18 @@ inline bool QQmlData::signalHasEndpoint(int index) const bool QQmlData::hasBindingBit(int coreIndex) const { - int bit = coreIndex * 2; + Q_ASSERT(coreIndex >= 0); + Q_ASSERT(coreIndex <= 0xffff); - return bindingBitsSize > bit && - ((bindingBitsSize == 32) ? (bindingBitsValue & (1 << bit)) : - (bindingBits[bit / 32] & (1 << (bit % 32)))); + return hasBitSet(coreIndex * 2); } -bool QQmlData::hasPendingBindingBit(int index) const +bool QQmlData::hasPendingBindingBit(int coreIndex) const { - int bit = index * 2 + 1; + Q_ASSERT(coreIndex >= 0); + Q_ASSERT(coreIndex <= 0xffff); - return bindingBitsSize > bit && - ((bindingBitsSize == 32) ? (bindingBitsValue & (1 << bit)) : - (bindingBits[bit / 32] & (1 << (bit % 32)))); + return hasBitSet(coreIndex * 2 + 1); } void QQmlData::flushPendingBinding(QObject *o, QQmlPropertyIndex propertyIndex) diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 48832f3b07..2b49eae4de 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -105,6 +105,9 @@ Q_DECLARE_METATYPE(QQmlProperty) QT_BEGIN_NAMESPACE +typedef QQmlData::BindingBitsType BindingBitsType; +enum { MaxInlineBits = QQmlData::MaxInlineBits }; + void qmlRegisterBaseTypes(const char *uri, int versionMajor, int versionMinor) { QQmlEnginePrivate::registerBaseTypes(uri, versionMajor, versionMinor); @@ -677,7 +680,8 @@ void QQmlPrivate::qdeclarativeelement_destructor(QObject *o) QQmlData::QQmlData() : ownedByQml1(false), ownMemory(true), ownContext(false), indestructible(true), explicitIndestructibleSet(false), hasTaintedV4Object(false), isQueuedForDeletion(false), rootObjectInCreation(false), - hasInterceptorMetaObject(false), hasVMEMetaObject(false), parentFrozen(false), bindingBitsSize(0), bindingBits(0), notifyList(0), context(0), outerContext(0), + hasInterceptorMetaObject(false), hasVMEMetaObject(false), parentFrozen(false), + bindingBitsSize(MaxInlineBits), bindingBitsValue(0), notifyList(0), context(0), outerContext(0), bindings(0), signalHandlers(0), nextContextObject(0), prevContextObject(0), lineNumber(0), columnNumber(0), jsEngineId(0), compilationUnit(0), deferredData(0), propertyCache(0), guards(0), extendedData(0) @@ -1690,7 +1694,7 @@ void QQmlData::destroyed(QObject *object) signalHandler = next; } - if (bindingBitsSize > 32) + if (bindingBitsSize > MaxInlineBits) free(bindingBits); if (propertyCache) @@ -1740,31 +1744,27 @@ void QQmlData::parentChanged(QObject *object, QObject *parent) static void QQmlData_setBit(QQmlData *data, QObject *obj, int bit) { - if (data->bindingBitsSize == 0 && bit < 32) { - data->bindingBitsSize = 32; - } - - if (data->bindingBitsSize <= bit) { + if (Q_UNLIKELY(data->bindingBitsSize <= bit)) { int props = QQmlMetaObject(obj).propertyCount(); Q_ASSERT(bit < 2 * props); - int arraySize = (2 * props + 31) / 32; + int arraySize = (2 * props + MaxInlineBits - 1) / MaxInlineBits; Q_ASSERT(arraySize > 1); // special handling for 32 here is to make sure we wipe the first byte // when going from bindingBitsValue to bindingBits, and preserve the old // set bits so we can restore them after the allocation - int oldArraySize = data->bindingBitsSize > 32 ? data->bindingBitsSize / 32 : 0; - quint32 oldValue = data->bindingBitsSize == 32 ? data->bindingBitsValue : 0; + int oldArraySize = data->bindingBitsSize > MaxInlineBits ? data->bindingBitsSize / MaxInlineBits : 0; + quintptr oldValue = data->bindingBitsSize == MaxInlineBits ? data->bindingBitsValue : 0; - data->bindingBits = (quint32 *)realloc((data->bindingBitsSize == 32) ? 0 : data->bindingBits, - arraySize * sizeof(quint32)); + data->bindingBits = static_cast<BindingBitsType *>(realloc((data->bindingBitsSize == MaxInlineBits) ? 0 : data->bindingBits, + arraySize * sizeof(BindingBitsType))); memset(data->bindingBits + oldArraySize, 0x00, - sizeof(quint32) * (arraySize - oldArraySize)); + sizeof(BindingBitsType) * (arraySize - oldArraySize)); - data->bindingBitsSize = arraySize * 32; + data->bindingBitsSize = arraySize * MaxInlineBits; // reinstate bindingBitsValue after we dropped it if (oldValue) { @@ -1772,19 +1772,19 @@ static void QQmlData_setBit(QQmlData *data, QObject *obj, int bit) } } - if (data->bindingBitsSize == 32) - data->bindingBitsValue |= (1 << (bit % 32)); + if (data->bindingBitsSize == MaxInlineBits) + data->bindingBitsValue |= BindingBitsType(1) << bit; else - data->bindingBits[bit / 32] |= (1 << (bit % 32)); + data->bindingBits[bit / MaxInlineBits] |= (BindingBitsType(1) << (bit % MaxInlineBits)); } static void QQmlData_clearBit(QQmlData *data, int bit) { if (data->bindingBitsSize > bit) { - if (data->bindingBitsSize == 32) - data->bindingBitsValue &= ~(1 << (bit % 32)); + if (data->bindingBitsSize == MaxInlineBits) + data->bindingBitsValue &= ~(BindingBitsType(1) << (bit % MaxInlineBits)); else - data->bindingBits[bit / 32] &= ~(1 << (bit % 32)); + data->bindingBits[bit / MaxInlineBits] &= ~(BindingBitsType(1) << (bit % MaxInlineBits)); } } |