aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/memory
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@theqtcompany.com>2015-08-07 14:26:43 +0200
committerLars Knoll <lars.knoll@theqtcompany.com>2015-08-10 07:24:36 +0000
commitc1667cd7277cd48e26a97ea5d10d6bcab0ef576e (patch)
treeacb05c619ec15344ea5c2140ea16d5afe95fb3ad /src/qml/memory
parent415f55d1400f6abdd3a8e3edaf5ff208ecdad216 (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.cpp43
-rw-r--r--src/qml/memory/qv4mm_p.h2
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;