From 378416af7542e34196908896c9a69573b995adb0 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Thu, 28 Jun 2012 15:29:22 +0200 Subject: Ensure QObject wrappers are garbage-collected if appropriate Address the "###" comment. When QScriptEngine::newQObject() is called with the option PreferExistingWrapperObject, the resulting wrapper object is cached by the engine, in case it will be needed later (e.g., by a subsequent newQObject() call for the same QObject, with the same wrap options). But if a QObject wrapper object is only referenced by the QtScript internals (i.e., not reachable from the JSC stack/heap, or kept in a QScriptValue), the wrapper should not be kept alive if the ownership is ScriptOwnership, or if the ownership is AutoOwnership and the C++ object has no parent. If the wrapper is marked in that case, it won't get collected, and hence the C++ object will be kept alive, too. In practice, QtScript appears to leak memory (the objects will only be destroyed when the engine is destroyed). Our copy of JSC doesn't have a concept of weak references; the ClientData callback in the JSC markRoots() function (which causes QScriptEnginePrivate::mark() to be called) was moved to the end. This enables the wrapper and connection marking logic to determine whether a wrapper can be safely discarded (if it hasn't been marked by JSC by this point, it must be a weak reference). Task-number: QTBUG-21993 Change-Id: I61f6aafc91f080b80d3f5859148e645b80d9b653 Reviewed-by: Olivier Goffart --- src/script/api/qscriptengine.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/script/api/qscriptengine.cpp') diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index 8b3b844..3b1cb9d 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -1253,6 +1253,9 @@ void QScriptEnginePrivate::setContextFlags(JSC::ExecState *exec, uint flags) } +// This function is called by JSC after all objects reachable by JSC itself +// have been processed (see JSC::Heap::markRoots()). +// Here we should mark additional objects managed by QtScript. void QScriptEnginePrivate::mark(JSC::MarkStack& markStack) { Q_Q(QScriptEngine); -- cgit v1.2.1