aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/memory
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-01-04 12:45:45 +0100
committerLars Knoll <lars.knoll@qt.io>2017-01-25 08:30:59 +0000
commita56809dcfda21363d3c96c39c6075d5d65e116a6 (patch)
tree8116594521219b1db693d7129f7d286d0458289a /src/qml/memory
parentd8c6bf2dc129522f779d2c4ffc698a97b7531f66 (diff)
Get rid of the inline member data in Object
Instead allocate a MemberData at the same time as the object if required. Turns out this is faster now, and significantly simplifies some of our internal logic to access member properties. In addition, we can properly setup the inline member size to use the full extent of the memory reserved by the memory manager. This avoid some needless reallocations of MemberData objects. Change-Id: I36daeeaf6df16f2268103662fc78d600b4058ef8 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/memory')
-rw-r--r--src/qml/memory/qv4mm.cpp25
-rw-r--r--src/qml/memory/qv4mm_p.h17
2 files changed, 31 insertions, 11 deletions
diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp
index 4cad197d32..6330ef6038 100644
--- a/src/qml/memory/qv4mm.cpp
+++ b/src/qml/memory/qv4mm.cpp
@@ -627,7 +627,7 @@ Heap::Base *MemoryManager::allocString(std::size_t unmanagedSize)
if (aggressiveGC)
runGC();
- const uint stringSize = align(sizeof(Heap::String));
+ const size_t stringSize = align(sizeof(Heap::String));
unmanagedHeapSize += unmanagedSize;
bool didGCRun = false;
if (unmanagedHeapSize > unmanagedHeapSizeGCLimit) {
@@ -680,6 +680,29 @@ Heap::Base *MemoryManager::allocData(std::size_t size)
return *m;
}
+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) {
+ 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 = static_cast<Heap::MemberData *>(m);
+ o->memberData->setVtable(MemberData::staticVTable());
+ o->memberData->size = static_cast<uint>((memberSize - sizeof(Heap::MemberData) + sizeof(Value))/sizeof(Value));
+ o->memberData->init();
+// qDebug() << " got" << o->memberData << o->memberData->size;
+ }
+ return o;
+}
+
static void drainMarkStack(QV4::ExecutionEngine *engine, Value *markBase)
{
while (engine->jsStackTop > markBase) {
diff --git a/src/qml/memory/qv4mm_p.h b/src/qml/memory/qv4mm_p.h
index 7517328b37..76017f8148 100644
--- a/src/qml/memory/qv4mm_p.h
+++ b/src/qml/memory/qv4mm_p.h
@@ -224,26 +224,22 @@ public:
template <typename ObjectType>
typename ObjectType::Data *allocateObject(InternalClass *ic)
{
- const int size = (sizeof(typename ObjectType::Data) + (sizeof(Value) - 1)) & ~(sizeof(Value) - 1);
- typename ObjectType::Data *o = allocManaged<ObjectType>(size + ic->size*sizeof(Value));
+ Heap::Object *o = allocObjectWithMemberData(align(sizeof(typename ObjectType::Data)), ic->size);
+ o->setVtable(ObjectType::staticVTable());
o->internalClass = ic;
- o->inlineMemberSize = ic->size;
- o->inlineMemberOffset = size/sizeof(Value);
- return o;
+ return static_cast<typename ObjectType::Data *>(o);
}
template <typename ObjectType>
typename ObjectType::Data *allocateObject()
{
InternalClass *ic = ObjectType::defaultInternalClass(engine);
- const int size = (sizeof(typename ObjectType::Data) + (sizeof(Value) - 1)) & ~(sizeof(Value) - 1);
- typename ObjectType::Data *o = allocManaged<ObjectType>(size + ic->size*sizeof(Value));
+ Heap::Object *o = allocObjectWithMemberData(align(sizeof(typename ObjectType::Data)), ic->size);
+ o->setVtable(ObjectType::staticVTable());
Object *prototype = ObjectType::defaultPrototype(engine);
o->internalClass = ic;
o->prototype = prototype->d();
- o->inlineMemberSize = ic->size;
- o->inlineMemberOffset = size/sizeof(Value);
- return o;
+ return static_cast<typename ObjectType::Data *>(o);
}
template <typename ManagedType, typename Arg1>
@@ -430,6 +426,7 @@ protected:
/// expects size to be aligned
Heap::Base *allocString(std::size_t unmanagedSize);
Heap::Base *allocData(std::size_t size);
+ Heap::Object *allocObjectWithMemberData(std::size_t size, uint nMembers);
#ifdef DETAILED_MM_STATS
void willAllocate(std::size_t size);