Reduce memory by not calling QUrl::toString() multiple times
authorAaron Kennedy <aaron.kennedy@nokia.com>
Thu, 16 Feb 2012 14:10:12 +0000 (14:10 +0000)
committerQt by Nokia <qt-info@nokia.com>
Mon, 20 Feb 2012 15:25:40 +0000 (16:25 +0100)
Change-Id: I57ce25f4e20cac048ff507a8c195b83adc30040d
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
13 files changed:
src/declarative/qml/qdeclarativecompiler.cpp
src/declarative/qml/qdeclarativecontext.cpp
src/declarative/qml/qdeclarativecontext_p.h
src/declarative/qml/qdeclarativeimport.cpp
src/declarative/qml/qdeclarativeimport_p.h
src/declarative/qml/qdeclarativescript.cpp
src/declarative/qml/qdeclarativescript_p.h
src/declarative/qml/qdeclarativetypeloader.cpp
src/declarative/qml/qdeclarativetypeloader_p.h
src/declarative/qml/qdeclarativevme.cpp
src/declarative/qml/qdeclarativevmemetaobject.cpp
src/declarative/qml/v4/qv4bindings.cpp
src/quick/util/qdeclarativeconnections.cpp

index abaf5cb..c4efc85 100644 (file)
@@ -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();
index 3e0db16..1029929 100644 (file)
@@ -464,6 +464,7 @@ void QDeclarativeContext::setBaseUrl(const QUrl &baseUrl)
     Q_D(QDeclarativeContext);
 
     d->data->url = baseUrl;
+    d->data->urlString = baseUrl.toString();
 }
 
 /*!
index dab0016..c53fc9c 100644 (file)
@@ -163,6 +163,7 @@ public:
 
     // Context base url
     QUrl url;
+    QString urlString;
 
     // List of imports that apply to this context
     QDeclarativeTypeNameCache *imports;
index 8bdcef9..a8d9035 100644 (file)
@@ -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;
+    }
 }
 
 /*!
index 64ea8fc..6dae0f3 100644 (file)
@@ -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,
index 48384ce..7a2247f 100644 (file)
@@ -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);
index c103247..86fc1c5 100644 (file)
@@ -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<TypeReference*> referencedTypes() const;
 
index a65de06..a9dc46e 100644 (file)
@@ -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) {
index 80016c9..85fe45e 100644 (file)
@@ -113,6 +113,7 @@ public:
 
     QUrl url() const;
     QUrl finalUrl() const;
+    QString finalUrlString() const;
 
     QList<QDeclarativeError> 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<QDeclarativeDataBlob *> m_waitingOnMe;
@@ -355,6 +357,7 @@ public:
     ~QDeclarativeScriptData();
 
     QUrl url;
+    QString urlString;
     QDeclarativeTypeNameCache *importCache;
     QList<QDeclarativeScriptBlob *> scripts;
     QDeclarativeScript::Object::ScriptBlock::Pragmas pragmas;
index 6f323e4..254ae5d 100644 (file)
@@ -420,6 +420,7 @@ QObject *QDeclarativeVME::run(QList<QDeclarativeError> *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<v8::Script> 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<v8::Object> 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.
index de8863a..2520bc4 100644 (file)
@@ -796,8 +796,9 @@ v8::Handle<v8::Function> 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);
     }
 
index 93f5bb4..2c26fff 100644 (file)
@@ -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;
index e128e2e..c98c87a 100644 (file)
@@ -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 ?