aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/memory
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-02-15 12:23:20 +0100
committerLars Knoll <lars.knoll@qt.io>2017-03-09 08:59:35 +0000
commita10f1b1e4ac8072a733bebcde7f4aafcdd54c126 (patch)
treea23c521e9b80f2242406eac07b533a76ba96875e /src/qml/memory
parent0bee9b94eb20d644a1df4fd0062527e680545f31 (diff)
Optimize allocObjectWithMemberData
Use only one call into the block allocator in the common case. Change-Id: Ic9be82f03ba66c1eff3e27407458343b6cd6d30c Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/memory')
-rw-r--r--src/qml/memory/qv4mm.cpp46
1 files changed, 27 insertions, 19 deletions
diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp
index 9c7915d2c3..069084763c 100644
--- a/src/qml/memory/qv4mm.cpp
+++ b/src/qml/memory/qv4mm.cpp
@@ -807,26 +807,33 @@ Heap::Base *MemoryManager::allocData(std::size_t size)
Heap::Object *MemoryManager::allocObjectWithMemberData(std::size_t size, uint nMembers)
{
- Heap::Object *o = static_cast<Heap::Object *>(allocData(size));
-
- // ### Could optimize this and allocate both in one go through the block allocator
- if (nMembers) {
-#ifdef MM_STATS
- ++allocationCount;
-#endif
+ Heap::Object *o;
+ if (!nMembers) {
+ o = static_cast<Heap::Object *>(allocData(size));
+ } else {
+ // Allocate both in one go through the block allocator
std::size_t memberSize = align(sizeof(Heap::MemberData) + (nMembers - 1)*sizeof(Value));
-// qDebug() << "allocating member data for" << o << nMembers << memberSize;
- Heap::Base *m;
- if (memberSize > Chunk::DataSize)
- m = *hugeItemAllocator.allocate(memberSize);
- else
- m = *blockAllocator.allocate(memberSize, true);
- memset(m, 0, memberSize);
- o->memberData.set(engine, static_cast<Heap::MemberData *>(m));
- o->memberData->setVtable(MemberData::staticVTable());
- o->memberData->values.alloc = static_cast<uint>((memberSize - sizeof(Heap::MemberData) + sizeof(Value))/sizeof(Value));
- o->memberData->values.size = o->memberData->values.alloc;
- o->memberData->init();
+ size_t totalSize = size + memberSize;
+ Heap::MemberData *m;
+ if (totalSize > Chunk::DataSize) {
+ o = static_cast<Heap::Object *>(allocData(size));
+ m = hugeItemAllocator.allocate(memberSize)->as<Heap::MemberData>();
+ } else {
+ HeapItem *mh = reinterpret_cast<HeapItem *>(allocData(totalSize));
+ Heap::Base *b = *mh;
+ o = static_cast<Heap::Object *>(b);
+ mh += (size >> Chunk::SlotSizeShift);
+ m = mh->as<Heap::MemberData>();
+ Chunk *c = mh->chunk();
+ size_t index = mh - c->realBase();
+ Chunk::setBit(c->objectBitmap, index);
+ Chunk::clearBit(c->extendsBitmap, index);
+ }
+ o->memberData.set(engine, m);
+ m->setVtable(MemberData::staticVTable());
+ m->values.alloc = static_cast<uint>((memberSize - sizeof(Heap::MemberData) + sizeof(Value))/sizeof(Value));
+ m->values.size = o->memberData->values.alloc;
+ m->init();
// qDebug() << " got" << o->memberData << o->memberData->size;
}
// qDebug() << "allocating object with memberData" << o << o->memberData.operator->();
@@ -1063,6 +1070,7 @@ void MemoryManager::runGC(bool forceFullCollection)
#ifdef MM_STATS
qDebug() << " Triggered by alloc request of" << lastAllocRequestedSlots << "slots.";
qDebug() << " Allocations since last GC" << allocationCount;
+ allocationCount = 0;
#endif
qDebug() << "Incremental:" << nextGCIsIncremental;
qDebug() << "Allocated" << totalMem << "bytes in" << blockAllocator.chunks.size() << "chunks";