From d1c2fb2e33f687ca883c67bcd5e0d73d1de32bdc Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 16 Feb 2012 14:10:12 +0000 Subject: [PATCH] Reduce memory by not calling QUrl::toString() multiple times Change-Id: I57ce25f4e20cac048ff507a8c195b83adc30040d Reviewed-by: Roberto Raggi --- src/declarative/qml/qdeclarativecompiler.cpp | 2 +- src/declarative/qml/qdeclarativecontext.cpp | 1 + src/declarative/qml/qdeclarativecontext_p.h | 1 + src/declarative/qml/qdeclarativeimport.cpp | 10 +++++++- src/declarative/qml/qdeclarativeimport_p.h | 2 +- src/declarative/qml/qdeclarativescript.cpp | 13 ++++++++--- src/declarative/qml/qdeclarativescript_p.h | 3 +- src/declarative/qml/qdeclarativetypeloader.cpp | 23 ++++++++++++++++---- src/declarative/qml/qdeclarativetypeloader_p.h | 3 ++ src/declarative/qml/qdeclarativevme.cpp | 5 ++- src/declarative/qml/qdeclarativevmemetaobject.cpp | 5 ++- src/declarative/qml/v4/qv4bindings.cpp | 2 +- src/quick/util/qdeclarativeconnections.cpp | 2 +- 13 files changed, 52 insertions(+), 20 deletions(-) diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index abaf5cb..c4efc85 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -1644,7 +1644,7 @@ int QDeclarativeCompiler::translationContextIndex() { if (cachedTranslationContextIndex == -1) { // This code must match that in the qsTr() implementation - QString path = output->url.toString(); + const QString &path = output->name; int lastSlash = path.lastIndexOf(QLatin1Char('/')); QString context = (lastSlash > -1) ? path.mid(lastSlash + 1, path.length()-lastSlash-5) : QString(); diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp index 3e0db16..1029929 100644 --- a/src/declarative/qml/qdeclarativecontext.cpp +++ b/src/declarative/qml/qdeclarativecontext.cpp @@ -464,6 +464,7 @@ void QDeclarativeContext::setBaseUrl(const QUrl &baseUrl) Q_D(QDeclarativeContext); d->data->url = baseUrl; + d->data->urlString = baseUrl.toString(); } /*! diff --git a/src/declarative/qml/qdeclarativecontext_p.h b/src/declarative/qml/qdeclarativecontext_p.h index dab0016..c53fc9c 100644 --- a/src/declarative/qml/qdeclarativecontext_p.h +++ b/src/declarative/qml/qdeclarativecontext_p.h @@ -163,6 +163,7 @@ public: // Context base url QUrl url; + QString urlString; // List of imports that apply to this context QDeclarativeTypeNameCache *imports; diff --git a/src/declarative/qml/qdeclarativeimport.cpp b/src/declarative/qml/qdeclarativeimport.cpp index 8bdcef9..a8d9035 100644 --- a/src/declarative/qml/qdeclarativeimport.cpp +++ b/src/declarative/qml/qdeclarativeimport.cpp @@ -171,10 +171,16 @@ QDeclarativeImports::~QDeclarativeImports() /*! Sets the base URL to be used for all relative file imports added. */ -void QDeclarativeImports::setBaseUrl(const QUrl& url) +void QDeclarativeImports::setBaseUrl(const QUrl& url, const QString &urlString) { d->baseUrl = url; - d->base = url.toString(); + + if (urlString.isEmpty()) { + d->base = url.toString(); + } else { + //Q_ASSERT(url.toString() == urlString); + d->base = urlString; + } } /*! diff --git a/src/declarative/qml/qdeclarativeimport_p.h b/src/declarative/qml/qdeclarativeimport_p.h index 64ea8fc..6dae0f3 100644 --- a/src/declarative/qml/qdeclarativeimport_p.h +++ b/src/declarative/qml/qdeclarativeimport_p.h @@ -80,7 +80,7 @@ public: ~QDeclarativeImports(); QDeclarativeImports &operator=(const QDeclarativeImports &); - void setBaseUrl(const QUrl &url); + void setBaseUrl(const QUrl &url, const QString &urlString = QString()); QUrl baseUrl() const; bool resolveType(const QString& type, diff --git a/src/declarative/qml/qdeclarativescript.cpp b/src/declarative/qml/qdeclarativescript.cpp index 48384ce..7a2247f 100644 --- a/src/declarative/qml/qdeclarativescript.cpp +++ b/src/declarative/qml/qdeclarativescript.cpp @@ -1287,12 +1287,17 @@ public: }; } -bool QDeclarativeScript::Parser::parse(const QByteArray &qmldata, const QUrl &url) +bool QDeclarativeScript::Parser::parse(const QByteArray &qmldata, const QUrl &url, + const QString &urlString) { clear(); - const QString fileName = url.toString(); - _scriptFile = fileName; + if (urlString.isEmpty()) { + _scriptFile = url.toString(); + } else { + // Q_ASSERT(urlString == url.toString()); + _scriptFile = urlString; + } QTextStream stream(qmldata, QIODevice::ReadOnly); #ifndef QT_NO_TEXTCODEC @@ -1300,7 +1305,7 @@ bool QDeclarativeScript::Parser::parse(const QByteArray &qmldata, const QUrl &ur #endif QString *code = _pool.NewString(stream.readAll()); - data = new QDeclarativeScript::ParserJsASTData(fileName); + data = new QDeclarativeScript::ParserJsASTData(_scriptFile); Lexer lexer(&data->engine); lexer.setCode(*code, /*line = */ 1); diff --git a/src/declarative/qml/qdeclarativescript_p.h b/src/declarative/qml/qdeclarativescript_p.h index c103247..86fc1c5 100644 --- a/src/declarative/qml/qdeclarativescript_p.h +++ b/src/declarative/qml/qdeclarativescript_p.h @@ -477,7 +477,8 @@ public: Parser(); ~Parser(); - bool parse(const QByteArray &data, const QUrl &url = QUrl()); + bool parse(const QByteArray &data, const QUrl &url = QUrl(), + const QString &urlString = QString()); QList referencedTypes() const; diff --git a/src/declarative/qml/qdeclarativetypeloader.cpp b/src/declarative/qml/qdeclarativetypeloader.cpp index a65de06..a9dc46e 100644 --- a/src/declarative/qml/qdeclarativetypeloader.cpp +++ b/src/declarative/qml/qdeclarativetypeloader.cpp @@ -388,6 +388,18 @@ QUrl QDeclarativeDataBlob::finalUrl() const } /*! +Returns the finalUrl() as a string. +*/ +QString QDeclarativeDataBlob::finalUrlString() const +{ + Q_ASSERT(isCompleteOrError() || (m_manager && m_manager->m_thread->isThisThread())); + if (m_finalUrlString.isEmpty()) + m_finalUrlString = m_finalUrl.toString(); + + return m_finalUrlString; +} + +/*! Return the errors on this blob. May only be called from the load thread, or after the blob isCompleteOrError(). @@ -1508,12 +1520,12 @@ void QDeclarativeTypeData::completed() void QDeclarativeTypeData::dataReceived(const QByteArray &data) { - if (!scriptParser.parse(data, finalUrl())) { + if (!scriptParser.parse(data, finalUrl(), finalUrlString())) { setError(scriptParser.errors()); return; } - m_imports.setBaseUrl(finalUrl()); + m_imports.setBaseUrl(finalUrl(), finalUrlString()); foreach (const QDeclarativeScript::Import &import, scriptParser.imports()) { if (import.type == QDeclarativeScript::Import::File && import.qualifier.isEmpty()) { @@ -1569,8 +1581,8 @@ void QDeclarativeTypeData::compile() QDeclarativeProfilerService::startRange(QDeclarativeProfilerService::Compiling); m_compiledData = new QDeclarativeCompiledData(typeLoader()->engine()); - m_compiledData->url = m_imports.baseUrl(); - m_compiledData->name = m_compiledData->url.toString(); + m_compiledData->url = finalUrl(); + m_compiledData->name = finalUrlString(); QDeclarativeProfilerService::rangeLocation(QDeclarativeProfilerService::Compiling, QUrl(m_compiledData->name),1,1); QDeclarativeProfilerService::rangeData(QDeclarativeProfilerService::Compiling, m_compiledData->name); @@ -1817,7 +1829,7 @@ void QDeclarativeScriptBlob::dataReceived(const QByteArray &data) QDeclarativeScript::Parser::JavaScriptMetaData metadata = QDeclarativeScript::Parser::extractMetaData(m_source); - m_imports.setBaseUrl(finalUrl()); + m_imports.setBaseUrl(finalUrl(), finalUrlString()); m_pragmas = metadata.pragmas; @@ -1881,6 +1893,7 @@ void QDeclarativeScriptBlob::done() QDeclarativeEngine *engine = typeLoader()->engine(); m_scriptData = new QDeclarativeScriptData(); m_scriptData->url = finalUrl(); + m_scriptData->urlString = finalUrlString(); m_scriptData->importCache = new QDeclarativeTypeNameCache(); for (int ii = 0; !isError() && ii < m_scripts.count(); ++ii) { diff --git a/src/declarative/qml/qdeclarativetypeloader_p.h b/src/declarative/qml/qdeclarativetypeloader_p.h index 80016c9..85fe45e 100644 --- a/src/declarative/qml/qdeclarativetypeloader_p.h +++ b/src/declarative/qml/qdeclarativetypeloader_p.h @@ -113,6 +113,7 @@ public: QUrl url() const; QUrl finalUrl() const; + QString finalUrlString() const; QList errors() const; @@ -166,6 +167,7 @@ private: QUrl m_url; QUrl m_finalUrl; + mutable QString m_finalUrlString; // List of QDeclarativeDataBlob's that are waiting for me to complete. QList m_waitingOnMe; @@ -355,6 +357,7 @@ public: ~QDeclarativeScriptData(); QUrl url; + QString urlString; QDeclarativeTypeNameCache *importCache; QList scripts; QDeclarativeScript::Object::ScriptBlock::Pragmas pragmas; diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp index 6f323e4..254ae5d 100644 --- a/src/declarative/qml/qdeclarativevme.cpp +++ b/src/declarative/qml/qdeclarativevme.cpp @@ -420,6 +420,7 @@ QObject *QDeclarativeVME::run(QList *errors, CTXT = new QDeclarativeContextData; CTXT->isInternal = true; CTXT->url = COMP->url; + CTXT->urlString = COMP->name; CTXT->imports = COMP->importCache; CTXT->imports->addref(); CTXT->setParent(parentCtxt); @@ -1085,8 +1086,7 @@ void QDeclarativeScriptData::initialize(QDeclarativeEngine *engine) // If compilation throws an error, a surrounding v8::TryCatch will record it. v8::Local program = v8engine->qmlModeCompile(m_programSource.constData(), - m_programSource.length(), url.toString(), - 1); + m_programSource.length(), urlString, 1); if (program.IsEmpty()) return; @@ -1122,6 +1122,7 @@ v8::Persistent QDeclarativeVME::run(QDeclarativeContextData *parentC else ctxt->isPragmaLibraryContext = parentCtxt->isPragmaLibraryContext; ctxt->url = script->url; + ctxt->urlString = script->urlString; // For backward compatibility, if there are no imports, we need to use the // imports from the parent context. See QTBUG-17518. diff --git a/src/declarative/qml/qdeclarativevmemetaobject.cpp b/src/declarative/qml/qdeclarativevmemetaobject.cpp index de8863a..2520bc4 100644 --- a/src/declarative/qml/qdeclarativevmemetaobject.cpp +++ b/src/declarative/qml/qdeclarativevmemetaobject.cpp @@ -796,8 +796,9 @@ v8::Handle QDeclarativeVMEMetaObject::method(int index) // XXX We should evaluate all methods in a single big script block to // improve the call time between dynamic methods defined on the same // object - v8methods[index] = QDeclarativeExpressionPrivate::evalFunction(ctxt, object, body, bodyLength, - ctxt->url.toString(), + v8methods[index] = QDeclarativeExpressionPrivate::evalFunction(ctxt, object, body, + bodyLength, + ctxt->urlString, data->lineNumber); } diff --git a/src/declarative/qml/v4/qv4bindings.cpp b/src/declarative/qml/v4/qv4bindings.cpp index 93f5bb4..2c26fff 100644 --- a/src/declarative/qml/v4/qv4bindings.cpp +++ b/src/declarative/qml/v4/qv4bindings.cpp @@ -299,7 +299,7 @@ void QV4Bindings::run(Binding *binding, QDeclarativePropertyPrivate::WriteFlags trace.addDetail("Line", binding->line); trace.addDetail("Column", binding->column); - QDeclarativeBindingProfiler prof(context->url.toString(), binding->line, binding->column); + QDeclarativeBindingProfiler prof(context->urlString, binding->line, binding->column); if (binding->updating) { QString name; diff --git a/src/quick/util/qdeclarativeconnections.cpp b/src/quick/util/qdeclarativeconnections.cpp index e128e2e..c98c87a 100644 --- a/src/quick/util/qdeclarativeconnections.cpp +++ b/src/quick/util/qdeclarativeconnections.cpp @@ -277,7 +277,7 @@ void QDeclarativeConnections::connectSignals() if (ddata) { ctxtdata = ddata->outerContext; if (ctxtdata && !ctxtdata->url.isEmpty()) - location = ddata->outerContext->url.toString(); + location = ddata->outerContext->urlString; } QDeclarativeExpression *expression = ctxtdata ? -- 1.7.2.5