From e59d8d831e53e2206af6661cb086a90d37ad7c2e Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 6 May 2013 15:11:01 +0200 Subject: [PATCH] Use a doubly linked list for PersistentValue This makes cleanup easier, more consistent and actually work. Change-Id: I5b58b6649ed527fd9f216c67ea609b49228c874a Reviewed-by: Simon Hausmann --- src/qml/qml/v4/qv4mm.cpp | 3 ++- src/qml/qml/v4/qv4value.cpp | 27 ++++++++++++++++++++------- src/qml/qml/v4/qv4value_p.h | 2 ++ 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/qml/qml/v4/qv4mm.cpp b/src/qml/qml/v4/qv4mm.cpp index f71f7a8..b400415 100644 --- a/src/qml/qml/v4/qv4mm.cpp +++ b/src/qml/qml/v4/qv4mm.cpp @@ -399,8 +399,9 @@ MemoryManager::~MemoryManager() { PersistentValuePrivate *persistent = m_persistentValues; while (persistent) { - persistent->value = Value::deletedValue(); PersistentValuePrivate *n = persistent->next; + persistent->value = Value::deletedValue(); + persistent->prev = 0; persistent->next = 0; persistent = n; } diff --git a/src/qml/qml/v4/qv4value.cpp b/src/qml/qml/v4/qv4value.cpp index 7e2f164..f330aeb 100644 --- a/src/qml/qml/v4/qv4value.cpp +++ b/src/qml/qml/v4/qv4value.cpp @@ -247,6 +247,16 @@ PersistentValue &PersistentValue::operator=(const PersistentValue &other) PersistentValue &PersistentValue::operator =(const Value &other) { d->value = other; + if (!d->prev) { + if (Managed *m = d->value.asManaged()) { + ExecutionEngine *engine = m->engine(); + if (engine) { + d->prev = &engine->memoryManager->m_persistentValues; + d->next = engine->memoryManager->m_persistentValues; + *d->prev = d; + } + } + } } PersistentValue::~PersistentValue() @@ -257,13 +267,16 @@ PersistentValue::~PersistentValue() PersistentValuePrivate::PersistentValuePrivate(const Value &v) : value(v) , refcount(1) + , prev(0) , next(0) { if (Managed *m = v.asManaged()) { ExecutionEngine *engine = m->engine(); if (engine) { + prev = &engine->memoryManager->m_persistentValues; next = engine->memoryManager->m_persistentValues; - engine->memoryManager->m_persistentValues = this; + if (next) + next->prev = &this->next; } } } @@ -272,11 +285,11 @@ void PersistentValuePrivate::deref() { // if engine is not 0, they are registered with the memory manager // and will get cleaned up in the next gc run - if (!--refcount && !next) { - ExecutionEngine *e = 0; - if (Managed *m = value.asManaged()) - e = m->engine(); - if (!e) - delete this; + if (!--refcount) { + if (prev) { + next->prev = prev; + *prev = next; + } + delete this; } } diff --git a/src/qml/qml/v4/qv4value_p.h b/src/qml/qml/v4/qv4value_p.h index 29fc68b..d583826 100644 --- a/src/qml/qml/v4/qv4value_p.h +++ b/src/qml/qml/v4/qv4value_p.h @@ -554,11 +554,13 @@ struct PersistentValuePrivate PersistentValuePrivate() : value(Value::deletedValue()) , refcount(1) + , prev(0) , next(0) {} PersistentValuePrivate(const Value &v); Value value; int refcount; + PersistentValuePrivate **prev; PersistentValuePrivate *next; void ref() { ++refcount; } -- 2.7.4