aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2012-05-18 11:11:40 +0100
committerQt by Nokia <qt-info@nokia.com>2012-05-24 17:49:58 +0200
commit72ac68162e4ab94bb2b62e047a726c119f77df13 (patch)
treee8f1bc56ef27347837426b10cb1abb5079cdf9cf /src/qml/qml
parent59ddedfb6faf040eb052ee25ed7154de1b05eb2c (diff)
Reduce size of QQmlNotifierEndpoint
Change-Id: I4d4a22f5f3d88d4ad2fcd738753fd8da2d8a9263 Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
Diffstat (limited to 'src/qml/qml')
-rw-r--r--src/qml/qml/qqmlboundsignal.cpp4
-rw-r--r--src/qml/qml/qqmlboundsignal_p.h4
-rw-r--r--src/qml/qml/qqmlengine_p.h3
-rw-r--r--src/qml/qml/qqmljavascriptexpression.cpp8
-rw-r--r--src/qml/qml/qqmljavascriptexpression_p.h12
-rw-r--r--src/qml/qml/qqmlnotifier.cpp46
-rw-r--r--src/qml/qml/qqmlnotifier_p.h73
-rw-r--r--src/qml/qml/qqmlvmemetaobject.cpp4
-rw-r--r--src/qml/qml/v4/qv4bindings.cpp10
-rw-r--r--src/qml/qml/v4/qv4bindings_p.h5
10 files changed, 108 insertions, 61 deletions
diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp
index 1a16c07a75..bc8ce07efe 100644
--- a/src/qml/qml/qqmlboundsignal.cpp
+++ b/src/qml/qml/qqmlboundsignal.cpp
@@ -249,7 +249,7 @@ QQmlBoundSignal::QQmlBoundSignal(QObject *scope, int signal, QObject *owner,
setParamsValid(false);
setIsEvaluating(false);
addToObject(owner);
- callback = &subscriptionCallback;
+ setCallback(QQmlNotifierEndpoint::QQmlBoundSignal);
/*
If this is a cloned method, connect to the 'original'. For example,
@@ -318,7 +318,7 @@ QQmlBoundSignalExpressionPointer QQmlBoundSignal::takeExpression(QQmlBoundSignal
return rv;
}
-void QQmlBoundSignal::subscriptionCallback(QQmlNotifierEndpoint *e, void **a)
+void QQmlBoundSignal_callback(QQmlNotifierEndpoint *e, void **a)
{
QQmlBoundSignal *s = static_cast<QQmlBoundSignal*>(e);
if (!s->m_expression)
diff --git a/src/qml/qml/qqmlboundsignal_p.h b/src/qml/qml/qqmlboundsignal_p.h
index b7f3e5f885..81bcb0bc06 100644
--- a/src/qml/qml/qqmlboundsignal_p.h
+++ b/src/qml/qml/qqmlboundsignal_p.h
@@ -147,11 +147,11 @@ public:
QQmlBoundSignalExpressionPointer takeExpression(QQmlBoundSignalExpression *);
QObject *scope() { return *m_scope; }
- static void subscriptionCallback(QQmlNotifierEndpoint *e, void **);
-
bool isEvaluating() const { return m_scope.flag(); }
private:
+ friend void QQmlBoundSignal_callback(QQmlNotifierEndpoint *, void **);
+
QQmlBoundSignalExpressionPointer m_expression;
QQmlBoundSignalParameters *m_params;
// We store some flag bits in the following flag pointer.
diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h
index 0631fe09ca..4518ba8bf3 100644
--- a/src/qml/qml/qqmlengine_p.h
+++ b/src/qml/qml/qqmlengine_p.h
@@ -103,13 +103,12 @@ class QDir;
class QQmlIncubator;
// This needs to be declared here so that the pool for it can live in QQmlEnginePrivate.
-// The inline method definitions are in qqmlexpression_p.h
+// The inline method definitions are in qqmljavascriptexpression_p.h
class QQmlJavaScriptExpressionGuard : public QQmlNotifierEndpoint
{
public:
inline QQmlJavaScriptExpressionGuard(QQmlJavaScriptExpression *);
- static inline void endpointCallback(QQmlNotifierEndpoint *, void **);
static inline QQmlJavaScriptExpressionGuard *New(QQmlJavaScriptExpression *e,
QQmlEngine *engine);
inline void Delete();
diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp
index 5b1261b1eb..d0218822d4 100644
--- a/src/qml/qml/qqmljavascriptexpression.cpp
+++ b/src/qml/qml/qqmljavascriptexpression.cpp
@@ -368,4 +368,12 @@ void QQmlJavaScriptExpression::clearGuards()
g->Delete();
}
+void QQmlJavaScriptExpressionGuard_callback(QQmlNotifierEndpoint *e, void **)
+{
+ QQmlJavaScriptExpression *expression =
+ static_cast<QQmlJavaScriptExpressionGuard *>(e)->expression;
+
+ expression->m_vtable->expressionChanged(expression);
+}
+
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmljavascriptexpression_p.h b/src/qml/qml/qqmljavascriptexpression_p.h
index 12be382f6a..4208584d47 100644
--- a/src/qml/qml/qqmljavascriptexpression_p.h
+++ b/src/qml/qml/qqmljavascriptexpression_p.h
@@ -146,7 +146,7 @@ protected:
private:
typedef QQmlJavaScriptExpressionGuard Guard;
- friend class QQmlJavaScriptExpressionGuard;
+ friend void QQmlJavaScriptExpressionGuard_callback(QQmlNotifierEndpoint *, void **);
struct GuardCapture : public QQmlEnginePrivate::PropertyCapture {
GuardCapture(QQmlEngine *engine, QQmlJavaScriptExpression *e)
@@ -253,15 +253,7 @@ bool QQmlJavaScriptExpression::hasDelayedError() const
QQmlJavaScriptExpressionGuard::QQmlJavaScriptExpressionGuard(QQmlJavaScriptExpression *e)
: expression(e), next(0)
{
- callback = &endpointCallback;
-}
-
-void QQmlJavaScriptExpressionGuard::endpointCallback(QQmlNotifierEndpoint *e, void **)
-{
- QQmlJavaScriptExpression *expression =
- static_cast<QQmlJavaScriptExpressionGuard *>(e)->expression;
-
- expression->m_vtable->expressionChanged(expression);
+ setCallback(QQmlNotifierEndpoint::QQmlJavaScriptExpressionGuard);
}
QQmlJavaScriptExpressionGuard *
diff --git a/src/qml/qml/qqmlnotifier.cpp b/src/qml/qml/qqmlnotifier.cpp
index 2bae7f64b0..7cbc5e6f72 100644
--- a/src/qml/qml/qqmlnotifier.cpp
+++ b/src/qml/qml/qqmlnotifier.cpp
@@ -46,27 +46,47 @@
QT_BEGIN_NAMESPACE
+typedef void (*Callback)(QQmlNotifierEndpoint *, void **);
+
+void QQmlBoundSignal_callback(QQmlNotifierEndpoint *, void **);
+void QQmlJavaScriptExpressionGuard_callback(QQmlNotifierEndpoint *, void **);
+void QQmlVMEMetaObjectEndpoint_callback(QQmlNotifierEndpoint *, void **);
+void QV4BindingsSubscription_callback(QQmlNotifierEndpoint *, void **);
+
+static Callback QQmlNotifier_callbacks[] = {
+ 0,
+ QQmlBoundSignal_callback,
+ QQmlJavaScriptExpressionGuard_callback,
+ QQmlVMEMetaObjectEndpoint_callback,
+ QV4BindingsSubscription_callback
+};
+
void QQmlNotifier::emitNotify(QQmlNotifierEndpoint *endpoint, void **a)
{
- QQmlNotifierEndpoint **oldDisconnected = endpoint->disconnected;
- endpoint->disconnected = &endpoint;
- endpoint->notifying = 1;
+ intptr_t originalSenderPtr;
+ intptr_t *disconnectWatch;
+
+ if (!endpoint->isNotifying()) {
+ originalSenderPtr = endpoint->senderPtr;
+ disconnectWatch = &originalSenderPtr;
+ endpoint->senderPtr = intptr_t(disconnectWatch) | 0x1;
+ } else {
+ disconnectWatch = (intptr_t *)(endpoint->senderPtr & ~0x1);
+ }
if (endpoint->next)
emitNotify(endpoint->next, a);
- if (endpoint) {
+ if (*disconnectWatch) {
- Q_ASSERT(endpoint->callback);
-
- endpoint->callback(endpoint, a);
+ Q_ASSERT(QQmlNotifier_callbacks[endpoint->callback]);
+ QQmlNotifier_callbacks[endpoint->callback](endpoint, a);
- if (endpoint)
- endpoint->disconnected = oldDisconnected;
+ if (disconnectWatch == &originalSenderPtr && originalSenderPtr) {
+ // End of notifying, restore values
+ endpoint->senderPtr = originalSenderPtr;
+ }
}
-
- if (oldDisconnected) *oldDisconnected = endpoint;
- else if (endpoint) endpoint->notifying = 0;
}
void QQmlNotifierEndpoint::connect(QObject *source, int sourceSignal, QQmlEngine *engine)
@@ -89,7 +109,7 @@ void QQmlNotifierEndpoint::connect(QObject *source, int sourceSignal, QQmlEngine
qPrintable(engineName));
}
- this->source = source;
+ senderPtr = intptr_t(source);
this->sourceSignal = sourceSignal;
QQmlPropertyPrivate::flushSignal(source, sourceSignal);
QQmlData *ddata = QQmlData::get(source, true);
diff --git a/src/qml/qml/qqmlnotifier_p.h b/src/qml/qml/qqmlnotifier_p.h
index e942861a89..49bf9eddac 100644
--- a/src/qml/qml/qqmlnotifier_p.h
+++ b/src/qml/qml/qqmlnotifier_p.h
@@ -70,8 +70,19 @@ public:
inline QQmlNotifierEndpoint();
inline ~QQmlNotifierEndpoint();
- typedef void (*Callback)(QQmlNotifierEndpoint *, void **);
- Callback callback;
+ // QQmlNotifierEndpoint can only invoke one of a set of pre-defined callbacks.
+ // To add another callback, extend this enum and add the callback to the top
+ // of qqmlnotifier.cpp. Four bits are reserved for the callback, so there can
+ // be up to 15 of them (0 is reserved).
+ enum Callback {
+ None = 0,
+ QQmlBoundSignal = 1,
+ QQmlJavaScriptExpressionGuard = 2,
+ QQmlVMEMetaObjectEndpoint = 3,
+ QV4BindingsSubscription = 4
+ };
+
+ inline void setCallback(Callback c) { callback = c; }
inline bool isConnected();
inline bool isConnected(QObject *source, int sourceSignal);
@@ -88,13 +99,16 @@ private:
friend class QQmlData;
friend class QQmlNotifier;
- union {
- QQmlNotifier *notifier;
- QObject *source;
- };
- unsigned int notifying : 1;
- signed int sourceSignal : 31;
- QQmlNotifierEndpoint **disconnected;
+ // Contains either the QObject*, or the QQmlNotifier* that this
+ // endpoint is connected to. While the endpoint is notifying, the
+ // senderPtr points to another intptr_t that contains this value.
+ intptr_t senderPtr;
+ inline QObject *senderAsObject() const;
+ inline QQmlNotifier *senderAsNotifier() const;
+
+ Callback callback:4;
+ signed int sourceSignal:28;
+
QQmlNotifierEndpoint *next;
QQmlNotifierEndpoint **prev;
};
@@ -111,12 +125,12 @@ QQmlNotifier::~QQmlNotifier()
QQmlNotifierEndpoint *n = endpoint;
endpoint = n->next;
+ if (n->isNotifying()) *((intptr_t *)(n->senderPtr & ~0x1)) = 0;
+
n->next = 0;
n->prev = 0;
- n->notifier = 0;
+ n->senderPtr = 0;
n->sourceSignal = -1;
- if (n->disconnected) *n->disconnected = 0;
- n->disconnected = 0;
}
endpoints = 0;
}
@@ -128,7 +142,7 @@ void QQmlNotifier::notify()
}
QQmlNotifierEndpoint::QQmlNotifierEndpoint()
-: callback(0), notifier(0), notifying(0), sourceSignal(-1), disconnected(0), next(0), prev(0)
+: senderPtr(0), callback(None), sourceSignal(-1), next(0), prev(0)
{
}
@@ -144,12 +158,13 @@ bool QQmlNotifierEndpoint::isConnected()
bool QQmlNotifierEndpoint::isConnected(QObject *source, int sourceSignal)
{
- return this->sourceSignal != -1 && this->source == source && this->sourceSignal == sourceSignal;
+ return this->sourceSignal != -1 && senderAsObject() == source &&
+ this->sourceSignal == sourceSignal;
}
bool QQmlNotifierEndpoint::isConnected(QQmlNotifier *notifier)
{
- return sourceSignal == -1 && this->notifier == notifier;
+ return sourceSignal == -1 && senderAsNotifier() == notifier;
}
void QQmlNotifierEndpoint::connect(QQmlNotifier *notifier)
@@ -160,19 +175,17 @@ void QQmlNotifierEndpoint::connect(QQmlNotifier *notifier)
if (next) { next->prev = &next; }
notifier->endpoints = this;
prev = &notifier->endpoints;
- this->notifier = notifier;
+ senderPtr = intptr_t(notifier);
}
void QQmlNotifierEndpoint::disconnect()
{
if (next) next->prev = prev;
if (prev) *prev = next;
- if (disconnected) *disconnected = 0;
+ if (isNotifying()) *((intptr_t *)(senderPtr & ~0x1)) = 0;
next = 0;
prev = 0;
- disconnected = 0;
- notifier = 0;
- notifying = 0;
+ senderPtr = 0;
sourceSignal = -1;
}
@@ -185,7 +198,7 @@ An in progress notify can be cancelled by calling cancelNotify.
*/
bool QQmlNotifierEndpoint::isNotifying() const
{
- return notifying == 1;
+ return senderPtr & 0x1;
}
/*!
@@ -193,13 +206,23 @@ Cancel any notifies that are in progress.
*/
void QQmlNotifierEndpoint::cancelNotify()
{
- notifying = 0;
- if (disconnected) {
- *disconnected = 0;
- disconnected = 0;
+ if (isNotifying()) {
+ intptr_t sp = *((intptr_t *)(senderPtr & ~0x1));
+ *((intptr_t *)(senderPtr & ~0x1)) = 0;
+ senderPtr = sp;
}
}
+QObject *QQmlNotifierEndpoint::senderAsObject() const
+{
+ return isNotifying()?((QObject *)(*((intptr_t *)(senderPtr & ~0x1)))):((QObject *)senderPtr);
+}
+
+QQmlNotifier *QQmlNotifierEndpoint::senderAsNotifier() const
+{
+ return isNotifying()?((QQmlNotifier *)(*((intptr_t *)(senderPtr & ~0x1)))):((QQmlNotifier *)senderPtr);
+}
+
QT_END_NAMESPACE
#endif // QQMLNOTIFIER_P_H
diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp
index e0d797269c..50fda6db39 100644
--- a/src/qml/qml/qqmlvmemetaobject.cpp
+++ b/src/qml/qml/qqmlvmemetaobject.cpp
@@ -446,10 +446,10 @@ void QQmlVMEVariant::ensureValueType(int t)
QQmlVMEMetaObjectEndpoint::QQmlVMEMetaObjectEndpoint()
{
- callback = &vmecallback;
+ setCallback(QQmlNotifierEndpoint::QQmlVMEMetaObjectEndpoint);
}
-void QQmlVMEMetaObjectEndpoint::vmecallback(QQmlNotifierEndpoint *e, void **)
+void QQmlVMEMetaObjectEndpoint_callback(QQmlNotifierEndpoint *e, void **)
{
QQmlVMEMetaObjectEndpoint *vmee = static_cast<QQmlVMEMetaObjectEndpoint*>(e);
vmee->tryConnect();
diff --git a/src/qml/qml/v4/qv4bindings.cpp b/src/qml/qml/v4/qv4bindings.cpp
index 95eb0b9984..39b571f336 100644
--- a/src/qml/qml/v4/qv4bindings.cpp
+++ b/src/qml/qml/v4/qv4bindings.cpp
@@ -349,9 +349,15 @@ void QV4Bindings::Binding::retargetBinding(QObject *t, int i)
target.value().targetProperty = i;
}
-void QV4Bindings::Subscription::subscriptionCallback(QQmlNotifierEndpoint *e, void **)
+QV4Bindings::Subscription::Subscription()
+: bindings(0), method(-1)
{
- Subscription *s = static_cast<Subscription *>(e);
+ setCallback(QQmlNotifierEndpoint::QV4BindingsSubscription);
+}
+
+void QV4BindingsSubscription_callback(QQmlNotifierEndpoint *e, void **)
+{
+ QV4Bindings::Subscription *s = static_cast<QV4Bindings::Subscription *>(e);
s->bindings->subscriptionNotify(s->method);
}
diff --git a/src/qml/qml/v4/qv4bindings_p.h b/src/qml/qml/v4/qv4bindings_p.h
index be58e02358..d2d8520a83 100644
--- a/src/qml/qml/v4/qv4bindings_p.h
+++ b/src/qml/qml/v4/qv4bindings_p.h
@@ -117,12 +117,11 @@ private:
class Subscription : public QQmlNotifierEndpoint
{
public:
- Subscription() : bindings(0), method(-1) { callback = &subscriptionCallback; }
- static void subscriptionCallback(QQmlNotifierEndpoint *e, void**);
+ inline Subscription();
QV4Bindings *bindings;
int method;
};
- friend class Subscription;
+ friend void QV4BindingsSubscription_callback(QQmlNotifierEndpoint *e, void **);
Subscription *subscriptions;