From 2d2580838d580edbac22a2cf906a4d6da2d670ef Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Mon, 14 May 2012 15:51:28 +1000 Subject: [PATCH] Improve memory usage of Connections and signal handlers. 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 --- src/qml/qml/qqmlboundsignal.cpp | 41 +++++++++++++++++++++++++++--------- src/qml/qml/qqmlboundsignal_p.h | 10 ++++++--- src/quick/util/qquickconnections.cpp | 4 ++-- 3 files changed, 40 insertions(+), 15 deletions(-) diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp index 629c8a5..8f15e0a 100644 --- a/src/qml/qml/qqmlboundsignal.cpp +++ b/src/qml/qml/qqmlboundsignal.cpp @@ -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(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. diff --git a/src/qml/qml/qqmlboundsignal_p.h b/src/qml/qml/qqmlboundsignal_p.h index a810600..f9159ee 100644 --- a/src/qml/qml/qqmlboundsignal_p.h +++ b/src/qml/qml/qqmlboundsignal_p.h @@ -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 m_v8qmlscope; v8::Persistent 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; diff --git a/src/quick/util/qquickconnections.cpp b/src/quick/util/qquickconnections.cpp index 2257761..d3c3361 100644 --- a/src/quick/util/qquickconnections.cpp +++ b/src/quick/util/qquickconnections.cpp @@ -236,7 +236,7 @@ QQmlConnectionsParser::compile(const QList &props) QQmlScript::Variant v = qvariant_cast(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; -- 2.7.4