aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2014-02-06 16:33:15 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-02-07 12:44:10 +0100
commit324ae0d7d99ef9f7159d29b2e0e7eabe5f8a43a4 (patch)
tree9576687c7580065e819392a3be6250dcf6e0c07c /src/qml
parent50ce88a53107f97664d928719c1877b8077e9a2e (diff)
[new compiler] Allow for interruption during object finalization
The object tree construction and binding allocation remains synchronous, but the initial evaluation of the bindings is now cooperatively interruptible again, like in the VME. Change-Id: Idd037dd481782c81ad43e20e93d922eb12ac8b85 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/qml/qqmlcomponent.cpp3
-rw-r--r--src/qml/qml/qqmlincubator.cpp14
-rw-r--r--src/qml/qml/qqmlincubator_p.h4
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp19
-rw-r--r--src/qml/qml/qqmlobjectcreator_p.h3
-rw-r--r--src/qml/qml/qqmlvme.cpp8
-rw-r--r--src/qml/qml/qqmlvme_p.h52
7 files changed, 50 insertions, 53 deletions
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index bf87a9dd2d..cc7ea57602 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -914,7 +914,8 @@ void QQmlComponentPrivate::complete(QQmlEnginePrivate *enginePriv, ConstructionS
{
if (state->completePending) {
if (enginePriv->useNewCompiler) {
- state->creator->finalize();
+ QQmlInstantiationInterrupt interrupt;
+ state->creator->finalize(interrupt);
} else {
state->vme.complete();
}
diff --git a/src/qml/qml/qqmlincubator.cpp b/src/qml/qml/qqmlincubator.cpp
index 10fd05ab58..de8eab7bd2 100644
--- a/src/qml/qml/qqmlincubator.cpp
+++ b/src/qml/qml/qqmlincubator.cpp
@@ -91,7 +91,7 @@ void QQmlEnginePrivate::incubate(QQmlIncubator &i, QQmlContextData *forContext)
p->changeStatus(QQmlIncubator::Loading);
if (!watcher.hasRecursed()) {
- QQmlVME::Interrupt i;
+ QQmlInstantiationInterrupt i;
p->incubate(i);
}
} else {
@@ -254,7 +254,7 @@ void QQmlIncubationController::incubatingObjectCountChanged(int incubatingObject
Q_UNUSED(incubatingObjectCount);
}
-void QQmlIncubatorPrivate::forceCompletion(QQmlVME::Interrupt &i)
+void QQmlIncubatorPrivate::forceCompletion(QQmlInstantiationInterrupt &i)
{
while (QQmlIncubator::Loading == status) {
while (QQmlIncubator::Loading == status && !waitingFor.isEmpty())
@@ -264,7 +264,7 @@ void QQmlIncubatorPrivate::forceCompletion(QQmlVME::Interrupt &i)
}
}
-void QQmlIncubatorPrivate::incubate(QQmlVME::Interrupt &i)
+void QQmlIncubatorPrivate::incubate(QQmlInstantiationInterrupt &i)
{
if (!compiledData)
return;
@@ -345,7 +345,7 @@ void QQmlIncubatorPrivate::incubate(QQmlVME::Interrupt &i)
QQmlContextData *ctxt = 0;
if (enginePriv->useNewCompiler)
- ctxt = creator->finalize();
+ ctxt = creator->finalize(i);
else
ctxt = vme.complete(i);
if (ctxt) {
@@ -391,7 +391,7 @@ void QQmlIncubationController::incubateFor(int msecs)
if (!d || !d->incubatorCount)
return;
- QQmlVME::Interrupt i(msecs * 1000000);
+ QQmlInstantiationInterrupt i(msecs * 1000000);
i.reset();
do {
static_cast<QQmlIncubatorPrivate*>(d->incubatorList.first())->incubate(i);
@@ -410,7 +410,7 @@ void QQmlIncubationController::incubateWhile(volatile bool *flag, int msecs)
if (!d || !d->incubatorCount)
return;
- QQmlVME::Interrupt i(flag, msecs * 1000000);
+ QQmlInstantiationInterrupt i(flag, msecs * 1000000);
i.reset();
do {
static_cast<QQmlIncubatorPrivate*>(d->incubatorList.first())->incubate(i);
@@ -609,7 +609,7 @@ returns, the incubator will not be in the Loading state.
*/
void QQmlIncubator::forceCompletion()
{
- QQmlVME::Interrupt i;
+ QQmlInstantiationInterrupt i;
d->forceCompletion(i);
}
diff --git a/src/qml/qml/qqmlincubator_p.h b/src/qml/qml/qqmlincubator_p.h
index a8b549bd28..b7009bfe43 100644
--- a/src/qml/qml/qqmlincubator_p.h
+++ b/src/qml/qml/qqmlincubator_p.h
@@ -104,8 +104,8 @@ public:
void clear();
- void forceCompletion(QQmlVME::Interrupt &i);
- void incubate(QQmlVME::Interrupt &i);
+ void forceCompletion(QQmlInstantiationInterrupt &i);
+ void incubate(QQmlInstantiationInterrupt &i);
};
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 2b69955dde..faeb3753ea 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -1048,13 +1048,16 @@ QObject *QmlObjectCreator::createInstance(int index, QObject *parent)
return result ? instance : 0;
}
-QQmlContextData *QmlObjectCreator::finalize()
+QQmlContextData *QmlObjectCreator::finalize(QQmlInstantiationInterrupt &interrupt)
{
{
QQmlTrace trace("VME Binding Enable");
trace.event("begin binding eval");
while (!allCreatedBindings->isEmpty()) {
+ if (interrupt.shouldInterrupt())
+ return 0;
+
QQmlAbstractBinding *b = allCreatedBindings->pop();
if (!b)
continue;
@@ -1077,10 +1080,8 @@ QQmlContextData *QmlObjectCreator::finalize()
status->componentComplete();
}
- #if 0 // ###
- if (watcher.hasRecursed() || interrupt.shouldInterrupt())
- return 0;
- #endif
+ if (interrupt.shouldInterrupt())
+ return 0;
}
}
@@ -1093,10 +1094,6 @@ QQmlContextData *QmlObjectCreator::finalize()
void *args[] = { 0 };
QMetaObject::metacall(obj, QMetaObject::InvokeMetaMethod, callback.second, args);
}
-#if 0 // ###
- if (watcher.hasRecursed())
- return 0;
-#endif
}
finalizeCallbacks.clear();
}
@@ -1113,10 +1110,8 @@ QQmlContextData *QmlObjectCreator::finalize()
// ### designer if (componentCompleteEnabled())
emit a->completed();
-#if 0 // ###
- if (watcher.hasRecursed() || interrupt.shouldInterrupt())
+ if (interrupt.shouldInterrupt())
return 0;
-#endif
}
}
diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h
index cb23f61c84..7ed75670c2 100644
--- a/src/qml/qml/qqmlobjectcreator_p.h
+++ b/src/qml/qml/qqmlobjectcreator_p.h
@@ -52,6 +52,7 @@ QT_BEGIN_NAMESPACE
class QQmlAbstractBinding;
struct QQmlTypeCompiler;
+class QQmlInstantiationInterrupt;
class QmlObjectCreator
{
@@ -62,7 +63,7 @@ public:
~QmlObjectCreator();
QObject *create(int subComponentIndex = -1, QObject *parent = 0);
- QQmlContextData *finalize();
+ QQmlContextData *finalize(QQmlInstantiationInterrupt &interrupt);
QQmlComponentAttached *componentAttached;
QList<QQmlEnginePrivate::FinalizeCallback> finalizeCallbacks;
diff --git a/src/qml/qml/qqmlvme.cpp b/src/qml/qml/qqmlvme.cpp
index 58d656a846..7d521192ad 100644
--- a/src/qml/qml/qqmlvme.cpp
+++ b/src/qml/qml/qqmlvme.cpp
@@ -184,7 +184,7 @@ struct ActiveVMERestorer
};
}
-QObject *QQmlVME::execute(QList<QQmlError> *errors, const Interrupt &interrupt)
+QObject *QQmlVME::execute(QList<QQmlError> *errors, const QQmlInstantiationInterrupt &interrupt)
{
Q_ASSERT(states.count() >= 1);
@@ -330,7 +330,7 @@ static QV4::ExecutionContext *qmlBindingContext(QQmlEngine *engine, QV4::Executi
removeBindingOnProperty(o, index)
QObject *QQmlVME::run(QList<QQmlError> *errors,
- const Interrupt &interrupt
+ const QQmlInstantiationInterrupt &interrupt
#ifdef QML_THREADED_VME_INTERPRETER
, void * const **storeJumpTable
#endif
@@ -1134,14 +1134,14 @@ void *const *QQmlVME::instructionJumpTable()
static void * const *jumpTable = 0;
if (!jumpTable) {
QQmlVME dummy;
- QQmlVME::Interrupt i;
+ QQmlInstantiationInterrupt i;
dummy.run(0, i, &jumpTable);
}
return jumpTable;
}
#endif
-QQmlContextData *QQmlVME::complete(const Interrupt &interrupt)
+QQmlContextData *QQmlVME::complete(const QQmlInstantiationInterrupt &interrupt)
{
Q_ASSERT(engine ||
(bindValues.isEmpty() &&
diff --git a/src/qml/qml/qqmlvme_p.h b/src/qml/qml/qqmlvme_p.h
index d26812a68f..5025653524 100644
--- a/src/qml/qml/qqmlvme_p.h
+++ b/src/qml/qml/qqmlvme_p.h
@@ -102,28 +102,28 @@ Q_DECLARE_TYPEINFO(QQmlVMETypes::List, Q_PRIMITIVE_TYPE | Q_MOVABLE_TYPE);
template<>
class QTypeInfo<QQmlVMETypes::State> : public QTypeInfoMerger<QQmlVMETypes::State, QBitField> {}; //Q_DECLARE_TYPEINFO
+class QQmlInstantiationInterrupt {
+public:
+ inline QQmlInstantiationInterrupt();
+ inline QQmlInstantiationInterrupt(volatile bool *runWhile, int nsecs=0);
+ inline QQmlInstantiationInterrupt(int nsecs);
+
+ inline void reset();
+ inline bool shouldInterrupt() const;
+private:
+ enum Mode { None, Time, Flag };
+ Mode mode;
+ struct {
+ QElapsedTimer timer;
+ int nsecs;
+ };
+ volatile bool *runWhile;
+};
+
class Q_QML_PRIVATE_EXPORT QQmlVME
{
Q_DECLARE_TR_FUNCTIONS(QQmlVME)
public:
- class Interrupt {
- public:
- inline Interrupt();
- inline Interrupt(volatile bool *runWhile, int nsecs=0);
- inline Interrupt(int nsecs);
-
- inline void reset();
- inline bool shouldInterrupt() const;
- private:
- enum Mode { None, Time, Flag };
- Mode mode;
- struct {
- QElapsedTimer timer;
- int nsecs;
- };
- volatile bool *runWhile;
- };
-
QQmlVME() : data(0), componentAttached(0) {}
QQmlVME(void *data) : data(data), componentAttached(0) {}
@@ -136,8 +136,8 @@ public:
bool initDeferred(QObject *);
void reset();
- QObject *execute(QList<QQmlError> *errors, const Interrupt & = Interrupt());
- QQmlContextData *complete(const Interrupt & = Interrupt());
+ QObject *execute(QList<QQmlError> *errors, const QQmlInstantiationInterrupt & = QQmlInstantiationInterrupt());
+ QQmlContextData *complete(const QQmlInstantiationInterrupt & = QQmlInstantiationInterrupt());
static void enableComponentComplete();
static void disableComponentComplete();
@@ -146,7 +146,7 @@ public:
private:
friend class QQmlVMEGuard;
- QObject *run(QList<QQmlError> *errors, const Interrupt &
+ QObject *run(QList<QQmlError> *errors, const QQmlInstantiationInterrupt &
#ifdef QML_THREADED_VME_INTERPRETER
, void *const**storeJumpTable = 0
#endif
@@ -207,28 +207,28 @@ private:
QQmlGuardedContextData *m_contexts;
};
-QQmlVME::Interrupt::Interrupt()
+QQmlInstantiationInterrupt::QQmlInstantiationInterrupt()
: mode(None), nsecs(0), runWhile(0)
{
}
-QQmlVME::Interrupt::Interrupt(volatile bool *runWhile, int nsecs)
+QQmlInstantiationInterrupt::QQmlInstantiationInterrupt(volatile bool *runWhile, int nsecs)
: mode(Flag), nsecs(nsecs), runWhile(runWhile)
{
}
-QQmlVME::Interrupt::Interrupt(int nsecs)
+QQmlInstantiationInterrupt::QQmlInstantiationInterrupt(int nsecs)
: mode(Time), nsecs(nsecs), runWhile(0)
{
}
-void QQmlVME::Interrupt::reset()
+void QQmlInstantiationInterrupt::reset()
{
if (mode == Time || nsecs)
timer.start();
}
-bool QQmlVME::Interrupt::shouldInterrupt() const
+bool QQmlInstantiationInterrupt::shouldInterrupt() const
{
if (mode == None) {
return false;