aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative/qml/v4
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2011-10-10 13:52:34 +1000
committerQt by Nokia <qt-info@nokia.com>2011-10-12 01:31:11 +0200
commit0466acb02740b5dbf3254d6445186b4d3ccd0699 (patch)
treea1b7314c2faae73cf93403afdc7ca92f2106d70d /src/declarative/qml/v4
parent3422d4adda7480a44a063ab86447c2fe2792fe02 (diff)
Optimize signal handling
Bindings connect to lots of signals that are never emitted. By managing signal connection lists ourselves, we can do a much better job than Qt's generic signal/slot connection logic. Also, by connecting to QDeclarativeNotifierEndpoint's rather than QObject slots, we can eliminate the need to instantiate a QObject for the V4 and V8 binding managers. Change-Id: I598667deaefdbd2860227bd74378a1b196761686 Reviewed-on: http://codereview.qt-project.org/6278 Reviewed-by: Aaron Kennedy <aaron.kennedy@nokia.com> Sanity-Review: Aaron Kennedy <aaron.kennedy@nokia.com>
Diffstat (limited to 'src/declarative/qml/v4')
-rw-r--r--src/declarative/qml/v4/qdeclarativev4bindings.cpp206
-rw-r--r--src/declarative/qml/v4/qdeclarativev4bindings_p.h70
2 files changed, 119 insertions, 157 deletions
diff --git a/src/declarative/qml/v4/qdeclarativev4bindings.cpp b/src/declarative/qml/v4/qdeclarativev4bindings.cpp
index 7aa5496403..df2ce7bf00 100644
--- a/src/declarative/qml/v4/qdeclarativev4bindings.cpp
+++ b/src/declarative/qml/v4/qdeclarativev4bindings.cpp
@@ -187,92 +187,18 @@ void Register::init(Type type)
} // end of anonymous namespace
-class QDeclarativeV4BindingsPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QDeclarativeV4Bindings)
-
-public:
- QDeclarativeV4BindingsPrivate();
- virtual ~QDeclarativeV4BindingsPrivate();
-
- struct Binding : public QDeclarativeAbstractBinding, public QDeclarativeDelayedError {
- Binding() : enabled(false), updating(0), property(0),
- scope(0), target(0), executedBlocks(0), parent(0) {}
-
- // Inherited from QDeclarativeAbstractBinding
- virtual void setEnabled(bool, QDeclarativePropertyPrivate::WriteFlags flags);
- virtual void update(QDeclarativePropertyPrivate::WriteFlags flags);
- virtual void destroy();
-
- int index:30;
- bool enabled:1;
- bool updating:1;
- int property;
- QObject *scope;
- QObject *target;
- quint32 executedBlocks;
-
- QDeclarativeV4BindingsPrivate *parent;
- };
-
- typedef QDeclarativeNotifierEndpoint Subscription;
- Subscription *subscriptions;
-
- void run(Binding *, QDeclarativePropertyPrivate::WriteFlags flags);
-
- QDeclarativeV4Program *program;
- QDeclarativeRefCount *dataRef;
- Binding *bindings;
-
- static int methodCount;
-
- void init();
- void run(int instr, quint32 &executedBlocks, QDeclarativeContextData *context,
- QDeclarativeDelayedError *error, QObject *scope, QObject *output,
- QDeclarativePropertyPrivate::WriteFlags storeFlags
-#ifdef QML_THREADED_INTERPRETER
- , void ***decode_instr = 0
-#endif
- );
-
-
- inline void unsubscribe(int subIndex);
- inline void subscribeId(QDeclarativeContextData *p, int idIndex, int subIndex);
- inline void subscribe(QObject *o, int notifyIndex, int subIndex);
-
- inline static qint32 toInt32(qreal n);
- static const qreal D32;
- static quint32 toUint32(qreal n);
-};
-
-QDeclarativeV4BindingsPrivate::QDeclarativeV4BindingsPrivate()
+QDeclarativeV4Bindings::QDeclarativeV4Bindings(const char *programData,
+ QDeclarativeContextData *context,
+ QDeclarativeRefCount *ref)
: subscriptions(0), program(0), dataRef(0), bindings(0)
{
-}
-
-QDeclarativeV4BindingsPrivate::~QDeclarativeV4BindingsPrivate()
-{
- delete [] subscriptions; subscriptions = 0;
- if (dataRef) dataRef->release();
-}
-
-int QDeclarativeV4BindingsPrivate::methodCount = -1;
-
-QDeclarativeV4Bindings::QDeclarativeV4Bindings(const char *program, QDeclarativeContextData *context,
- QDeclarativeRefCount *dataRef)
-: QObject(*(new QDeclarativeV4BindingsPrivate))
-{
- Q_D(QDeclarativeV4Bindings);
-
- if (d->methodCount == -1)
- d->methodCount = QDeclarativeV4Bindings::staticMetaObject.methodCount();
-
- d->program = (QDeclarativeV4Program *)program;
- d->dataRef = dataRef;
+ program = (QDeclarativeV4Program *)programData;
+ dataRef = ref;
if (dataRef) dataRef->addref();
if (program) {
- d->init();
+ subscriptions = new Subscription[program->subscriptions];
+ bindings = new Binding[program->bindings];
QDeclarativeAbstractExpression::setContext(context);
}
@@ -280,30 +206,28 @@ QDeclarativeV4Bindings::QDeclarativeV4Bindings(const char *program, QDeclarative
QDeclarativeV4Bindings::~QDeclarativeV4Bindings()
{
- Q_D(QDeclarativeV4Bindings);
-
- delete [] d->bindings;
+ delete [] bindings;
+ delete [] subscriptions; subscriptions = 0;
+ if (dataRef) dataRef->release();
}
QDeclarativeAbstractBinding *QDeclarativeV4Bindings::configBinding(int index, QObject *target,
- QObject *scope, int property)
+ QObject *scope, int property)
{
- Q_D(QDeclarativeV4Bindings);
-
- QDeclarativeV4BindingsPrivate::Binding *rv = d->bindings + index;
+ Binding *rv = bindings + index;
rv->index = index;
rv->property = property;
rv->target = target;
rv->scope = scope;
- rv->parent = d;
+ rv->parent = this;
addref(); // This is decremented in Binding::destroy()
return rv;
}
-void QDeclarativeV4BindingsPrivate::Binding::setEnabled(bool e, QDeclarativePropertyPrivate::WriteFlags flags)
+void QDeclarativeV4Bindings::Binding::setEnabled(bool e, QDeclarativePropertyPrivate::WriteFlags flags)
{
if (enabled != e) {
enabled = e;
@@ -312,50 +236,47 @@ void QDeclarativeV4BindingsPrivate::Binding::setEnabled(bool e, QDeclarativeProp
}
}
-void QDeclarativeV4BindingsPrivate::Binding::update(QDeclarativePropertyPrivate::WriteFlags flags)
+void QDeclarativeV4Bindings::Binding::update(QDeclarativePropertyPrivate::WriteFlags flags)
{
QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Binding);
parent->run(this, flags);
QDeclarativeDebugTrace::endRange(QDeclarativeDebugTrace::Binding);
}
-void QDeclarativeV4BindingsPrivate::Binding::destroy()
+void QDeclarativeV4Bindings::Binding::destroy()
{
enabled = false;
removeFromObject();
clear();
removeError();
- parent->q_func()->release();
+ parent->release();
}
-int QDeclarativeV4Bindings::qt_metacall(QMetaObject::Call c, int id, void **)
+void QDeclarativeV4Bindings::Subscription::subscriptionCallback(QDeclarativeNotifierEndpoint *e)
{
- Q_D(QDeclarativeV4Bindings);
-
- if (c == QMetaObject::InvokeMetaMethod && id >= d->methodCount) {
- id -= d->methodCount;
+ Subscription *s = static_cast<Subscription *>(e);
+ s->bindings->subscriptionNotify(s->method);
+}
- QDeclarativeV4Program::BindingReferenceList *list = d->program->signalTable(id);
+void QDeclarativeV4Bindings::subscriptionNotify(int id)
+{
+ QDeclarativeV4Program::BindingReferenceList *list = program->signalTable(id);
- for (quint32 ii = 0; ii < list->count; ++ii) {
- QDeclarativeV4Program::BindingReference *bindingRef = list->bindings + ii;
+ for (quint32 ii = 0; ii < list->count; ++ii) {
+ QDeclarativeV4Program::BindingReference *bindingRef = list->bindings + ii;
- QDeclarativeV4BindingsPrivate::Binding *binding = d->bindings + bindingRef->binding;
- if (binding->executedBlocks & bindingRef->blockMask)
- d->run(binding, QDeclarativePropertyPrivate::DontRemoveBinding);
- }
+ Binding *binding = bindings + bindingRef->binding;
+ if (binding->executedBlocks & bindingRef->blockMask)
+ run(binding, QDeclarativePropertyPrivate::DontRemoveBinding);
}
- return -1;
}
-void QDeclarativeV4BindingsPrivate::run(Binding *binding, QDeclarativePropertyPrivate::WriteFlags flags)
+void QDeclarativeV4Bindings::run(Binding *binding, QDeclarativePropertyPrivate::WriteFlags flags)
{
- Q_Q(QDeclarativeV4Bindings);
-
if (!binding->enabled)
return;
- QDeclarativeContextData *context = q->QDeclarativeAbstractExpression::context();
+ QDeclarativeContextData *context = QDeclarativeAbstractExpression::context();
if (!context || !context->isValid())
return;
@@ -373,7 +294,7 @@ void QDeclarativeV4BindingsPrivate::run(Binding *binding, QDeclarativePropertyPr
} else {
name = QLatin1String(binding->target->metaObject()->property(binding->property).name());
}
- qmlInfo(binding->target) << QCoreApplication::translate("QDeclarativeV4Bindings", "Binding loop detected for property \"%1\"").arg(name);
+ qmlInfo(binding->target) << tr("Binding loop detected for property \"%1\"").arg(name);
return;
}
@@ -396,33 +317,29 @@ void QDeclarativeV4BindingsPrivate::run(Binding *binding, QDeclarativePropertyPr
}
-void QDeclarativeV4BindingsPrivate::unsubscribe(int subIndex)
+void QDeclarativeV4Bindings::unsubscribe(int subIndex)
{
- QDeclarativeV4BindingsPrivate::Subscription *sub = (subscriptions + subIndex);
+ Subscription *sub = (subscriptions + subIndex);
sub->disconnect();
}
-void QDeclarativeV4BindingsPrivate::subscribeId(QDeclarativeContextData *p, int idIndex, int subIndex)
+void QDeclarativeV4Bindings::subscribeId(QDeclarativeContextData *p, int idIndex, int subIndex)
{
- Q_Q(QDeclarativeV4Bindings);
-
unsubscribe(subIndex);
if (p->idValues[idIndex]) {
- QDeclarativeV4BindingsPrivate::Subscription *sub = (subscriptions + subIndex);
- sub->target = q;
- sub->targetMethod = methodCount + subIndex;
+ Subscription *sub = (subscriptions + subIndex);
+ sub->bindings = this;
+ sub->method = subIndex;
sub->connect(&p->idValues[idIndex].bindings);
}
}
-void QDeclarativeV4BindingsPrivate::subscribe(QObject *o, int notifyIndex, int subIndex)
+void QDeclarativeV4Bindings::subscribe(QObject *o, int notifyIndex, int subIndex)
{
- Q_Q(QDeclarativeV4Bindings);
-
- QDeclarativeV4BindingsPrivate::Subscription *sub = (subscriptions + subIndex);
- sub->target = q;
- sub->targetMethod = methodCount + subIndex;
+ Subscription *sub = (subscriptions + subIndex);
+ sub->bindings = this;
+ sub->method = subIndex;
if (o)
sub->connect(o, notifyIndex);
else
@@ -507,14 +424,6 @@ inline static QUrl toUrl(Register *reg, int type, QDeclarativeContextData *conte
return base;
}
-void QDeclarativeV4BindingsPrivate::init()
-{
- if (program->subscriptions)
- subscriptions = new QDeclarativeV4BindingsPrivate::Subscription[program->subscriptions];
-
- bindings = new QDeclarativeV4BindingsPrivate::Binding[program->bindings];
-}
-
static bool testCompareVariants(const QVariant &qtscriptRaw, const QVariant &v4)
{
QVariant qtscript = qtscriptRaw;
@@ -680,9 +589,9 @@ static void throwException(int id, QDeclarativeDelayedError *error,
QDeclarativeEnginePrivate::warning(context->engine, error->error);
}
-const qreal QDeclarativeV4BindingsPrivate::D32 = 4294967296.0;
+const qreal QDeclarativeV4Bindings::D32 = 4294967296.0;
-qint32 QDeclarativeV4BindingsPrivate::toInt32(qreal n)
+qint32 QDeclarativeV4Bindings::toInt32(qreal n)
{
if (qIsNaN(n) || qIsInf(n) || (n == 0))
return 0;
@@ -702,7 +611,7 @@ qint32 QDeclarativeV4BindingsPrivate::toInt32(qreal n)
return qint32 (n);
}
-inline quint32 QDeclarativeV4BindingsPrivate::toUint32(qreal n)
+inline quint32 QDeclarativeV4Bindings::toUint32(qreal n)
{
if (qIsNaN(n) || qIsInf(n) || (n == 0))
return 0;
@@ -751,25 +660,24 @@ void **QDeclarativeV4Bindings::getDecodeInstrTable()
if (!decode_instr) {
QDeclarativeV4Bindings *dummy = new QDeclarativeV4Bindings(0, 0, 0);
quint32 executedBlocks = 0;
- dummy->d_func()->run(0, executedBlocks, 0, 0, 0, 0,
- QDeclarativePropertyPrivate::BypassInterceptor,
- &decode_instr);
+ dummy->run(0, executedBlocks, 0, 0, 0, 0,
+ QDeclarativePropertyPrivate::BypassInterceptor,
+ &decode_instr);
dummy->release();
}
return decode_instr;
}
#endif
-void QDeclarativeV4BindingsPrivate::run(int instrIndex, quint32 &executedBlocks,
- QDeclarativeContextData *context, QDeclarativeDelayedError *error,
- QObject *scope, QObject *output, QDeclarativePropertyPrivate::WriteFlags storeFlags
+void QDeclarativeV4Bindings::run(int instrIndex, quint32 &executedBlocks,
+ QDeclarativeContextData *context, QDeclarativeDelayedError *error,
+ QObject *scope, QObject *output,
+ QDeclarativePropertyPrivate::WriteFlags storeFlags
#ifdef QML_THREADED_INTERPRETER
- ,void ***table
+ ,void ***table
#endif
- )
+ )
{
- Q_Q(QDeclarativeV4Bindings);
-
#ifdef QML_THREADED_INTERPRETER
if (table) {
static void *decode_instr[] = {
@@ -840,11 +748,11 @@ void QDeclarativeV4BindingsPrivate::run(int instrIndex, quint32 &executedBlocks,
reg.setUndefined();
} else {
int subIdx = instr->fetchAndSubscribe.subscription;
- QDeclarativeV4BindingsPrivate::Subscription *sub = 0;
+ Subscription *sub = 0;
if (subIdx != -1) {
sub = (subscriptions + subIdx);
- sub->target = q;
- sub->targetMethod = methodCount + subIdx;
+ sub->bindings = this;
+ sub->method = subIdx;
}
reg.init((Register::Type)instr->fetchAndSubscribe.valueType);
if (instr->fetchAndSubscribe.valueType >= FirstCleanupType)
diff --git a/src/declarative/qml/v4/qdeclarativev4bindings_p.h b/src/declarative/qml/v4/qdeclarativev4bindings_p.h
index c0345ea3c4..d69d75b835 100644
--- a/src/declarative/qml/v4/qdeclarativev4bindings_p.h
+++ b/src/declarative/qml/v4/qdeclarativev4bindings_p.h
@@ -61,28 +61,82 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-class QDeclarativeV4BindingsPrivate;
-class QDeclarativeV4Bindings : public QObject,
- public QDeclarativeAbstractExpression,
+class QDeclarativeV4Program;
+class QDeclarativeV4Bindings : public QDeclarativeAbstractExpression,
public QDeclarativeRefCount
{
+ Q_DECLARE_TR_FUNCTIONS(QDeclarativeV4Bindings)
public:
QDeclarativeV4Bindings(const char *program, QDeclarativeContextData *context,
QDeclarativeRefCount *);
virtual ~QDeclarativeV4Bindings();
- QDeclarativeAbstractBinding *configBinding(int index, QObject *target, QObject *scope, int property);
+ QDeclarativeAbstractBinding *configBinding(int index, QObject *target,
+ QObject *scope, int property);
#ifdef QML_THREADED_INTERPRETER
static void **getDecodeInstrTable();
#endif
-protected:
- int qt_metacall(QMetaObject::Call, int, void **);
-
private:
Q_DISABLE_COPY(QDeclarativeV4Bindings)
- Q_DECLARE_PRIVATE(QDeclarativeV4Bindings)
+
+ struct Binding : public QDeclarativeAbstractBinding, public QDeclarativeDelayedError {
+ Binding() : enabled(false), updating(0), property(0),
+ scope(0), target(0), executedBlocks(0), parent(0) {}
+
+ // Inherited from QDeclarativeAbstractBinding
+ virtual void setEnabled(bool, QDeclarativePropertyPrivate::WriteFlags flags);
+ virtual void update(QDeclarativePropertyPrivate::WriteFlags flags);
+ virtual void destroy();
+
+ int index:30;
+ bool enabled:1;
+ bool updating:1;
+ int property;
+ QObject *scope;
+ QObject *target;
+ quint32 executedBlocks;
+
+ QDeclarativeV4Bindings *parent;
+ };
+
+ struct Subscription : public QDeclarativeNotifierEndpoint
+ {
+ Subscription() : bindings(0), method(-1) { callback = &subscriptionCallback; }
+ static void subscriptionCallback(QDeclarativeNotifierEndpoint *e);
+ QDeclarativeV4Bindings *bindings;
+ int method;
+ };
+ friend class Subscription;
+
+ Subscription *subscriptions;
+
+ void subscriptionNotify(int);
+ void run(Binding *, QDeclarativePropertyPrivate::WriteFlags flags);
+
+ QDeclarativeV4Program *program;
+ QDeclarativeRefCount *dataRef;
+ Binding *bindings;
+
+ void init();
+ void run(int instr, quint32 &executedBlocks, QDeclarativeContextData *context,
+ QDeclarativeDelayedError *error, QObject *scope, QObject *output,
+ QDeclarativePropertyPrivate::WriteFlags storeFlags
+#ifdef QML_THREADED_INTERPRETER
+ , void ***decode_instr = 0
+#endif
+ );
+
+
+ inline void unsubscribe(int subIndex);
+ inline void subscribeId(QDeclarativeContextData *p, int idIndex, int subIndex);
+ inline void subscribe(QObject *o, int notifyIndex, int subIndex);
+
+ inline static qint32 toInt32(qreal n);
+ static const qreal D32;
+ static quint32 toUint32(qreal n);
+
};
QT_END_NAMESPACE