Skip to content

Commit

Permalink
Clean up manual refcounting of compilation units
Browse files Browse the repository at this point in the history
Replace manual use in QQmlData and QQmlData::DeferredData with
QQmlRefPointer.

Due to forward declaration trouble this required declaring a non-inline
constructor/destructor for QQmlData and DeferedData and disabling
copying, so that not every C++ compilation unit including qqmldata_p.h
needs to instantiate the QQmlRefPointer destructor and thus know whether
QV4::CompiledData::CompilationUnit has release(), etc. The out-of-line
declarations however should not have any negative impact as the only
call sites are within qqmlengine.cpp, too.

Change-Id: I2e8295cb0d7f876a5d7d18765dbac285184e6c99
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
  • Loading branch information
tronical committed Feb 6, 2018
1 parent 43b6e03 commit 5b0a98f
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 13 deletions.
10 changes: 8 additions & 2 deletions src/qml/qml/qqmldata_p.h
Expand Up @@ -56,6 +56,7 @@
#include <private/qqmlpropertyindex_p.h>
#include <private/qv4value_p.h>
#include <private/qv4persistent_p.h>
#include <private/qqmlrefcount_p.h>
#include <qjsengine.h>
#include <qvector.h>

Expand Down Expand Up @@ -116,6 +117,7 @@ class Q_QML_PRIVATE_EXPORT QQmlData : public QAbstractDeclarativeData
{
public:
QQmlData();
~QQmlData();

static inline void init() {
static bool initialized = false;
Expand Down Expand Up @@ -219,12 +221,15 @@ class Q_QML_PRIVATE_EXPORT QQmlData : public QAbstractDeclarativeData
quint32 jsEngineId; // id of the engine that created the jsWrapper

struct DeferredData {
DeferredData();
~DeferredData();
unsigned int deferredIdx;
QMultiHash<int, const QV4::CompiledData::Binding *> bindings;
QV4::CompiledData::CompilationUnit *compilationUnit;//Not always the same as the other compilation unit
QQmlRefPointer<QV4::CompiledData::CompilationUnit> compilationUnit;//Not always the same as the other compilation unit
QQmlContextData *context;//Could be either context or outerContext
Q_DISABLE_COPY(DeferredData);
};
QV4::CompiledData::CompilationUnit *compilationUnit;
QQmlRefPointer<QV4::CompiledData::CompilationUnit> compilationUnit;
QVector<DeferredData *> deferredData;

void deferData(int objectIndex, QV4::CompiledData::CompilationUnit *, QQmlContextData *);
Expand Down Expand Up @@ -299,6 +304,7 @@ class Q_QML_PRIVATE_EXPORT QQmlData : public QAbstractDeclarativeData
const BindingBitsType *bits = (bindingBitsArraySize == InlineBindingArraySize) ? bindingBitsValue : bindingBits;
return bits[offset] & bitFlagForBit(bit);
}
Q_DISABLE_COPY(QQmlData);
};

bool QQmlData::wasDeleted(const QObject *object)
Expand Down
21 changes: 14 additions & 7 deletions src/qml/qml/qqmlengine.cpp
Expand Up @@ -746,13 +746,17 @@ QQmlData::QQmlData()
hasInterceptorMetaObject(false), hasVMEMetaObject(false), parentFrozen(false),
bindingBitsArraySize(InlineBindingArraySize), notifyList(0),
bindings(0), signalHandlers(0), nextContextObject(0), prevContextObject(0),
lineNumber(0), columnNumber(0), jsEngineId(0), compilationUnit(0),
lineNumber(0), columnNumber(0), jsEngineId(0),
propertyCache(0), guards(0), extendedData(0)
{
memset(bindingBitsValue, 0, sizeof(bindingBitsValue));
init();
}

QQmlData::~QQmlData()
{
}

void QQmlData::destroyed(QAbstractDeclarativeData *d, QObject *o)
{
QQmlData *ddata = static_cast<QQmlData *>(d);
Expand Down Expand Up @@ -924,6 +928,14 @@ void QQmlData::flushPendingBindingImpl(QQmlPropertyIndex index)
QQmlPropertyData::DontRemoveBinding);
}

QQmlData::DeferredData::DeferredData()
{
}

QQmlData::DeferredData::~DeferredData()
{
}

bool QQmlEnginePrivate::baseModulesUninitialized = true;
void QQmlEnginePrivate::init()
{
Expand Down Expand Up @@ -1651,7 +1663,6 @@ void QQmlData::deferData(int objectIndex, QV4::CompiledData::CompilationUnit *co
QQmlData::DeferredData *deferData = new QQmlData::DeferredData;
deferData->deferredIdx = objectIndex;
deferData->compilationUnit = compilationUnit;
deferData->compilationUnit->addref();
deferData->context = context;

const QV4::CompiledData::Object *compiledObject = compilationUnit->objectAt(objectIndex);
Expand All @@ -1673,7 +1684,6 @@ void QQmlData::releaseDeferredData()
while (it != deferredData.end()) {
DeferredData *deferData = *it;
if (deferData->bindings.isEmpty()) {
deferData->compilationUnit->release();
delete deferData;
it = deferredData.erase(it);
} else {
Expand Down Expand Up @@ -1751,10 +1761,7 @@ void QQmlData::destroyed(QObject *object)
if (bindings && !bindings->ref.deref())
delete bindings;

if (compilationUnit) {
compilationUnit->release();
compilationUnit = 0;
}
compilationUnit = nullptr;

releaseDeferredData();

Expand Down
3 changes: 0 additions & 3 deletions src/qml/qml/qqmlobjectcreator.cpp
Expand Up @@ -203,10 +203,7 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
if (instance) {
QQmlData *ddata = QQmlData::get(instance);
Q_ASSERT(ddata);
if (ddata->compilationUnit)
ddata->compilationUnit->release();
ddata->compilationUnit = compilationUnit;
ddata->compilationUnit->addref();
}

if (topLevelCreator)
Expand Down
2 changes: 1 addition & 1 deletion src/qml/qml/qqmlobjectcreator_p.h
Expand Up @@ -137,7 +137,7 @@ class Q_QML_PRIVATE_EXPORT QQmlObjectCreator

QQmlEngine *engine;
QV4::ExecutionEngine *v4;
QV4::CompiledData::CompilationUnit *compilationUnit;
QQmlRefPointer<QV4::CompiledData::CompilationUnit> compilationUnit;
const QV4::CompiledData::Unit *qmlUnit;
QQmlGuardedContextData parentContext;
QQmlContextData *context;
Expand Down

0 comments on commit 5b0a98f

Please sign in to comment.