Fix profiling of QML/JS compilation
authorUlf Hermann <ulf.hermann@theqtcompany.com>
Tue, 11 Aug 2015 10:47:28 +0000 (12:47 +0200)
committerSimon Hausmann <simon.hausmann@theqtcompany.com>
Mon, 24 Aug 2015 19:24:20 +0000 (19:24 +0000)
The compilation of .js resources was missed and the compile times were
underestimated because the dependency resolution and error checking
wasn't factored in. In particular we only profiled the done() step for
QQmlTypeData. However, JavaScript compilation also occurs in the
dataReceived() step of QQmlScriptBlob and QQmlTypeData will already
parse the program into an AST at that step.

Compile steps can be nested now, but considering the fact that
significant time may be spent before and after compiling dependencies
for a parent module, this seems to be the best way to model them.

Furthermore, in order to not needlessly convert QUrl to QString at
runtime, the compilation profiler saves the files now as QUrl.

Change-Id: I215a87787f9117c069ecd77b2d913cc0b0ff3c89
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp
src/qml/debugger/qqmlprofiler_p.h
src/qml/qml/qqmltypeloader.cpp

index 349c181d131243dd3f153d0d8473ce4e114f38be..245900abae5840ff834095e66960aafd696a806d 100644 (file)
@@ -81,7 +81,7 @@ static void qQmlProfilerDataToByteArrays(const QQmlProfilerData *d, QList<QByteA
                     ds << QQmlProfilerDefinitions::QmlBinding;
                 break;
             case QQmlProfilerDefinitions::RangeData:
-                ds << d->detailString;
+                ds << (d->detailString.isEmpty() ? d->detailUrl.toString() : d->detailString);
                 break;
             case QQmlProfilerDefinitions::RangeLocation:
                 ds << (d->detailUrl.isEmpty() ? d->detailString : d->detailUrl.toString()) << d->x
index 3c8337c96935637136249546abeb11b164fd5f39..7e29c3ede6f8a5f5620d6f29b57350cb748a4e77 100644 (file)
@@ -99,8 +99,9 @@ struct Q_AUTOTEST_EXPORT QQmlProfilerData
     int messageType;        //bit field of QQmlProfilerService::Message
     int detailType;
 
+    // RangeData prefers detailString; RangeLocation prefers detailUrl.
     QString detailString;   //used by RangeData and possibly by RangeLocation
-    QUrl detailUrl;         //used by RangeLocation, overrides detailString
+    QUrl detailUrl;         //used by RangeLocation and possibly by RangeData
 
     int x;                  //used by RangeLocation
     int y;                  //used by RangeLocation
@@ -120,11 +121,11 @@ public:
 
     // Have toByteArrays() construct another RangeData event from the same QString later.
     // This is somewhat pointless but important for backwards compatibility.
-    void startCompiling(const QString &name)
+    void startCompiling(const QUrl &url)
     {
         m_data.append(QQmlProfilerData(m_timer.nsecsElapsed(),
                                        (1 << RangeStart | 1 << RangeLocation | 1 << RangeData),
-                                       1 << Compiling, name, 1, 1));
+                                       1 << Compiling, url, 1, 1));
     }
 
     void startHandlingSignal(const QQmlSourceLocation &location)
@@ -217,10 +218,10 @@ struct QQmlHandlingSignalProfiler : public QQmlProfilerHelper {
 };
 
 struct QQmlCompilingProfiler : public QQmlProfilerHelper {
-    QQmlCompilingProfiler(QQmlProfiler *profiler, const QString &name) :
+    QQmlCompilingProfiler(QQmlProfiler *profiler, const QUrl &url) :
         QQmlProfilerHelper(profiler)
     {
-        Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCompiling, profiler, startCompiling(name));
+        Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCompiling, profiler, startCompiling(url));
     }
 
     ~QQmlCompilingProfiler()
index 408f17ffdeaa8f83c9f6d57bb75224bdcdd4af04..eb65f732dd3dcb95c1e631ebf62f390d0176139a 100644 (file)
@@ -647,6 +647,8 @@ void QQmlDataBlob::notifyComplete(QQmlDataBlob *blob)
 {
     Q_ASSERT(m_waitingFor.contains(blob));
     Q_ASSERT(blob->status() == Error || blob->status() == Complete);
+    QQmlCompilingProfiler prof(QQmlEnginePrivate::get(typeLoader()->engine())->profiler,
+                               blob->url());
 
     m_inCallback = true;
 
@@ -1194,6 +1196,8 @@ void QQmlTypeLoader::setData(QQmlDataBlob *blob, QQmlFile *file)
 void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QQmlDataBlob::Data &d)
 {
     QML_MEMORY_SCOPE_URL(blob->url());
+    QQmlCompilingProfiler prof(QQmlEnginePrivate::get(engine())->profiler, blob->url());
+
     blob->m_inCallback = true;
 
     blob->dataReceived(d);
@@ -1212,6 +1216,8 @@ void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QQmlDataBlob::Data &d)
 void QQmlTypeLoader::setCachedUnit(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit)
 {
     QML_MEMORY_SCOPE_URL(blob->url());
+    QQmlCompilingProfiler prof(QQmlEnginePrivate::get(engine())->profiler, blob->url());
+
     blob->m_inCallback = true;
 
     blob->initializeFromCachedUnit(unit);
@@ -2253,8 +2259,6 @@ void QQmlTypeData::compile()
 
     m_compiledData = new QQmlCompiledData(typeLoader()->engine());
 
-    QQmlCompilingProfiler prof(QQmlEnginePrivate::get(typeLoader()->engine())->profiler, finalUrlString());
-
     QQmlTypeCompiler compiler(QQmlEnginePrivate::get(typeLoader()->engine()), m_compiledData, this, m_document.data());
     if (!compiler.compile()) {
         setError(compiler.compilationErrors());