Improve memory usage of Connections and signal handlers.
authorMichael Brasser <michael.brasser@nokia.com>
Mon, 14 May 2012 05:51:28 +0000 (15:51 +1000)
committerQt by Nokia <qt-info@nokia.com>
Fri, 18 May 2012 00:24:35 +0000 (02:24 +0200)
Following the pattern of 330152354aed8496ac78d145e14b25ee2d7bf8fb, store
the source as Utf8. Keep one less copy of the source when possible.

Change-Id: Ifa5f5fdc9ea3d48e904489dc262145eff36e710c
Reviewed-by: Chris Adams <christopher.adams@nokia.com>
src/qml/qml/qqmlboundsignal.cpp
src/qml/qml/qqmlboundsignal_p.h
src/quick/util/qquickconnections.cpp

index 629c8a5..8f15e0a 100644 (file)
@@ -72,7 +72,10 @@ QQmlBoundSignalExpression::QQmlBoundSignalExpression(QQmlContextData *ctxt, QObj
     setNotifyOnValueChanged(false);
     setContext(ctxt);
     setScopeObject(scope);
-    m_expression = QString::fromUtf8(expression);
+    if (isRewritten)
+        m_expressionUtf8 = expression;
+    else
+        m_expression = QString::fromUtf8(expression);
     m_expressionFunctionValid = false;
     m_expressionFunctionRewritten = isRewritten;
     m_fileName = fileName;
@@ -87,7 +90,10 @@ QQmlBoundSignalExpression::QQmlBoundSignalExpression(QQmlContextData *ctxt, QObj
     setNotifyOnValueChanged(false);
     setContext(ctxt);
     setScopeObject(scope);
-    m_expression = expression;
+    if (isRewritten)
+        m_expressionUtf8 = expression.toUtf8();
+    else
+        m_expression = expression;
     m_expressionFunctionValid = false;
     m_expressionFunctionRewritten = isRewritten;
     m_fileName = fileName;
@@ -104,7 +110,7 @@ QQmlBoundSignalExpression::~QQmlBoundSignalExpression()
 QString QQmlBoundSignalExpression::expressionIdentifier(QQmlJavaScriptExpression *e)
 {
     QQmlBoundSignalExpression *This = static_cast<QQmlBoundSignalExpression *>(e);
-    return QLatin1Char('"') + This->m_expression + QLatin1Char('"');
+    return This->sourceFile() + QLatin1Char(':') + QString::number(This->lineNumber());
 }
 
 void QQmlBoundSignalExpression::expressionChanged(QQmlJavaScriptExpression *)
@@ -112,6 +118,20 @@ void QQmlBoundSignalExpression::expressionChanged(QQmlJavaScriptExpression *)
     // bound signals do not notify on change.
 }
 
+QString QQmlBoundSignalExpression::expression() const
+{
+    if (m_expressionFunctionValid) {
+        Q_ASSERT (context() && engine());
+        v8::HandleScope handle_scope;
+        v8::Context::Scope context_scope(QQmlEnginePrivate::get(engine())->v8engine()->context());
+        return QV8Engine::toStringStatic(m_v8function->ToString());
+    } else if (!m_expressionUtf8.isEmpty()) {
+        return QString::fromUtf8(m_expressionUtf8);
+    } else {
+        return m_expression;
+    }
+}
+
 // This mirrors code in QQmlExpressionPrivate::value() and v8value().
 // Any change made here should be made there and vice versa.
 void QQmlBoundSignalExpression::evaluate(QObject *secondaryScope)
@@ -124,18 +144,19 @@ void QQmlBoundSignalExpression::evaluate(QObject *secondaryScope)
         v8::HandleScope handle_scope;
         v8::Context::Scope context_scope(ep->v8engine()->context());
         if (!m_expressionFunctionValid) {
-            bool ok = true;
-            QString code;
+
             if (m_expressionFunctionRewritten) {
-                code = m_expression;
+                m_v8function = evalFunction(context(), scopeObject(), m_expressionUtf8, m_fileName, m_line, &m_v8qmlscope);
+                m_expressionUtf8.clear();
             } else {
+                bool ok = true;
                 QQmlRewrite::RewriteSignalHandler rewriteSignalHandler;
-                code = rewriteSignalHandler(m_expression, m_functionName, &ok);
+                const QString &code = rewriteSignalHandler(m_expression, QString()/*no name hint available*/, &ok);
+                if (ok)
+                    m_v8function = evalFunction(context(), scopeObject(), code, m_fileName, m_line, &m_v8qmlscope);
+                m_expression.clear();
             }
 
-            if (ok)
-                m_v8function = evalFunction(context(), scopeObject(), code, m_fileName, m_line, &m_v8qmlscope);
-
             if (m_v8function.IsEmpty() || m_v8function->IsNull()) {
                 ep->dereferenceScarceResources();
                 return; // could not evaluate function.  Not valid.
index a810600..f9159ee 100644 (file)
@@ -83,7 +83,7 @@ public:
     QString sourceFile() const { return m_fileName; }
     int lineNumber() const { return m_line; }
     int columnNumber() const { return m_column; }
-    QString expression() const { return m_expression; }
+    QString expression() const;
 
     QQmlEngine *engine() const { return context() ? context()->engine : 0; }
 
@@ -93,8 +93,12 @@ private:
     v8::Persistent<v8::Object> m_v8qmlscope;
     v8::Persistent<v8::Function> m_v8function;
 
-    QString m_expression;
-    QString m_functionName; // hint for debugger
+    //either expressionUtf8 or expression will be used (but not both).
+    //once m_v8function is valid, we clear both expressions, and
+    //extract it from m_v8function if needed.
+    QByteArray m_expressionUtf8;
+    QString m_expression;   //only used when expression needs to be rewritten
+
     QString m_fileName;
     int m_line;
     int m_column;
index 2257761..d3c3361 100644 (file)
@@ -236,7 +236,7 @@ QQmlConnectionsParser::compile(const QList<QQmlCustomParserProperty> &props)
                 QQmlScript::Variant v = qvariant_cast<QQmlScript::Variant>(value);
                 if (v.isScript()) {
                     ds << propName;
-                    ds << rewriteSignalHandler(v, propName);
+                    ds << rewriteSignalHandler(v, propName).toUtf8();
                     ds << propLine;
                     ds << propColumn;
                 } else {
@@ -269,7 +269,7 @@ void QQuickConnections::connectSignals()
     while (!ds.atEnd()) {
         QString propName;
         ds >> propName;
-        QString script;
+        QByteArray script;
         ds >> script;
         int line;
         ds >> line;