aboutsummaryrefslogtreecommitdiffstats
path: root/tools/qmlprofiler/qmlprofilerdata.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/qmlprofiler/qmlprofilerdata.cpp')
-rw-r--r--tools/qmlprofiler/qmlprofilerdata.cpp280
1 files changed, 83 insertions, 197 deletions
diff --git a/tools/qmlprofiler/qmlprofilerdata.cpp b/tools/qmlprofiler/qmlprofilerdata.cpp
index 307b9d3686..74fa44c1d6 100644
--- a/tools/qmlprofiler/qmlprofilerdata.cpp
+++ b/tools/qmlprofiler/qmlprofilerdata.cpp
@@ -1,31 +1,26 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQml module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
@@ -73,14 +68,14 @@ Q_STATIC_ASSERT(sizeof(MESSAGE_STRINGS) ==
struct QmlRangeEventData {
QmlRangeEventData() {} // never called
QmlRangeEventData(const QString &_displayName, int _detailType, const QString &_eventHashStr,
- const QmlEventLocation &_location, const QString &_details,
+ const QQmlEventLocation &_location, const QString &_details,
QQmlProfilerDefinitions::Message _message,
QQmlProfilerDefinitions::RangeType _rangeType)
: displayName(_displayName), eventHashStr(_eventHashStr), location(_location),
details(_details), message(_message), rangeType(_rangeType), detailType(_detailType) {}
QString displayName;
QString eventHashStr;
- QmlEventLocation location;
+ QQmlEventLocation location;
QString details;
QQmlProfilerDefinitions::Message message;
QQmlProfilerDefinitions::RangeType rangeType;
@@ -107,14 +102,17 @@ struct QmlRangeEventStartInstance {
qint64 duration;
union {
int frameRate;
+ int inputType;
qint64 numericData1;
};
union {
int animationCount;
+ int inputA;
qint64 numericData2;
};
union {
int threadId;
+ int inputB;
qint64 numericData3;
};
qint64 numericData4;
@@ -127,18 +125,6 @@ Q_DECLARE_TYPEINFO(QmlRangeEventData, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(QmlRangeEventStartInstance, Q_MOVABLE_TYPE);
QT_END_NAMESPACE
-struct QV8EventInfo {
- QString displayName;
- QString eventHashStr;
- QString functionName;
- QString fileName;
- int line;
- qint64 totalTime;
- qint64 selfTime;
-
- QHash<QString, qint64> v8children;
-};
-
/////////////////////////////////////////////////////////////////
class QmlProfilerDataPrivate
{
@@ -148,18 +134,12 @@ public:
// data storage
QHash<QString, QmlRangeEventData *> eventDescriptions;
QVector<QmlRangeEventStartInstance> startInstanceList;
- QHash<QString, QV8EventInfo *> v8EventHash;
qint64 traceStartTime;
qint64 traceEndTime;
// internal state while collecting events
qint64 qmlMeasuredTime;
- qint64 v8MeasuredTime;
- QHash<int, QV8EventInfo *> v8parents;
- void clearV8RootEvent();
- QV8EventInfo v8RootEvent;
-
QmlProfilerData::State state;
};
@@ -183,12 +163,6 @@ void QmlProfilerData::clear()
d->eventDescriptions.clear();
d->startInstanceList.clear();
- qDeleteAll(d->v8EventHash);
- d->v8EventHash.clear();
- d->v8parents.clear();
- d->clearV8RootEvent();
- d->v8MeasuredTime = 0;
-
d->traceEndTime = std::numeric_limits<qint64>::min();
d->traceStartTime = std::numeric_limits<qint64>::max();
d->qmlMeasuredTime = 0;
@@ -196,7 +170,7 @@ void QmlProfilerData::clear()
setState(Empty);
}
-QString QmlProfilerData::getHashStringForQmlEvent(const QmlEventLocation &location, int eventType)
+QString QmlProfilerData::getHashStringForQmlEvent(const QQmlEventLocation &location, int eventType)
{
return QString(QStringLiteral("%1:%2:%3:%4")).arg(
location.filename,
@@ -205,14 +179,9 @@ QString QmlProfilerData::getHashStringForQmlEvent(const QmlEventLocation &locati
QString::number(eventType));
}
-QString QmlProfilerData::getHashStringForV8Event(const QString &displayName, const QString &function)
-{
- return QString(QStringLiteral("%1:%2")).arg(displayName, function);
-}
-
QString QmlProfilerData::qmlRangeTypeAsString(QQmlProfilerDefinitions::RangeType type)
{
- if (type * sizeof(QString) < sizeof(RANGE_TYPE_STRINGS))
+ if (type * sizeof(char *) < sizeof(RANGE_TYPE_STRINGS))
return QLatin1String(RANGE_TYPE_STRINGS[type]);
else
return QString::number(type);
@@ -220,7 +189,7 @@ QString QmlProfilerData::qmlRangeTypeAsString(QQmlProfilerDefinitions::RangeType
QString QmlProfilerData::qmlMessageAsString(QQmlProfilerDefinitions::Message type)
{
- if (type * sizeof(QString) < sizeof(MESSAGE_STRINGS))
+ if (type * sizeof(char *) < sizeof(MESSAGE_STRINGS))
return QLatin1String(MESSAGE_STRINGS[type]);
else
return QString::number(type);
@@ -253,15 +222,13 @@ void QmlProfilerData::addQmlEvent(QQmlProfilerDefinitions::RangeType type,
qint64 startTime,
qint64 duration,
const QStringList &data,
- const QmlEventLocation &location)
+ const QQmlEventLocation &location)
{
setState(AcquiringData);
QString details;
// generate details string
- if (data.isEmpty())
- details = tr("Source code not available");
- else {
+ if (!data.isEmpty()) {
details = data.join(QLatin1Char(' ')).replace(
QLatin1Char('\n'), QLatin1Char(' ')).simplified();
QRegExp rewrite(QStringLiteral("\\(function \\$(\\w+)\\(\\) \\{ (return |)(.+) \\}\\)"));
@@ -273,7 +240,7 @@ void QmlProfilerData::addQmlEvent(QQmlProfilerDefinitions::RangeType type,
details = details.mid(details.lastIndexOf(QLatin1Char('/')) + 1);
}
- QmlEventLocation eventLocation = location;
+ QQmlEventLocation eventLocation = location;
QString displayName, eventHashStr;
// generate hash
if (eventLocation.filename.isEmpty()) {
@@ -315,7 +282,7 @@ void QmlProfilerData::addFrameEvent(qint64 time, int framerate, int animationcou
} else {
newEvent = new QmlRangeEventData(displayName, QQmlProfilerDefinitions::AnimationFrame,
eventHashStr,
- QmlEventLocation(), details,
+ QQmlEventLocation(), details,
QQmlProfilerDefinitions::Event,
QQmlProfilerDefinitions::MaximumRangeType);
d->eventDescriptions.insert(eventHashStr, newEvent);
@@ -340,7 +307,7 @@ void QmlProfilerData::addSceneGraphFrameEvent(QQmlProfilerDefinitions::SceneGrap
newEvent = d->eventDescriptions[eventHashStr];
} else {
newEvent = new QmlRangeEventData(QStringLiteral("<SceneGraph>"), type, eventHashStr,
- QmlEventLocation(), QString(),
+ QQmlEventLocation(), QString(),
QQmlProfilerDefinitions::SceneGraphFrame,
QQmlProfilerDefinitions::MaximumRangeType);
d->eventDescriptions.insert(eventHashStr, newEvent);
@@ -353,12 +320,12 @@ void QmlProfilerData::addSceneGraphFrameEvent(QQmlProfilerDefinitions::SceneGrap
}
void QmlProfilerData::addPixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventType type,
- qint64 time, const QmlEventLocation &location,
- int width, int height, int refcount)
+ qint64 time, const QString &location,
+ int numericData1, int numericData2)
{
setState(AcquiringData);
- QString filePath = QUrl(location.filename).path();
+ QString filePath = QUrl(location).path();
QString eventHashStr = filePath.mid(filePath.lastIndexOf(QLatin1Char('/')) + 1) +
QStringLiteral(":") + QString::number(type);
@@ -366,13 +333,14 @@ void QmlProfilerData::addPixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventTy
if (d->eventDescriptions.contains(eventHashStr)) {
newEvent = d->eventDescriptions[eventHashStr];
} else {
- newEvent = new QmlRangeEventData(eventHashStr, type, eventHashStr, location, QString(),
+ newEvent = new QmlRangeEventData(eventHashStr, type, eventHashStr,
+ QQmlEventLocation(location, -1, -1), QString(),
QQmlProfilerDefinitions::PixmapCacheEvent,
QQmlProfilerDefinitions::MaximumRangeType);
d->eventDescriptions.insert(eventHashStr, newEvent);
}
- QmlRangeEventStartInstance rangeEventStartInstance(time, width, height, refcount, 0, 0,
+ QmlRangeEventStartInstance rangeEventStartInstance(time, numericData1, numericData2, 0, 0, 0,
newEvent);
d->startInstanceList.append(rangeEventStartInstance);
}
@@ -386,7 +354,7 @@ void QmlProfilerData::addMemoryEvent(QQmlProfilerDefinitions::MemoryType type, q
if (d->eventDescriptions.contains(eventHashStr)) {
newEvent = d->eventDescriptions[eventHashStr];
} else {
- newEvent = new QmlRangeEventData(eventHashStr, type, eventHashStr, QmlEventLocation(),
+ newEvent = new QmlRangeEventData(eventHashStr, type, eventHashStr, QQmlEventLocation(),
QString(), QQmlProfilerDefinitions::MemoryAllocation,
QQmlProfilerDefinitions::MaximumRangeType);
d->eventDescriptions.insert(eventHashStr, newEvent);
@@ -395,93 +363,36 @@ void QmlProfilerData::addMemoryEvent(QQmlProfilerDefinitions::MemoryType type, q
d->startInstanceList.append(rangeEventStartInstance);
}
-void QmlProfilerData::addInputEvent(QQmlProfilerDefinitions::EventType type, qint64 time)
+void QmlProfilerData::addInputEvent(QQmlProfilerDefinitions::InputEventType type, qint64 time,
+ int a, int b)
{
setState(AcquiringData);
- QString eventHashStr = QString::fromLatin1("Input:%1").arg(type);
+ QQmlProfilerDefinitions::EventType eventType;
+ switch (type) {
+ case QQmlProfilerDefinitions::InputKeyPress:
+ case QQmlProfilerDefinitions::InputKeyRelease:
+ case QQmlProfilerDefinitions::InputKeyUnknown:
+ eventType = QQmlProfilerDefinitions::Key;
+ break;
+ default:
+ eventType = QQmlProfilerDefinitions::Mouse;
+ break;
+ }
+
+ QString eventHashStr = QString::fromLatin1("Input:%1").arg(eventType);
QmlRangeEventData *newEvent;
if (d->eventDescriptions.contains(eventHashStr)) {
newEvent = d->eventDescriptions[eventHashStr];
} else {
- newEvent = new QmlRangeEventData(QString(), type, eventHashStr, QmlEventLocation(),
+ newEvent = new QmlRangeEventData(QString(), eventType, eventHashStr, QQmlEventLocation(),
QString(), QQmlProfilerDefinitions::Event,
QQmlProfilerDefinitions::MaximumRangeType);
d->eventDescriptions.insert(eventHashStr, newEvent);
}
- d->startInstanceList.append(QmlRangeEventStartInstance(time, -1, 0, 0, 0, newEvent));
-}
-
-QString QmlProfilerData::rootEventName()
-{
- return tr("<program>");
-}
-
-QString QmlProfilerData::rootEventDescription()
-{
- return tr("Main Program");
-}
-
-void QmlProfilerDataPrivate::clearV8RootEvent()
-{
- v8RootEvent.displayName = QmlProfilerData::rootEventName();
- v8RootEvent.eventHashStr = QmlProfilerData::rootEventName();
- v8RootEvent.functionName = QmlProfilerData::rootEventDescription();
- v8RootEvent.line = -1;
- v8RootEvent.totalTime = 0;
- v8RootEvent.selfTime = 0;
- v8RootEvent.v8children.clear();
-}
-
-void QmlProfilerData::addV8Event(int depth, const QString &function, const QString &filename,
- int lineNumber, double totalTime, double selfTime)
-{
- QString displayName = filename.mid(filename.lastIndexOf(QLatin1Char('/')) + 1) +
- QLatin1Char(':') + QString::number(lineNumber);
- QString hashStr = getHashStringForV8Event(displayName, function);
-
- setState(AcquiringData);
-
- // time is given in milliseconds, but internally we store it in microseconds
- totalTime *= 1e6;
- selfTime *= 1e6;
-
- // accumulate information
- QV8EventInfo *eventData = d->v8EventHash[hashStr];
- if (!eventData) {
- eventData = new QV8EventInfo;
- eventData->displayName = displayName;
- eventData->eventHashStr = hashStr;
- eventData->fileName = filename;
- eventData->functionName = function;
- eventData->line = lineNumber;
- eventData->totalTime = totalTime;
- eventData->selfTime = selfTime;
- d->v8EventHash[hashStr] = eventData;
- } else {
- eventData->totalTime += totalTime;
- eventData->selfTime += selfTime;
- }
- d->v8parents[depth] = eventData;
-
- QV8EventInfo *parentEvent = 0;
- if (depth == 0) {
- parentEvent = &d->v8RootEvent;
- d->v8MeasuredTime += totalTime;
- }
- if (depth > 0 && d->v8parents.contains(depth-1)) {
- parentEvent = d->v8parents.value(depth-1);
- }
-
- if (parentEvent != 0) {
- if (!parentEvent->v8children.contains(eventData->eventHashStr)) {
- parentEvent->v8children[eventData->eventHashStr] = totalTime;
- } else {
- parentEvent->v8children[eventData->eventHashStr] += totalTime;
- }
- }
+ d->startInstanceList.append(QmlRangeEventStartInstance(time, -1, type, a, b, newEvent));
}
void QmlProfilerData::computeQmlTime()
@@ -532,7 +443,7 @@ void QmlProfilerData::sortStartTimes()
// find block to sort
while ( itFrom != d->startInstanceList.begin()
&& itTo->startTime > itFrom->startTime ) {
- itTo--;
+ --itTo;
itFrom = itTo - 1;
}
@@ -543,7 +454,7 @@ void QmlProfilerData::sortStartTimes()
// find block length
while ( itFrom != d->startInstanceList.begin()
&& itTo->startTime <= itFrom->startTime )
- itFrom--;
+ --itFrom;
if (itTo->startTime <= itFrom->startTime)
std::sort(itFrom, itTo + 1, compareStartTimes);
@@ -567,7 +478,7 @@ void QmlProfilerData::complete()
bool QmlProfilerData::isEmpty() const
{
- return d->startInstanceList.isEmpty() && d->v8EventHash.isEmpty();
+ return d->startInstanceList.isEmpty();
}
bool QmlProfilerData::save(const QString &filename)
@@ -604,25 +515,31 @@ bool QmlProfilerData::save(const QString &filename)
stream.writeStartElement(QStringLiteral("eventData"));
stream.writeAttribute(QStringLiteral("totalTime"), QString::number(d->qmlMeasuredTime));
- foreach (const QmlRangeEventData *eventData, d->eventDescriptions.values()) {
+ const auto eventDescriptionsKeys = d->eventDescriptions.keys();
+ for (auto it = d->eventDescriptions.cbegin(), end = d->eventDescriptions.cend();
+ it != end; ++it) {
+ const QmlRangeEventData *eventData = it.value();
stream.writeStartElement(QStringLiteral("event"));
stream.writeAttribute(QStringLiteral("index"), QString::number(
- d->eventDescriptions.keys().indexOf(eventData->eventHashStr)));
- stream.writeTextElement(QStringLiteral("displayname"), eventData->displayName);
+ eventDescriptionsKeys.indexOf(eventData->eventHashStr)));
+ if (!eventData->displayName.isEmpty())
+ stream.writeTextElement(QStringLiteral("displayname"), eventData->displayName);
if (eventData->rangeType != QQmlProfilerDefinitions::MaximumRangeType)
stream.writeTextElement(QStringLiteral("type"),
qmlRangeTypeAsString(eventData->rangeType));
else
stream.writeTextElement(QStringLiteral("type"),
qmlMessageAsString(eventData->message));
- if (!eventData->location.filename.isEmpty()) {
+ if (!eventData->location.filename.isEmpty())
stream.writeTextElement(QStringLiteral("filename"), eventData->location.filename);
+ if (eventData->location.line >= 0)
stream.writeTextElement(QStringLiteral("line"),
QString::number(eventData->location.line));
+ if (eventData->location.column >= 0)
stream.writeTextElement(QStringLiteral("column"),
QString::number(eventData->location.column));
- }
- stream.writeTextElement(QStringLiteral("details"), eventData->details);
+ if (!eventData->details.isEmpty())
+ stream.writeTextElement(QStringLiteral("details"), eventData->details);
if (eventData->rangeType == QQmlProfilerDefinitions::Binding)
stream.writeTextElement(QStringLiteral("bindingType"),
QString::number((int)eventData->detailType));
@@ -662,14 +579,24 @@ bool QmlProfilerData::save(const QString &filename)
stream.writeAttribute(QStringLiteral("duration"),
QString::number(event.duration));
stream.writeAttribute(QStringLiteral("eventIndex"), QString::number(
- d->eventDescriptions.keys().indexOf(event.data->eventHashStr)));
- if (event.data->message == QQmlProfilerDefinitions::Event &&
- event.data->detailType == QQmlProfilerDefinitions::AnimationFrame) {
- // special: animation frame
- stream.writeAttribute(QStringLiteral("framerate"), QString::number(event.frameRate));
- stream.writeAttribute(QStringLiteral("animationcount"),
- QString::number(event.animationCount));
- stream.writeAttribute(QStringLiteral("thread"), QString::number(event.threadId));
+ eventDescriptionsKeys.indexOf(event.data->eventHashStr)));
+ if (event.data->message == QQmlProfilerDefinitions::Event) {
+ if (event.data->detailType == QQmlProfilerDefinitions::AnimationFrame) {
+ // special: animation frame
+ stream.writeAttribute(QStringLiteral("framerate"), QString::number(event.frameRate));
+ stream.writeAttribute(QStringLiteral("animationcount"),
+ QString::number(event.animationCount));
+ stream.writeAttribute(QStringLiteral("thread"), QString::number(event.threadId));
+ } else if (event.data->detailType == QQmlProfilerDefinitions::Key ||
+ event.data->detailType == QQmlProfilerDefinitions::Mouse) {
+ // numerical value here, to keep the format a bit more compact
+ stream.writeAttribute(QStringLiteral("type"),
+ QString::number(event.inputType));
+ stream.writeAttribute(QStringLiteral("data1"),
+ QString::number(event.inputA));
+ stream.writeAttribute(QStringLiteral("data2"),
+ QString::number(event.inputB));
+ }
} else if (event.data->message == QQmlProfilerDefinitions::PixmapCacheEvent) {
// special: pixmap cache event
if (event.data->detailType == QQmlProfilerDefinitions::PixmapSizeKnown) {
@@ -682,7 +609,7 @@ bool QmlProfilerData::save(const QString &filename)
event.data->detailType ==
QQmlProfilerDefinitions::PixmapCacheCountChanged) {
stream.writeAttribute(QStringLiteral("refCount"),
- QString::number(event.numericData3));
+ QString::number(event.numericData1));
}
} else if (event.data->message == QQmlProfilerDefinitions::SceneGraphFrame) {
// special: scenegraph frame events
@@ -708,38 +635,6 @@ bool QmlProfilerData::save(const QString &filename)
}
stream.writeEndElement(); // profilerDataModel
- stream.writeStartElement(QStringLiteral("v8profile")); // v8 profiler output
- stream.writeAttribute(QStringLiteral("totalTime"), QString::number(d->v8MeasuredTime));
- foreach (QV8EventInfo *v8event, d->v8EventHash.values()) {
- stream.writeStartElement(QStringLiteral("event"));
- stream.writeAttribute(QStringLiteral("index"),QString::number(
- d->v8EventHash.keys().indexOf(v8event->eventHashStr)));
- stream.writeTextElement(QStringLiteral("displayname"), v8event->displayName);
- stream.writeTextElement(QStringLiteral("functionname"), v8event->functionName);
- if (!v8event->fileName.isEmpty()) {
- stream.writeTextElement(QStringLiteral("filename"), v8event->fileName);
- stream.writeTextElement(QStringLiteral("line"), QString::number(v8event->line));
- }
- stream.writeTextElement(QStringLiteral("totalTime"), QString::number(v8event->totalTime));
- stream.writeTextElement(QStringLiteral("selfTime"), QString::number(v8event->selfTime));
- if (!v8event->v8children.isEmpty()) {
- stream.writeStartElement(QStringLiteral("childrenEvents"));
- QStringList childrenIndexes;
- QStringList childrenTimes;
- foreach (const QString &childHash, v8event->v8children.keys()) {
- childrenIndexes << QString::number(v8EventIndex(childHash));
- childrenTimes << QString::number(v8event->v8children[childHash]);
- }
-
- stream.writeAttribute(QStringLiteral("list"), childrenIndexes.join(QString(", ")));
- stream.writeAttribute(QStringLiteral("childrenTimes"),
- childrenTimes.join(QString(", ")));
- stream.writeEndElement();
- }
- stream.writeEndElement();
- }
- stream.writeEndElement(); // v8 profiler output
-
stream.writeEndElement(); // trace
stream.writeEndDocument();
@@ -747,15 +642,6 @@ bool QmlProfilerData::save(const QString &filename)
return true;
}
-int QmlProfilerData::v8EventIndex(const QString &hashStr)
-{
- if (!d->v8EventHash.contains(hashStr)) {
- emit error("Trying to index nonexisting v8 event");
- return -1;
- }
- return d->v8EventHash.keys().indexOf( hashStr );
-}
-
void QmlProfilerData::setState(QmlProfilerData::State state)
{
// It's not an error, we are continuously calling "AcquiringData" for example