From c1667cd7277cd48e26a97ea5d10d6bcab0ef576e Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 7 Aug 2015 14:26:43 +0200 Subject: destruct qobject wrappers before sweeping the GC heap The wrappers emit a destroyed signal, and it's important that the GC heap is in a well defined state when these signals are emitted. Change-Id: I423c4241b1e2fd3de727277d26bbe64f08862193 Reviewed-by: Simon Hausmann --- src/qml/memory/qv4mm.cpp | 43 +++++++++++++++---------------------------- src/qml/memory/qv4mm_p.h | 2 -- 2 files changed, 15 insertions(+), 30 deletions(-) (limited to 'src/qml/memory') diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp index 7e75570af3..24be663ed7 100644 --- a/src/qml/memory/qv4mm.cpp +++ b/src/qml/memory/qv4mm.cpp @@ -109,8 +109,6 @@ struct MemoryManager::Data LargeItem *largeItems; std::size_t totalLargeItemsAllocated; - GCDeletable *deletable; - // statistics: #ifdef DETAILED_MM_STATS QVector allocSizeCounters; @@ -125,7 +123,6 @@ struct MemoryManager::Data , maxChunkSize(32*1024) , largeItems(0) , totalLargeItemsAllocated(0) - , deletable(0) { memset(nonFullChunks, 0, sizeof(nonFullChunks)); memset(nChunks, 0, sizeof(nChunks)); @@ -351,8 +348,6 @@ void MemoryManager::mark() if ((*it).managed()->d()->vtable() != QObjectWrapper::staticVTable()) continue; QObjectWrapper *qobjectWrapper = static_cast((*it).managed()); - if (!qobjectWrapper) - continue; QObject *qobject = qobjectWrapper->object(); if (!qobject) continue; @@ -379,13 +374,20 @@ void MemoryManager::mark() void MemoryManager::sweep(bool lastSweep) { - if (m_weakValues) { - for (PersistentValueStorage::Iterator it = m_weakValues->begin(); it != m_weakValues->end(); ++it) { - if (Managed *m = (*it).as()) { - if (!m->markBit()) - (*it) = Primitive::undefinedValue(); - } + for (PersistentValueStorage::Iterator it = m_weakValues->begin(); it != m_weakValues->end(); ++it) { + if (!(*it).isManaged()) + continue; + Managed *m = (*it).as(); + if (m->markBit()) + continue; + // we need to call detroyObject on qobjectwrappers now, so that they can emit the destroyed + // signal before we start sweeping the heap + if ((*it).managed()->d()->vtable() == QObjectWrapper::staticVTable()) { + QObjectWrapper *qobjectWrapper = static_cast((*it).managed()); + qobjectWrapper->destroyObject(lastSweep); } + + (*it) = Primitive::undefinedValue(); } if (MultiplyWrappedQObjectMap *multiplyWrappedQObjects = m_d->engine->m_multiplyWrappedQObjects) { @@ -453,15 +455,6 @@ void MemoryManager::sweep(bool lastSweep) i = *last; } - GCDeletable *deletable = m_d->deletable; - m_d->deletable = 0; - while (deletable) { - GCDeletable *next = deletable->next; - deletable->lastCall = lastSweep; - delete deletable; - deletable = next; - } - // some execution contexts are allocated on the stack, make sure we clear their markBit as well if (!lastSweep) { Heap::ExecutionContext *ctx = engine()->current; @@ -556,10 +549,10 @@ size_t MemoryManager::getLargeItemsMem() const MemoryManager::~MemoryManager() { delete m_persistentValues; - delete m_weakValues; - m_weakValues = 0; sweep(/*lastSweep*/true); + + delete m_weakValues; #ifdef V4_USE_VALGRIND VALGRIND_DESTROY_MEMPOOL(this); #endif @@ -584,12 +577,6 @@ void MemoryManager::dumpStats() const #endif // DETAILED_MM_STATS } -void MemoryManager::registerDeletable(GCDeletable *d) -{ - d->next = m_d->deletable; - m_d->deletable = d; -} - #ifdef DETAILED_MM_STATS void MemoryManager::willAllocate(std::size_t size) { diff --git a/src/qml/memory/qv4mm_p.h b/src/qml/memory/qv4mm_p.h index a7b4e6ef4e..6d6ce1bad7 100644 --- a/src/qml/memory/qv4mm_p.h +++ b/src/qml/memory/qv4mm_p.h @@ -153,8 +153,6 @@ public: void dumpStats() const; - void registerDeletable(GCDeletable *d); - size_t getUsedMem() const; size_t getAllocatedMem() const; size_t getLargeItemsMem() const; -- cgit v1.2.3