aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2015-01-29 14:56:00 +0100
committerSimon Hausmann <simon.hausmann@theqtcompany.com>2015-04-27 10:44:27 +0000
commit0699f27c9da6629ca02a1920146cb32999401676 (patch)
tree222f7691041b311744bbf05431e6fbffbbcaf5ea /src
parent8018c4b6e7743c576a3548f6e73e588f19f632a9 (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.h24
-rw-r--r--src/qml/qml/qqmlengine.cpp34
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)