From 94fc57c00521e9b56d7b88759831a82cf9bff67e Mon Sep 17 00:00:00 2001
From: Ulf Hermann <ulf.hermann@qt.io>
Date: Tue, 24 May 2016 10:05:25 +0200
Subject: [PATCH] QmlProfiler: Support server generated event type IDs

This way we only have to transmit the location and data events once per
type, not once per event.

Change-Id: Ic6ab9619824764fc8b3abf09c7b58200eda2a198
Reviewed-by: Milian Wolff <milian.wolff@kdab.com>
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
---
 .../qmlprofiler/qmlprofilertraceclient.cpp    | 37 +++++++++++++------
 src/plugins/qmlprofiler/qmltypedevent.cpp     | 20 +++++++---
 src/plugins/qmlprofiler/qmltypedevent.h       |  1 +
 3 files changed, 41 insertions(+), 17 deletions(-)

diff --git a/src/plugins/qmlprofiler/qmlprofilertraceclient.cpp b/src/plugins/qmlprofiler/qmlprofilertraceclient.cpp
index 84a3fffa3c..bbf9694e6f 100644
--- a/src/plugins/qmlprofiler/qmlprofilertraceclient.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilertraceclient.cpp
@@ -71,7 +71,7 @@ public:
 
     void sendRecordingStatus(int engineId);
     bool updateFeatures(ProfileFeature feature);
-    int resolveType(const QmlEventType &type);
+    int resolveType(const QmlTypedEvent &type);
     int resolveStackTop();
     void processCurrentEvent();
 
@@ -88,19 +88,31 @@ public:
     // Reuse the same event, so that we don't have to constantly reallocate all the data.
     QmlTypedEvent currentEvent;
     QHash<QmlEventType, int> eventTypeIds;
+    QHash<qint64, int> serverTypeIds;
     QStack<QmlTypedEvent> rangesInProgress;
 };
 
-int QmlProfilerTraceClientPrivate::resolveType(const QmlEventType &type)
+int QmlProfilerTraceClientPrivate::resolveType(const QmlTypedEvent &event)
 {
-    QHash<QmlEventType, int>::ConstIterator it = eventTypeIds.constFind(type);
-
     int typeIndex = -1;
-    if (it != eventTypeIds.constEnd()) {
-        typeIndex = it.value();
+    if (event.serverTypeId != 0) {
+        QHash<qint64, int>::ConstIterator it = serverTypeIds.constFind(event.serverTypeId);
+
+        if (it != serverTypeIds.constEnd()) {
+            typeIndex = it.value();
+        } else {
+            typeIndex = model->addEventType(event.type);
+            serverTypeIds[event.serverTypeId] = typeIndex;
+        }
     } else {
-        typeIndex = model->addEventType(type);
-        eventTypeIds[type] = typeIndex;
+        QHash<QmlEventType, int>::ConstIterator it = eventTypeIds.constFind(event.type);
+
+        if (it != eventTypeIds.constEnd()) {
+            typeIndex = it.value();
+        } else {
+            typeIndex = model->addEventType(event.type);
+            eventTypeIds[event.type] = typeIndex;
+        }
     }
     return typeIndex;
 }
@@ -115,7 +127,7 @@ int QmlProfilerTraceClientPrivate::resolveStackTop()
     if (typeIndex >= 0)
         return typeIndex;
 
-    typeIndex = resolveType(typedEvent.type);
+    typeIndex = resolveType(typedEvent);
     typedEvent.event.setTypeIndex(typeIndex);
     model->addEvent(typedEvent.event);
     return typeIndex;
@@ -149,7 +161,7 @@ void QmlProfilerTraceClientPrivate::processCurrentEvent()
         rangesInProgress.top().type.location = currentEvent.type.location;
         break;
     default: {
-        int typeIndex = resolveType(currentEvent.type);
+        int typeIndex = resolveType(currentEvent);
         currentEvent.event.setTypeIndex(typeIndex);
         model->addEvent(currentEvent.event);
         break;
@@ -161,8 +173,10 @@ void QmlProfilerTraceClientPrivate::sendRecordingStatus(int engineId)
 {
     QmlDebug::QPacket stream(q->connection()->currentDataStreamVersion());
     stream << recording << engineId; // engineId -1 is OK. It means "all of them"
-    if (recording)
+    if (recording) {
         stream << requestedFeatures << flushInterval;
+        stream << true; // yes, we support type IDs
+    }
     q->sendMessage(stream.data());
 }
 
@@ -246,6 +260,7 @@ void QmlProfilerTraceClient::setRequestedFeatures(quint64 features)
             d->currentEvent.type.message = DebugMessage;
             d->currentEvent.type.rangeType = MaximumRangeType;
             d->currentEvent.type.detailType = type;
+            d->currentEvent.serverTypeId = 0;
             d->processCurrentEvent();
         });
     } else {
diff --git a/src/plugins/qmlprofiler/qmltypedevent.cpp b/src/plugins/qmlprofiler/qmltypedevent.cpp
index 235c4c177c..5cf9900131 100644
--- a/src/plugins/qmlprofiler/qmltypedevent.cpp
+++ b/src/plugins/qmlprofiler/qmltypedevent.cpp
@@ -50,6 +50,7 @@ QDataStream &operator>>(QDataStream &stream, QmlTypedEvent &event)
     event.type.data.clear();
     event.type.location.filename.clear();
     event.type.location.line = event.type.location.column = -1;
+    event.serverTypeId = 0;
 
     switch (messageType) {
     case Event: {
@@ -147,10 +148,12 @@ QDataStream &operator>>(QDataStream &stream, QmlTypedEvent &event)
         break;
     }
     case RangeStart: {
-        // read and ignore binding type
-        if (rangeType == Binding && !stream.atEnd()) {
-            qint32 bindingType;
-            stream >> bindingType;
+        if (!stream.atEnd()) {
+            qint64 typeId;
+            stream >> typeId;
+            if (stream.status() == QDataStream::Ok)
+                event.serverTypeId = typeId;
+            // otherwise it's the old binding type of 4 bytes
         }
 
         event.type.message = MaximumMessage;
@@ -166,16 +169,21 @@ QDataStream &operator>>(QDataStream &stream, QmlTypedEvent &event)
         event.type.rangeType = rangeType;
         event.event.setRangeStage(RangeData);
         event.type.detailType = -1;
+        if (!stream.atEnd())
+            stream >> event.serverTypeId;
         break;
     }
     case RangeLocation: {
         stream >> event.type.location.filename
                 >> static_cast<qint32 &>(event.type.location.line);
 
-        if (!stream.atEnd())
+        if (!stream.atEnd()) {
             stream >> static_cast<qint32 &>(event.type.location.column);
-        else
+            if (!stream.atEnd())
+                stream >> event.serverTypeId;
+        } else {
             event.type.location.column = -1;
+        }
 
         event.type.message = MaximumMessage;
         event.type.rangeType = rangeType;
diff --git a/src/plugins/qmlprofiler/qmltypedevent.h b/src/plugins/qmlprofiler/qmltypedevent.h
index aff8ca89d5..d836d2b7a2 100644
--- a/src/plugins/qmlprofiler/qmltypedevent.h
+++ b/src/plugins/qmlprofiler/qmltypedevent.h
@@ -35,6 +35,7 @@ struct QmlTypedEvent
 {
     QmlEvent event;
     QmlEventType type;
+    qint64 serverTypeId = 0;
 };
 
 QDataStream &operator>>(QDataStream &stream, QmlTypedEvent &event);
-- 
GitLab