diff options
author | Frank Meerkoetter <frank.meerkoetter@basyskom.com> | 2015-08-29 22:25:51 +0200 |
---|---|---|
committer | Frank Meerkoetter <frank.meerkoetter@basyskom.com> | 2015-09-05 11:52:44 +0000 |
commit | cef14c0ff9a0caaa5b65ab89825534b3fcbd4764 (patch) | |
tree | 46cb93062822bcc7d8c59fe89cb7801954119678 | |
parent | 217bca42934ecf9a5fab74bbddbfa852c9b1bfe6 (diff) |
Allocate QML defined properties without extra room
QV4::MemberData is used to allocate storage for QML defined properties.
QV4::MemberData::reallocate() is multiplying each allocation by two
as a growth strategy. This is a waste of memory for QML defined properties.
This commits extends the QV4::MemberData with an additional method
to allow exactly sized allocations.
Change-Id: I5c0a3a5a3852d39af9e1afb512380fb1400d2448
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
-rw-r--r-- | src/qml/jsruntime/qv4memberdata.cpp | 28 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4memberdata_p.h | 3 | ||||
-rw-r--r-- | src/qml/qml/qqmlvmemetaobject.cpp | 2 |
3 files changed, 22 insertions, 11 deletions
diff --git a/src/qml/jsruntime/qv4memberdata.cpp b/src/qml/jsruntime/qv4memberdata.cpp index 5ec5cb1f58..20f8d9ec0f 100644 --- a/src/qml/jsruntime/qv4memberdata.cpp +++ b/src/qml/jsruntime/qv4memberdata.cpp @@ -46,20 +46,30 @@ void MemberData::markObjects(Heap::Base *that, ExecutionEngine *e) m->data[i].mark(e); } -Heap::MemberData *MemberData::reallocate(ExecutionEngine *e, Heap::MemberData *old, uint idx) +static Heap::MemberData *reallocateHelper(ExecutionEngine *e, Heap::MemberData *old, uint n) { - uint s = old ? old->size : 0; - if (idx < s) - return old; - - int newAlloc = qMax((uint)4, 2*idx); - uint alloc = sizeof(Heap::MemberData) + (newAlloc)*sizeof(Value); + uint alloc = sizeof(Heap::MemberData) + (n)*sizeof(Value); Scope scope(e); Scoped<MemberData> newMemberData(scope, e->memoryManager->allocManaged<MemberData>(alloc)); if (old) - memcpy(newMemberData->d(), old, sizeof(Heap::MemberData) + s*sizeof(Value)); + memcpy(newMemberData->d(), old, sizeof(Heap::MemberData) + old->size * sizeof(Value)); else new (newMemberData->d()) Heap::MemberData; - newMemberData->d()->size = newAlloc; + newMemberData->d()->size = n; return newMemberData->d(); } + +Heap::MemberData *MemberData::allocate(ExecutionEngine *e, uint n) +{ + return reallocateHelper(e, 0, n); +} + +Heap::MemberData *MemberData::reallocate(ExecutionEngine *e, Heap::MemberData *old, uint n) +{ + uint s = old ? old->size : 0; + if (n < s) + return old; + + // n is multiplied by two to leave room for growth + return reallocateHelper(e, old, qMax((uint)4, 2*n)); +} diff --git a/src/qml/jsruntime/qv4memberdata_p.h b/src/qml/jsruntime/qv4memberdata_p.h index 4c7cfa47cb..50b8ddb3d1 100644 --- a/src/qml/jsruntime/qv4memberdata_p.h +++ b/src/qml/jsruntime/qv4memberdata_p.h @@ -61,7 +61,8 @@ struct MemberData : Managed Value *data() { return d()->data; } inline uint size() const { return d()->size; } - static Heap::MemberData *reallocate(QV4::ExecutionEngine *e, Heap::MemberData *old, uint idx); + static Heap::MemberData *allocate(QV4::ExecutionEngine *e, uint n); + static Heap::MemberData *reallocate(QV4::ExecutionEngine *e, Heap::MemberData *old, uint n); static void markObjects(Heap::Base *that, ExecutionEngine *e); }; diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index 0ffeddbabc..4b19d1af04 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -1086,7 +1086,7 @@ void QQmlVMEMetaObject::allocateProperties() { Q_ASSERT(cache && cache->engine); QV4::ExecutionEngine *v4 = cache->engine; - QV4::Heap::MemberData *data = QV4::MemberData::reallocate(v4, 0, metaData->propertyCount); + QV4::Heap::MemberData *data = QV4::MemberData::allocate(v4, metaData->propertyCount); properties.set(v4, data); for (uint i = 0; i < data->size; ++i) data->data[i] = QV4::Encode::undefined(); |