forked from qt-creator/qt-creator
QmlProfiler: Record debug messages separately
They are not time-ordered like normal messages, so we need to buffer them and only insert them when the normal event stream arrives at their timestamp. The time ordering is important as the "restrict to range" feature uses it to determine the start of the range. Change-Id: If27a3f667c4c39e69efa95fcb9cdfd3dbf01e657 Task-number: QTCREATORBUG-19456 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
@@ -56,6 +56,7 @@ public:
|
|||||||
bool updateFeatures(ProfileFeature feature);
|
bool updateFeatures(ProfileFeature feature);
|
||||||
int resolveType(const QmlTypedEvent &type);
|
int resolveType(const QmlTypedEvent &type);
|
||||||
int resolveStackTop();
|
int resolveStackTop();
|
||||||
|
void forwardEvents(const QmlEvent &last);
|
||||||
void processCurrentEvent();
|
void processCurrentEvent();
|
||||||
|
|
||||||
QmlProfilerTraceClient *q;
|
QmlProfilerTraceClient *q;
|
||||||
@@ -74,6 +75,7 @@ public:
|
|||||||
QHash<qint64, int> serverTypeIds;
|
QHash<qint64, int> serverTypeIds;
|
||||||
QStack<QmlTypedEvent> rangesInProgress;
|
QStack<QmlTypedEvent> rangesInProgress;
|
||||||
QQueue<QmlEvent> pendingMessages;
|
QQueue<QmlEvent> pendingMessages;
|
||||||
|
QQueue<QmlEvent> pendingDebugMessages;
|
||||||
};
|
};
|
||||||
|
|
||||||
int QmlProfilerTraceClientPrivate::resolveType(const QmlTypedEvent &event)
|
int QmlProfilerTraceClientPrivate::resolveType(const QmlTypedEvent &event)
|
||||||
@@ -117,12 +119,21 @@ int QmlProfilerTraceClientPrivate::resolveStackTop()
|
|||||||
typedEvent.event.setTypeIndex(typeIndex);
|
typedEvent.event.setTypeIndex(typeIndex);
|
||||||
while (!pendingMessages.isEmpty()
|
while (!pendingMessages.isEmpty()
|
||||||
&& pendingMessages.head().timestamp() < typedEvent.event.timestamp()) {
|
&& pendingMessages.head().timestamp() < typedEvent.event.timestamp()) {
|
||||||
modelManager->addEvent(pendingMessages.dequeue());
|
forwardEvents(pendingMessages.dequeue());
|
||||||
}
|
}
|
||||||
modelManager->addEvent(typedEvent.event);
|
forwardEvents(typedEvent.event);
|
||||||
return typeIndex;
|
return typeIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QmlProfilerTraceClientPrivate::forwardEvents(const QmlEvent &last)
|
||||||
|
{
|
||||||
|
while (!pendingDebugMessages.isEmpty()
|
||||||
|
&& pendingDebugMessages.front().timestamp() <= last.timestamp()) {
|
||||||
|
modelManager->addEvent(pendingDebugMessages.dequeue());
|
||||||
|
}
|
||||||
|
modelManager->addEvent(last);
|
||||||
|
}
|
||||||
|
|
||||||
void QmlProfilerTraceClientPrivate::processCurrentEvent()
|
void QmlProfilerTraceClientPrivate::processCurrentEvent()
|
||||||
{
|
{
|
||||||
// RangeData and RangeLocation always apply to the range on the top of the stack. Furthermore,
|
// RangeData and RangeLocation always apply to the range on the top of the stack. Furthermore,
|
||||||
@@ -142,8 +153,8 @@ void QmlProfilerTraceClientPrivate::processCurrentEvent()
|
|||||||
break;
|
break;
|
||||||
currentEvent.event.setTypeIndex(typeIndex);
|
currentEvent.event.setTypeIndex(typeIndex);
|
||||||
while (!pendingMessages.isEmpty())
|
while (!pendingMessages.isEmpty())
|
||||||
modelManager->addEvent(pendingMessages.dequeue());
|
forwardEvents(pendingMessages.dequeue());
|
||||||
modelManager->addEvent(currentEvent.event);
|
forwardEvents(currentEvent.event);
|
||||||
rangesInProgress.pop();
|
rangesInProgress.pop();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -155,11 +166,15 @@ void QmlProfilerTraceClientPrivate::processCurrentEvent()
|
|||||||
if (!rangesInProgress.isEmpty())
|
if (!rangesInProgress.isEmpty())
|
||||||
rangesInProgress.top().type.setLocation(currentEvent.type.location());
|
rangesInProgress.top().type.setLocation(currentEvent.type.location());
|
||||||
break;
|
break;
|
||||||
|
case DebugMessage:
|
||||||
|
currentEvent.event.setTypeIndex(resolveType(currentEvent));
|
||||||
|
pendingDebugMessages.enqueue(currentEvent.event);
|
||||||
|
break;
|
||||||
default: {
|
default: {
|
||||||
int typeIndex = resolveType(currentEvent);
|
int typeIndex = resolveType(currentEvent);
|
||||||
currentEvent.event.setTypeIndex(typeIndex);
|
currentEvent.event.setTypeIndex(typeIndex);
|
||||||
if (rangesInProgress.isEmpty())
|
if (rangesInProgress.isEmpty())
|
||||||
modelManager->addEvent(currentEvent.event);
|
forwardEvents(currentEvent.event);
|
||||||
else
|
else
|
||||||
pendingMessages.enqueue(currentEvent.event);
|
pendingMessages.enqueue(currentEvent.event);
|
||||||
break;
|
break;
|
||||||
@@ -202,6 +217,7 @@ void QmlProfilerTraceClient::clearData()
|
|||||||
{
|
{
|
||||||
d->eventTypeIds.clear();
|
d->eventTypeIds.clear();
|
||||||
d->rangesInProgress.clear();
|
d->rangesInProgress.clear();
|
||||||
|
d->pendingDebugMessages.clear();
|
||||||
if (d->recordedFeatures != 0) {
|
if (d->recordedFeatures != 0) {
|
||||||
d->recordedFeatures = 0;
|
d->recordedFeatures = 0;
|
||||||
emit recordedFeaturesChanged(0);
|
emit recordedFeaturesChanged(0);
|
||||||
@@ -246,7 +262,7 @@ void QmlProfilerTraceClient::setRequestedFeatures(quint64 features)
|
|||||||
[this](QtMsgType type, const QString &text,
|
[this](QtMsgType type, const QString &text,
|
||||||
const QmlDebug::QDebugContextInfo &context)
|
const QmlDebug::QDebugContextInfo &context)
|
||||||
{
|
{
|
||||||
d->updateFeatures(ProfileDebugMessages);
|
QTC_ASSERT(d->updateFeatures(ProfileDebugMessages), return);
|
||||||
d->currentEvent.event.setTimestamp(context.timestamp > 0 ? context.timestamp : 0);
|
d->currentEvent.event.setTimestamp(context.timestamp > 0 ? context.timestamp : 0);
|
||||||
d->currentEvent.event.setTypeIndex(-1);
|
d->currentEvent.event.setTypeIndex(-1);
|
||||||
d->currentEvent.event.setString(text);
|
d->currentEvent.event.setString(text);
|
||||||
@@ -297,6 +313,10 @@ void QmlProfilerTraceClient::messageReceived(const QByteArray &data)
|
|||||||
d->currentEvent.event.setTimestamp(d->maximumTime);
|
d->currentEvent.event.setTimestamp(d->maximumTime);
|
||||||
d->processCurrentEvent();
|
d->processCurrentEvent();
|
||||||
}
|
}
|
||||||
|
QTC_CHECK(d->pendingMessages.isEmpty());
|
||||||
|
while (!d->pendingDebugMessages.isEmpty())
|
||||||
|
d->modelManager->addEvent(d->pendingDebugMessages.dequeue());
|
||||||
|
|
||||||
emit complete(d->maximumTime);
|
emit complete(d->maximumTime);
|
||||||
} else if (d->currentEvent.type.message() == Event
|
} else if (d->currentEvent.type.message() == Event
|
||||||
&& d->currentEvent.type.detailType() == StartTrace) {
|
&& d->currentEvent.type.detailType() == StartTrace) {
|
||||||
|
|||||||
Reference in New Issue
Block a user