aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/qml/qqmlvmemetaobject.cpp3
-rw-r--r--src/qml/qml/v4/qv4engine.cpp2
-rw-r--r--src/qml/qml/v4/qv4mm.cpp14
-rw-r--r--src/qml/qml/v4/qv4value.cpp76
-rw-r--r--src/qml/qml/v4/qv4value_p.h1
-rw-r--r--src/qml/qml/v8/qv8qobjectwrapper.cpp10
-rw-r--r--src/qml/qml/v8/qv8qobjectwrapper_p.h2
7 files changed, 65 insertions, 43 deletions
diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp
index ace9ff9a65..09edd3af89 100644
--- a/src/qml/qml/qqmlvmemetaobject.cpp
+++ b/src/qml/qml/qqmlvmemetaobject.cpp
@@ -73,7 +73,8 @@ void QQmlVMEVariantQObjectPtr::objectDestroyed(QObject *)
if (m_isVar && m_target->varPropertiesInitialized && !m_target->varProperties.isEmpty()) {
// Set the var property to NULL
QV4::ArrayObject *a = m_target->varProperties.value().asArrayObject();
- a->putIndexed(m_index - m_target->firstVarPropertyIndex, QV4::Value::nullValue());
+ if (a)
+ a->putIndexed(m_index - m_target->firstVarPropertyIndex, QV4::Value::nullValue());
}
m_target->activate(m_target->object, m_target->methodOffset() + m_index, 0);
diff --git a/src/qml/qml/v4/qv4engine.cpp b/src/qml/qml/v4/qv4engine.cpp
index f4f80a4a1b..81bd9417a6 100644
--- a/src/qml/qml/v4/qv4engine.cpp
+++ b/src/qml/qml/v4/qv4engine.cpp
@@ -269,13 +269,13 @@ ExecutionEngine::ExecutionEngine(QQmlJS::EvalISelFactory *factory)
ExecutionEngine::~ExecutionEngine()
{
+ delete memoryManager;
emptyClass->destroy();
delete identifierCache;
delete bumperPointerAllocator;
delete regExpCache;
UnwindHelper::deregisterFunctions(functions);
qDeleteAll(functions);
- delete memoryManager;
delete regExpAllocator;
delete executableAllocator;
}
diff --git a/src/qml/qml/v4/qv4mm.cpp b/src/qml/qml/v4/qv4mm.cpp
index fcc660e3db..cf37c695f3 100644
--- a/src/qml/qml/v4/qv4mm.cpp
+++ b/src/qml/qml/v4/qv4mm.cpp
@@ -333,7 +333,9 @@ std::size_t MemoryManager::sweep()
if (Managed *m = weak->value.asManaged()) {
if (!m->markBit) {
weak->value = Value::emptyValue();
+ PersistentValuePrivate *n = weak->next;
weak->removeFromList();
+ weak = n;
continue;
}
}
@@ -448,6 +450,18 @@ void MemoryManager::setEnableGC(bool enableGC)
MemoryManager::~MemoryManager()
{
+ PersistentValuePrivate *weak = m_weakValues;
+ while (weak) {
+ if (QObjectWrapper *qobjectWrapper = weak->value.asQObjectWrapper()) {
+ weak->ref();
+ qobjectWrapper->deleteQObject(/*deleteInstantly*/ true);
+ PersistentValuePrivate *n = weak->next;
+ weak->deref();
+ weak = n;
+ } else
+ weak = weak->next;
+ }
+
PersistentValuePrivate *persistent = m_persistentValues;
while (persistent) {
PersistentValuePrivate *n = persistent->next;
diff --git a/src/qml/qml/v4/qv4value.cpp b/src/qml/qml/v4/qv4value.cpp
index a6f5beb99f..fb463b5abd 100644
--- a/src/qml/qml/v4/qv4value.cpp
+++ b/src/qml/qml/v4/qv4value.cpp
@@ -248,6 +248,8 @@ PersistentValue &PersistentValue::operator=(const PersistentValue &other)
d = other.d;
if (d)
d->ref();
+
+ return *this;
}
PersistentValue &PersistentValue::operator =(const Value &other)
@@ -256,26 +258,8 @@ PersistentValue &PersistentValue::operator =(const Value &other)
d = new PersistentValuePrivate(other);
return *this;
}
- d->value = other;
- Managed *m = d->value.asManaged();
- if (!d->prev) {
- if (m) {
- ExecutionEngine *engine = m->engine();
- if (engine) {
- d->prev = &engine->memoryManager->m_persistentValues;
- d->next = engine->memoryManager->m_persistentValues;
- *d->prev = d;
- if (d->next)
- d->next->prev = &d->next;
- }
- }
- } else if (!m) {
- if (d->next)
- d->next->prev = d->prev;
- *d->prev = d->next;
- d->prev = 0;
- d->next = 0;
- }
+ d = d->detach(other);
+ return *this;
}
PersistentValue::~PersistentValue()
@@ -308,6 +292,8 @@ WeakValue &WeakValue::operator=(const WeakValue &other)
d = other.d;
if (d)
d->ref();
+
+ return *this;
}
WeakValue &WeakValue::operator =(const Value &other)
@@ -316,26 +302,8 @@ WeakValue &WeakValue::operator =(const Value &other)
d = new PersistentValuePrivate(other, /*weak*/true);
return *this;
}
- d->value = other;
- Managed *m = d->value.asManaged();
- if (!d->prev) {
- if (m) {
- ExecutionEngine *engine = m->engine();
- if (engine) {
- d->prev = &engine->memoryManager->m_weakValues;
- d->next = engine->memoryManager->m_weakValues;
- *d->prev = d;
- if (d->next)
- d->next->prev = &d->next;
- }
- }
- } else if (!m) {
- if (d->next)
- d->next->prev = d->prev;
- *d->prev = d->next;
- d->prev = 0;
- d->next = 0;
- }
+ d = d->detach(other, /*weak*/true);
+ return *this;
}
@@ -383,6 +351,7 @@ void PersistentValuePrivate::removeFromList()
if (next)
next->prev = prev;
*prev = next;
+ next = 0;
prev = 0;
}
}
@@ -397,3 +366,30 @@ void PersistentValuePrivate::deref()
}
}
+PersistentValuePrivate *PersistentValuePrivate::detach(const QV4::Value &value, bool weak)
+{
+ if (refcount == 1) {
+ this->value = value;
+
+ Managed *m = value.asManaged();
+ if (!prev) {
+ if (m) {
+ ExecutionEngine *engine = m->engine();
+ if (engine) {
+ PersistentValuePrivate **listRoot = weak ? &engine->memoryManager->m_weakValues : &engine->memoryManager->m_persistentValues;
+ prev = listRoot;
+ next = *listRoot;
+ *prev = this;
+ if (next)
+ next->prev = &this->next;
+ }
+ }
+ } else if (!m)
+ removeFromList();
+
+ return this;
+ }
+ --refcount;
+ return new PersistentValuePrivate(value, weak);
+}
+
diff --git a/src/qml/qml/v4/qv4value_p.h b/src/qml/qml/v4/qv4value_p.h
index 9914467c39..45604740e6 100644
--- a/src/qml/qml/v4/qv4value_p.h
+++ b/src/qml/qml/v4/qv4value_p.h
@@ -577,6 +577,7 @@ struct PersistentValuePrivate
void removeFromList();
void ref() { ++refcount; }
void deref();
+ PersistentValuePrivate *detach(const QV4::Value &value, bool weak = false);
};
class Q_QML_EXPORT PersistentValue
diff --git a/src/qml/qml/v8/qv8qobjectwrapper.cpp b/src/qml/qml/v8/qv8qobjectwrapper.cpp
index 578eaea567..e1d5cab5c7 100644
--- a/src/qml/qml/v8/qv8qobjectwrapper.cpp
+++ b/src/qml/qml/v8/qv8qobjectwrapper.cpp
@@ -94,6 +94,11 @@ QObjectWrapper::QObjectWrapper(ExecutionEngine *engine, QObject *object)
QObjectWrapper::~QObjectWrapper()
{
+ deleteQObject();
+}
+
+void QObjectWrapper::deleteQObject(bool deleteInstantly)
+{
if (!object)
return;
QQmlData *ddata = QQmlData::get(object, false);
@@ -104,7 +109,10 @@ QObjectWrapper::~QObjectWrapper()
if (ddata->ownContext && ddata->context)
ddata->context->emitDestruction();
ddata->isQueuedForDeletion = true;
- object->deleteLater();
+ if (deleteInstantly)
+ delete object;
+ else
+ object->deleteLater();
}
}
diff --git a/src/qml/qml/v8/qv8qobjectwrapper_p.h b/src/qml/qml/v8/qv8qobjectwrapper_p.h
index b9d528e3c7..1811889873 100644
--- a/src/qml/qml/v8/qv8qobjectwrapper_p.h
+++ b/src/qml/qml/v8/qv8qobjectwrapper_p.h
@@ -87,6 +87,8 @@ struct Q_QML_EXPORT QObjectWrapper : public QV4::Object
QV8Engine *v8Engine; // ### Remove again.
QQmlGuard<QObject> object;
+ void deleteQObject(bool deleteInstantly = false);
+
private:
String *m_destroy;
String *m_toString;