summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2010-01-08 09:02:10 (GMT)
committerAaron Kennedy <aaron.kennedy@nokia.com>2010-01-08 09:02:10 (GMT)
commit8c84f7ca274e5c8e4d249ede904bb247659dbce4 (patch)
tree58e7553b5a417c87e61cb0ba95319123344d0f32 /src
parentb30af554ba34bddc4f2487f037113c810597cda0 (diff)
downloadQt-8c84f7ca274e5c8e4d249ede904bb247659dbce4.zip
Qt-8c84f7ca274e5c8e4d249ede904bb247659dbce4.tar.gz
Qt-8c84f7ca274e5c8e4d249ede904bb247659dbce4.tar.bz2
Optimization: Cache compiled dynamic functions
Diffstat (limited to 'src')
-rw-r--r--src/declarative/qml/qmlcompiler.cpp15
-rw-r--r--src/declarative/qml/qmlcontext.cpp2
-rw-r--r--src/declarative/qml/qmlcontext_p.h1
-rw-r--r--src/declarative/qml/qmlengine.cpp5
-rw-r--r--src/declarative/qml/qmlexpression.cpp32
-rw-r--r--src/declarative/qml/qmlexpression_p.h2
-rw-r--r--src/declarative/qml/qmlvmemetaobject.cpp61
-rw-r--r--src/declarative/qml/qmlvmemetaobject_p.h10
8 files changed, 81 insertions, 47 deletions
diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp
index 7f11a23..7c43305 100644
--- a/src/declarative/qml/qmlcompiler.cpp
+++ b/src/declarative/qml/qmlcompiler.cpp
@@ -2341,13 +2341,24 @@ bool QmlCompiler::buildDynamicMeta(QmlParser::Object *obj, DynamicMetaMode mode)
}
for (int ii = 0; ii < obj->dynamicSlots.count(); ++ii) {
- const Object::DynamicSlot &s = obj->dynamicSlots.at(ii);
+ Object::DynamicSlot &s = obj->dynamicSlots[ii];
QByteArray sig(s.name + '(');
+ QString funcScript(QLatin1String("(function("));
+
for (int jj = 0; jj < s.parameterNames.count(); ++jj) {
- if (jj) sig.append(',');
+ if (jj) {
+ sig.append(',');
+ funcScript.append(QLatin1Char(','));
+ }
+ funcScript.append(s.parameterNames.at(jj));
sig.append("QVariant");
}
sig.append(')');
+ funcScript.append(QLatin1Char(')'));
+ funcScript.append(s.body);
+ funcScript.append(QLatin1Char(')'));
+ s.body = funcScript;
+
QMetaMethodBuilder b = builder.addSlot(sig);
b.setReturnType("QVariant");
b.setParameterNames(s.parameterNames);
diff --git a/src/declarative/qml/qmlcontext.cpp b/src/declarative/qml/qmlcontext.cpp
index e063981..e7ac864 100644
--- a/src/declarative/qml/qmlcontext.cpp
+++ b/src/declarative/qml/qmlcontext.cpp
@@ -57,7 +57,7 @@
QT_BEGIN_NAMESPACE
QmlContextPrivate::QmlContextPrivate()
-: parent(0), engine(0), isInternal(false), isTemporary(false), propertyNames(0),
+: parent(0), engine(0), isInternal(false), propertyNames(0),
notifyIndex(-1), highPriorityCount(0), imports(0), expressions(0), contextObjects(0),
idValues(0), idValueCount(0), optimizedBindings(0)
{
diff --git a/src/declarative/qml/qmlcontext_p.h b/src/declarative/qml/qmlcontext_p.h
index cb89474..e682ee2 100644
--- a/src/declarative/qml/qmlcontext_p.h
+++ b/src/declarative/qml/qmlcontext_p.h
@@ -88,7 +88,6 @@ public:
QmlEngine *engine;
bool isInternal;
- bool isTemporary;
QmlIntegerCache *propertyNames;
QList<QVariant> propertyValues;
diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp
index 708cdd1..19a20e8 100644
--- a/src/declarative/qml/qmlengine.cpp
+++ b/src/declarative/qml/qmlengine.cpp
@@ -649,10 +649,7 @@ QmlContext *QmlEnginePrivate::getContext(QScriptContext *ctxt)
QScriptValue scopeNode = QScriptDeclarativeClass::scopeChainValue(ctxt, -3);
Q_ASSERT(scopeNode.isValid());
Q_ASSERT(QScriptDeclarativeClass::scriptClass(scopeNode) == contextClass);
- QmlContext *context = contextClass->contextFromValue(scopeNode);
- while (context && QmlContextPrivate::get(context)->isTemporary)
- context = context->parentContext();
- return context;
+ return contextClass->contextFromValue(scopeNode);
}
QScriptValue QmlEnginePrivate::createComponent(QScriptContext *ctxt,
diff --git a/src/declarative/qml/qmlexpression.cpp b/src/declarative/qml/qmlexpression.cpp
index 1321601..1587d61 100644
--- a/src/declarative/qml/qmlexpression.cpp
+++ b/src/declarative/qml/qmlexpression.cpp
@@ -138,19 +138,13 @@ void QmlExpressionPrivate::init(QmlContext *ctxt, void *expr, QmlRefCount *rc,
dd->cachedPrograms[progIdx] =
new QScriptProgram(data->expression, data->url, data->line);
}
-#endif
-
- QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine);
- scriptContext->pushScope(ep->contextClass->newContext(ctxt, me));
-#if !defined(Q_OS_SYMBIAN)
- data->expressionFunction = scriptEngine->evaluate(*dd->cachedPrograms.at(progIdx));
+ data->expressionFunction = evalInObjectScope(ctxt, me, *dd->cachedPrograms.at(progIdx));
#else
- data->expressionFunction = scriptEngine->evaluate(data->expression);
+ data->expressionFunction = evalInObjectScope(ctxt, me, data->expression);
#endif
data->expressionFunctionValid = true;
- scriptEngine->popContext();
}
}
@@ -158,6 +152,28 @@ void QmlExpressionPrivate::init(QmlContext *ctxt, void *expr, QmlRefCount *rc,
data->me = me;
}
+QScriptValue QmlExpressionPrivate::evalInObjectScope(QmlContext *context, QObject *object,
+ const QString &program)
+{
+ QmlEnginePrivate *ep = QmlEnginePrivate::get(context->engine());
+ QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(&ep->scriptEngine);
+ scriptContext->pushScope(ep->contextClass->newContext(context, object));
+ QScriptValue rv = ep->scriptEngine.evaluate(program);
+ ep->scriptEngine.popContext();
+ return rv;
+}
+
+QScriptValue QmlExpressionPrivate::evalInObjectScope(QmlContext *context, QObject *object,
+ const QScriptProgram &program)
+{
+ QmlEnginePrivate *ep = QmlEnginePrivate::get(context->engine());
+ QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(&ep->scriptEngine);
+ scriptContext->pushScope(ep->contextClass->newContext(context, object));
+ QScriptValue rv = ep->scriptEngine.evaluate(program);
+ ep->scriptEngine.popContext();
+ return rv;
+}
+
/*!
\class QmlExpression
\brief The QmlExpression class evaluates ECMAScript in a QML context.
diff --git a/src/declarative/qml/qmlexpression_p.h b/src/declarative/qml/qmlexpression_p.h
index 3f87b2f..8561a57 100644
--- a/src/declarative/qml/qmlexpression_p.h
+++ b/src/declarative/qml/qmlexpression_p.h
@@ -164,6 +164,8 @@ public:
}
static void exceptionToError(QScriptEngine *, QmlError &);
+ static QScriptValue evalInObjectScope(QmlContext *, QObject *, const QString &);
+ static QScriptValue evalInObjectScope(QmlContext *, QObject *, const QScriptProgram &);
};
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmlvmemetaobject.cpp b/src/declarative/qml/qmlvmemetaobject.cpp
index 3b1f068..fd699c3 100644
--- a/src/declarative/qml/qmlvmemetaobject.cpp
+++ b/src/declarative/qml/qmlvmemetaobject.cpp
@@ -44,6 +44,7 @@
#include "qml.h"
#include "qmlrefcount_p.h"
#include "qmlexpression.h"
+#include "qmlexpression_p.h"
#include "qmlcontext_p.h"
#include <QColor>
@@ -56,11 +57,11 @@ QT_BEGIN_NAMESPACE
QmlVMEMetaObject::QmlVMEMetaObject(QObject *obj,
const QMetaObject *other,
const QmlVMEMetaData *meta,
- QmlRefCount *rc)
-: object(obj), ref(rc), ctxt(qmlContext(obj)), metaData(meta), parent(0)
+ QmlCompiledData *cdata)
+: object(obj), compiledData(cdata), ctxt(qmlContext(obj)), metaData(meta), methods(0),
+ parent(0)
{
- if (ref)
- ref->addref();
+ compiledData->addref();
*static_cast<QMetaObject *>(this) = *other;
this->d.superdata = obj->metaObject();
@@ -91,12 +92,11 @@ QmlVMEMetaObject::QmlVMEMetaObject(QObject *obj,
QmlVMEMetaObject::~QmlVMEMetaObject()
{
- if (ref)
- ref->release();
- if (parent)
- delete parent;
+ compiledData->release();
+ delete parent;
qDeleteAll(listProperties);
delete [] data;
+ delete [] methods;
}
int QmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
@@ -260,29 +260,36 @@ int QmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
id -= plainSignals;
if (id < metaData->methodCount) {
+ if (!ctxt->engine())
+ return -1; // We can't run the method
+
+ QmlEnginePrivate *ep = QmlEnginePrivate::get(ctxt->engine());
+
+ if (!methods)
+ methods = new QScriptValue[metaData->methodCount];
+
QmlVMEMetaData::MethodData *data = metaData->methodData() + id;
- const QChar *body =
- (const QChar *)(((const char*)metaData) + data->bodyOffset);
+ if (!methods[id].isValid()) {
+ const QChar *body =
+ (const QChar *)(((const char*)metaData) + data->bodyOffset);
- QString code = QString::fromRawData(body, data->bodyLength);
+ QString code = QString::fromRawData(body, data->bodyLength);
- QVariant rv;
- if (0 == (metaData->methodData() + id)->parameterCount) {
- QmlExpression expr(ctxt, code, object);
- expr.setTrackChange(false);
- rv = expr.value();
- } else {
- QmlContext newCtxt(ctxt);
- QmlContextPrivate::get(&newCtxt)->isTemporary = true;
- QMetaMethod m = method(_id);
- QList<QByteArray> names = m.parameterNames();
- for (int ii = 0; ii < names.count(); ++ii)
- newCtxt.setContextProperty(QString::fromLatin1(names.at(ii)), *(QVariant *)a[ii + 1]);
- QmlExpression expr(&newCtxt, code, object);
- expr.setTrackChange(false);
- rv = expr.value();
+ // XXX Use QScriptProgram
+ methods[id] = QmlExpressionPrivate::evalInObjectScope(ctxt, object, code);
}
- if (a[0]) *reinterpret_cast<QVariant *>(a[0]) = rv;
+
+ QScriptValueList args;
+ if (data->parameterCount) {
+ for (int ii = 0; ii < data->parameterCount; ++ii) {
+ args << ep->scriptValueFromVariant(*(QVariant *)a[ii + 1]);
+ }
+ }
+ QScriptValue rv = methods[id].call(ep->scriptEngine.globalObject(), args);
+
+ if (a[0]) *reinterpret_cast<QVariant *>(a[0]) = ep->scriptValueToVariant(rv);
+
+ return -1;
}
return -1;
}
diff --git a/src/declarative/qml/qmlvmemetaobject_p.h b/src/declarative/qml/qmlvmemetaobject_p.h
index 462f652..b79e42c 100644
--- a/src/declarative/qml/qmlvmemetaobject_p.h
+++ b/src/declarative/qml/qmlvmemetaobject_p.h
@@ -62,6 +62,7 @@
#include <private/qobject_p.h>
#include "qmlguard_p.h"
+#include "qmlcompiler_p.h"
QT_BEGIN_NAMESPACE
@@ -88,7 +89,7 @@ struct QmlVMEMetaData
int parameterCount;
int bodyOffset;
int bodyLength;
- int _dummy;
+ int scriptProgram;
};
PropertyData *propertyData() const {
@@ -108,8 +109,8 @@ class QmlRefCount;
class QmlVMEMetaObject : public QAbstractDynamicMetaObject
{
public:
- QmlVMEMetaObject(QObject *, const QMetaObject *, const QmlVMEMetaData *data,
- QmlRefCount * = 0);
+ QmlVMEMetaObject(QObject *obj, const QMetaObject *other, const QmlVMEMetaData *data,
+ QmlCompiledData *compiledData);
~QmlVMEMetaObject();
void registerInterceptor(int index, int valueIndex, QmlPropertyValueInterceptor *interceptor);
@@ -119,7 +120,7 @@ protected:
private:
QObject *object;
- QmlRefCount *ref;
+ QmlCompiledData *compiledData;
QmlGuard<QmlContext> ctxt;
const QmlVMEMetaData *metaData;
@@ -130,6 +131,7 @@ private:
QBitArray aConnected;
QBitArray aInterceptors;
QHash<int, QPair<int, QmlPropertyValueInterceptor*> > interceptors;
+ QScriptValue *methods;
QAbstractDynamicMetaObject *parent;