diff options
author | Lars Knoll <lars.knoll@theqtcompany.com> | 2015-08-07 14:26:43 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@theqtcompany.com> | 2015-08-10 07:24:36 +0000 |
commit | c1667cd7277cd48e26a97ea5d10d6bcab0ef576e (patch) | |
tree | acb05c619ec15344ea5c2140ea16d5afe95fb3ad /src/qml/memory | |
parent | 415f55d1400f6abdd3a8e3edaf5ff208ecdad216 (diff) |
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 <simon.hausmann@theqtcompany.com>
Diffstat (limited to 'src/qml/memory')
-rw-r--r-- | src/qml/memory/qv4mm.cpp | 43 | ||||
-rw-r--r-- | src/qml/memory/qv4mm_p.h | 2 |
2 files changed, 15 insertions, 30 deletions
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<unsigned> 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<QObjectWrapper*>((*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<Managed>()) { - 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<Managed>(); + 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<QObjectWrapper*>((*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; |