From a10f1b1e4ac8072a733bebcde7f4aafcdd54c126 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 15 Feb 2017 12:23:20 +0100 Subject: Optimize allocObjectWithMemberData Use only one call into the block allocator in the common case. Change-Id: Ic9be82f03ba66c1eff3e27407458343b6cd6d30c Reviewed-by: Simon Hausmann --- src/qml/memory/qv4mm.cpp | 46 +++++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 19 deletions(-) (limited to 'src/qml/memory') 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(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(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(m)); - o->memberData->setVtable(MemberData::staticVTable()); - o->memberData->values.alloc = static_cast((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(allocData(size)); + m = hugeItemAllocator.allocate(memberSize)->as(); + } else { + HeapItem *mh = reinterpret_cast(allocData(totalSize)); + Heap::Base *b = *mh; + o = static_cast(b); + mh += (size >> Chunk::SlotSizeShift); + m = mh->as(); + 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((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"; -- cgit v1.2.3