diff options
author | Lars Knoll <lars.knoll@qt.io> | 2018-01-16 16:34:03 +0100 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2018-01-17 09:20:18 +0000 |
commit | c2d0693ca99171ebeb8f35423f29562b0d26c6c0 (patch) | |
tree | 602146f52e5250a8ab987a4857619c558e39349c /src/qml/qml/qqmlengine.cpp | |
parent | 4e0277664071c31e2189e2351e3e9d12c4e7e08c (diff) |
Have more bindingBits available inline
Many QML items have more than 32 properties, so we ended
up malloc'ing the binding bit table on the heap quite
often. Extending the inline data to be able to accommodate
for up to 64 properties fixes that.
Change-Id: I90a42d601a5406ffacf2506f1957b0c2080bbb7b
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/qml/qqmlengine.cpp')
-rw-r--r-- | src/qml/qml/qqmlengine.cpp | 60 |
1 files changed, 26 insertions, 34 deletions
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 5350ad38a3..c09c048307 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -110,7 +110,10 @@ Q_DECLARE_METATYPE(QQmlProperty) QT_BEGIN_NAMESPACE typedef QQmlData::BindingBitsType BindingBitsType; -enum { MaxInlineBits = QQmlData::MaxInlineBits }; +enum { + BitsPerType = QQmlData::BitsPerType, + InlineBindingArraySize = QQmlData::InlineBindingArraySize +}; void qmlRegisterBaseTypes(const char *uri, int versionMajor, int versionMinor) { @@ -741,11 +744,12 @@ QQmlData::QQmlData() : ownedByQml1(false), ownMemory(true), indestructible(true), explicitIndestructibleSet(false), hasTaintedV4Object(false), isQueuedForDeletion(false), rootObjectInCreation(false), hasInterceptorMetaObject(false), hasVMEMetaObject(false), parentFrozen(false), - bindingBitsSize(MaxInlineBits), bindingBitsValue(0), notifyList(0), + bindingBitsArraySize(InlineBindingArraySize), notifyList(0), bindings(0), signalHandlers(0), nextContextObject(0), prevContextObject(0), lineNumber(0), columnNumber(0), jsEngineId(0), compilationUnit(0), propertyCache(0), guards(0), extendedData(0) { + memset(bindingBitsValue, 0, sizeof(bindingBitsValue)); init(); } @@ -1792,7 +1796,7 @@ void QQmlData::destroyed(QObject *object) signalHandler = next; } - if (bindingBitsSize > MaxInlineBits) + if (bindingBitsArraySize > InlineBindingArraySize) free(bindingBits); if (propertyCache) @@ -1841,47 +1845,35 @@ void QQmlData::parentChanged(QObject *object, QObject *parent) static void QQmlData_setBit(QQmlData *data, QObject *obj, int bit) { - if (Q_UNLIKELY(data->bindingBitsSize <= bit)) { + uint offset = QQmlData::offsetForBit(bit); + BindingBitsType *bits = (data->bindingBitsArraySize == InlineBindingArraySize) ? data->bindingBitsValue : data->bindingBits; + if (Q_UNLIKELY(data->bindingBitsArraySize <= offset)) { int props = QQmlMetaObject(obj).propertyCount(); Q_ASSERT(bit < 2 * props); - 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 > MaxInlineBits ? data->bindingBitsSize / MaxInlineBits : 0; - quintptr oldValue = data->bindingBitsSize == MaxInlineBits ? data->bindingBitsValue : 0; - - data->bindingBits = static_cast<BindingBitsType *>(realloc((data->bindingBitsSize == MaxInlineBits) ? 0 : data->bindingBits, - arraySize * sizeof(BindingBitsType))); - - memset(data->bindingBits + oldArraySize, - 0x00, - sizeof(BindingBitsType) * (arraySize - oldArraySize)); + uint arraySize = (2 * static_cast<uint>(props) + BitsPerType - 1) / BitsPerType; + Q_ASSERT(arraySize > InlineBindingArraySize && arraySize > data->bindingBitsArraySize); - data->bindingBitsSize = arraySize * MaxInlineBits; + BindingBitsType *newBits = static_cast<BindingBitsType *>(malloc(arraySize*sizeof(BindingBitsType))); + memcpy(newBits, bits, data->bindingBitsArraySize * sizeof(BindingBitsType)); + memset(newBits + data->bindingBitsArraySize, 0, sizeof(BindingBitsType) * (arraySize - data->bindingBitsArraySize)); - // reinstate bindingBitsValue after we dropped it - if (oldValue) { - memcpy(data->bindingBits, &oldValue, sizeof(oldValue)); - } + if (data->bindingBitsArraySize > InlineBindingArraySize) + free(bits); + data->bindingBits = newBits; + bits = newBits; + data->bindingBitsArraySize = arraySize; } - - if (data->bindingBitsSize == MaxInlineBits) - data->bindingBitsValue |= BindingBitsType(1) << bit; - else - data->bindingBits[bit / MaxInlineBits] |= (BindingBitsType(1) << (bit % MaxInlineBits)); + Q_ASSERT(offset < data->bindingBitsArraySize); + bits[offset] |= QQmlData::bitFlagForBit(bit); } static void QQmlData_clearBit(QQmlData *data, int bit) { - if (data->bindingBitsSize > bit) { - if (data->bindingBitsSize == MaxInlineBits) - data->bindingBitsValue &= ~(BindingBitsType(1) << (bit % MaxInlineBits)); - else - data->bindingBits[bit / MaxInlineBits] &= ~(BindingBitsType(1) << (bit % MaxInlineBits)); + uint offset = QQmlData::offsetForBit(bit); + if (data->bindingBitsArraySize > offset) { + BindingBitsType *bits = (data->bindingBitsArraySize == InlineBindingArraySize) ? data->bindingBitsValue : data->bindingBits; + bits[offset] &= ~QQmlData::bitFlagForBit(bit); } } |