aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2015-01-29 14:56:00 +0100
committerRobin Burchell <robin.burchell@viroteck.net>2015-02-24 10:33:15 +0000
commit54a19db8d00b67044861c8ffd1d5b1e646658609 (patch)
tree531637181d091e0d1470eca3ef80badb588b8724
parent9fcae3df40335b97a50836ffb07a5ffbc4f40673 (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: I29b7a79400090180f405693093f266c151260fcc Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
-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 33be4c321f..ab67d7738d 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -1685,7 +1685,7 @@ void QQmlData::destroyed(QObject *object)
signalHandler = next;
}
- if (bindingBits)
+ if (bindingBitsSize > 32)
free(bindingBits);
if (propertyCache)
@@ -1733,14 +1733,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,
@@ -1748,15 +1758,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)