diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2015-01-29 14:56:00 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@theqtcompany.com> | 2015-04-27 10:44:27 +0000 |
commit | 0699f27c9da6629ca02a1920146cb32999401676 (patch) | |
tree | 222f7691041b311744bbf05431e6fbffbbcaf5ea /src | |
parent | 8018c4b6e7743c576a3548f6e73e588f19f632a9 (diff) |
Only heap allocate binding bits storage if needed.
For samegame, this has the following change on the total bytes allocated:
Startup (main page):
Before: 1636
After: 1072
Difference: 564 bytes (-34%)
Actual game (single player):
Before: 14120
After: 10432
Difference: 3688 bytes (-26%)
Done-with: Robin Burchell <robin.burchell@viroteck.net>
Change-Id: I10fd1e9f1440dcff93aed06e2c77c2912bc7dd39
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
(cherry picked from commit 54a19db8d00b67044861c8ffd1d5b1e646658609)
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/qml/qqmldata_p.h | 24 | ||||
-rw-r--r-- | src/qml/qml/qqmlengine.cpp | 34 |
2 files changed, 43 insertions, 15 deletions
diff --git a/src/qml/qml/qqmldata_p.h b/src/qml/qml/qqmldata_p.h index c9bae8e774..c7654be545 100644 --- a/src/qml/qml/qqmldata_p.h +++ b/src/qml/qml/qqmldata_p.h @@ -123,8 +123,14 @@ public: quint32 parentFrozen:1; quint32 dummy:22; + // When bindingBitsSize < 32, we store the binding bit flags inside + // bindingBitsValue. When we need more than 32 bits, we allocated + // sufficient space and use bindingBits to point to it. int bindingBitsSize; - quint32 *bindingBits; + union { + quint32 *bindingBits; + quint32 bindingBitsValue; + }; struct NotifyList { quint64 connectionMask; @@ -261,19 +267,19 @@ QQmlNotifierEndpoint *QQmlData::notify(int index) bool QQmlData::hasBindingBit(int coreIndex) const { int bit = coreIndex * 2; - if (bindingBitsSize > bit) - return bindingBits[bit / 32] & (1 << (bit % 32)); - else - return false; + + return bindingBitsSize > bit && + ((bindingBitsSize == 32) ? (bindingBitsValue & (1 << bit)) : + (bindingBits[bit / 32] & (1 << (bit % 32)))); } bool QQmlData::hasPendingBindingBit(int coreIndex) const { int bit = coreIndex * 2 + 1; - if (bindingBitsSize > bit) - return bindingBits[bit / 32] & (1 << (bit % 32)); - else - return false; + + return bindingBitsSize > bit && + ((bindingBitsSize == 32) ? (bindingBitsValue & (1 << bit)) : + (bindingBits[bit / 32] & (1 << (bit % 32)))); } void QQmlData::flushPendingBinding(QObject *o, int coreIndex) diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 2361274e5f..8a7e4b84e7 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -1696,7 +1696,7 @@ void QQmlData::destroyed(QObject *object) signalHandler = next; } - if (bindingBits) + if (bindingBitsSize > 32) free(bindingBits); if (propertyCache) @@ -1744,14 +1744,24 @@ 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) { int props = QQmlMetaObject(obj).propertyCount(); Q_ASSERT(bit < 2 * props); int arraySize = (2 * props + 31) / 32; - int oldArraySize = data->bindingBitsSize / 32; + Q_ASSERT(arraySize > 1); - data->bindingBits = (quint32 *)realloc(data->bindingBits, + // 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; + + data->bindingBits = (quint32 *)realloc((data->bindingBitsSize == 32) ? 0 : data->bindingBits, arraySize * sizeof(quint32)); memset(data->bindingBits + oldArraySize, @@ -1759,15 +1769,27 @@ static void QQmlData_setBit(QQmlData *data, QObject *obj, int bit) sizeof(quint32) * (arraySize - oldArraySize)); data->bindingBitsSize = arraySize * 32; + + // reinstate bindingBitsValue after we dropped it + if (oldValue) { + memcpy(data->bindingBits, &oldValue, sizeof(oldValue)); + } } - data->bindingBits[bit / 32] |= (1 << (bit % 32)); + if (data->bindingBitsSize == 32) + data->bindingBitsValue |= (1 << (bit % 32)); + else + data->bindingBits[bit / 32] |= (1 << (bit % 32)); } static void QQmlData_clearBit(QQmlData *data, int bit) { - if (data->bindingBitsSize > bit) - data->bindingBits[bit / 32] &= ~(1 << (bit % 32)); + if (data->bindingBitsSize > bit) { + if (data->bindingBitsSize == 32) + data->bindingBitsValue &= ~(1 << (bit % 32)); + else + data->bindingBits[bit / 32] &= ~(1 << (bit % 32)); + } } void QQmlData::clearBindingBit(int coreIndex) |