diff options
Diffstat (limited to 'plugins/qmlprofiler/qv8profilerdatamodel.cpp')
-rw-r--r-- | plugins/qmlprofiler/qv8profilerdatamodel.cpp | 489 |
1 files changed, 0 insertions, 489 deletions
diff --git a/plugins/qmlprofiler/qv8profilerdatamodel.cpp b/plugins/qmlprofiler/qv8profilerdatamodel.cpp deleted file mode 100644 index 406d010e80..0000000000 --- a/plugins/qmlprofiler/qv8profilerdatamodel.cpp +++ /dev/null @@ -1,489 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of Qt Creator. -** -** 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 Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/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 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "qv8profilerdatamodel.h" - -#include <QStringList> - -QT_BEGIN_NAMESPACE -Q_DECLARE_TYPEINFO(QmlProfiler::Internal::QV8EventData, Q_MOVABLE_TYPE); -Q_DECLARE_TYPEINFO(QmlProfiler::Internal::QV8EventSub, Q_MOVABLE_TYPE); -QT_END_NAMESPACE - -namespace QmlProfiler { -namespace Internal { - -typedef QHash <QString, QV8EventSub *> EventHash; - -static EventHash cloneEventHash(const EventHash &src) -{ - EventHash result; - const EventHash::ConstIterator cend = src.constEnd(); - for (EventHash::ConstIterator it = src.constBegin(); it != cend; ++it) - result.insert(it.key(), new QV8EventSub(it.value())); - return result; -} - -QV8EventData &QV8EventData::operator=(const QV8EventData &ref) -{ - if (this == &ref) - return *this; - - displayName = ref.displayName; - eventHashStr = ref.eventHashStr; - filename = ref.filename; - functionName = ref.functionName; - line = ref.line; - totalTime = ref.totalTime; - totalPercent = ref.totalPercent; - selfTime = ref.selfTime; - SelfTimeInPercent = ref.SelfTimeInPercent; - eventId = ref.eventId; - - qDeleteAll(parentHash); - parentHash = cloneEventHash(ref.parentHash); - - qDeleteAll(childrenHash); - childrenHash = cloneEventHash(ref.childrenHash); - - return *this; -} - -QV8EventData::QV8EventData() -{ - line = -1; - eventId = -1; - totalTime = 0; - selfTime = 0; - totalPercent = 0; - SelfTimeInPercent = 0; -} - -QV8EventData::~QV8EventData() -{ - qDeleteAll(parentHash.values()); - parentHash.clear(); - qDeleteAll(childrenHash.values()); - childrenHash.clear(); -} - -class QV8ProfilerDataModel::QV8ProfilerDataModelPrivate -{ -public: - QV8ProfilerDataModelPrivate(QV8ProfilerDataModel *qq) {Q_UNUSED(qq);} - - void clearV8RootEvent(); - void collectV8Statistics(); - - QHash<QString, QV8EventData *> v8EventHash; - QHash<int, QV8EventData *> v8parents; - QV8EventData v8RootEvent; - qint64 v8MeasuredTime; -}; - -QV8ProfilerDataModel::QV8ProfilerDataModel(QObject *parent) - : QObject(parent) - , d(new QV8ProfilerDataModelPrivate(this)) -{ - d->v8MeasuredTime = 0; - d->clearV8RootEvent(); -} - -QV8ProfilerDataModel::~QV8ProfilerDataModel() -{ - delete d; -} - -void QV8ProfilerDataModel::clear() -{ - qDeleteAll(d->v8EventHash.values()); - d->v8EventHash.clear(); - d->v8parents.clear(); - d->clearV8RootEvent(); - d->v8MeasuredTime = 0; - - emit changed(); -} - -bool QV8ProfilerDataModel::isEmpty() const -{ - return d->v8EventHash.isEmpty(); -} - -QV8EventData *QV8ProfilerDataModel::v8EventDescription(int eventId) const -{ - foreach (QV8EventData *event, d->v8EventHash.values()) { - if (event->eventId == eventId) - return event; - } - return 0; -} - -qint64 QV8ProfilerDataModel::v8MeasuredTime() const -{ - return d->v8MeasuredTime; -} - -QList<QV8EventData *> QV8ProfilerDataModel::getV8Events() const -{ - return d->v8EventHash.values(); -} - -QString getHashStringForV8Event(const QString &displayName, const QString &function) -{ - return QString::fromLatin1("%1:%2").arg(displayName, function); -} - -void QV8ProfilerDataModel::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); - - // time is given in milliseconds, but internally we store it in microseconds - totalTime *= 1e6; - selfTime *= 1e6; - - // accumulate information - QV8EventData *eventData = d->v8EventHash[hashStr]; - if (!eventData) { - eventData = new QV8EventData; - 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; - - QV8EventData *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 (!eventData->parentHash.contains(parentEvent->eventHashStr)) { - QV8EventSub *newParentSub = new QV8EventSub(parentEvent); - newParentSub->totalTime = totalTime; - - eventData->parentHash.insert(parentEvent->eventHashStr, newParentSub); - } else { - QV8EventSub *newParentSub = eventData->parentHash.value(parentEvent->eventHashStr); - newParentSub->totalTime += totalTime; - } - - if (!parentEvent->childrenHash.contains(eventData->eventHashStr)) { - QV8EventSub *newChildSub = new QV8EventSub(eventData); - newChildSub->totalTime = totalTime; - - parentEvent->childrenHash.insert(eventData->eventHashStr, newChildSub); - } else { - QV8EventSub *newChildSub = parentEvent->childrenHash.value(eventData->eventHashStr); - newChildSub->totalTime += totalTime; - } - } - -} - -void QV8ProfilerDataModel::collectV8Statistics() -{ - d->collectV8Statistics(); -} - -void QV8ProfilerDataModel::QV8ProfilerDataModelPrivate::collectV8Statistics() -{ - if (!v8EventHash.isEmpty()) { - double totalTimes = v8MeasuredTime; - double selfTimes = 0; - foreach (QV8EventData *v8event, v8EventHash.values()) { - selfTimes += v8event->selfTime; - } - - // prevent divisions by 0 - if (totalTimes == 0) - totalTimes = 1; - if (selfTimes == 0) - selfTimes = 1; - - // insert root event in eventlist - // the +1 ns is to get it on top of the sorted list - v8RootEvent.totalTime = v8MeasuredTime + 1; - v8RootEvent.selfTime = 0; - - QString rootEventHash = getHashStringForV8Event( - tr("<program>"), - tr("Main Program")); - QV8EventData *v8RootEventPointer = v8EventHash[rootEventHash]; - if (v8RootEventPointer) { - v8RootEvent = *v8RootEventPointer; - } else { - v8EventHash[rootEventHash] = new QV8EventData; - *v8EventHash[rootEventHash] = v8RootEvent; - } - - foreach (QV8EventData *v8event, v8EventHash.values()) { - v8event->totalPercent = v8event->totalTime * 100.0 / totalTimes; - v8event->SelfTimeInPercent = v8event->selfTime * 100.0 / selfTimes; - } - - int index = 0; - foreach (QV8EventData *v8event, v8EventHash.values()) { - v8event->eventId = index++; - } - v8RootEvent.eventId = v8EventHash[rootEventHash]->eventId; - } else { - // On empty data, still add a fake root event - clearV8RootEvent(); - } -} - -void QV8ProfilerDataModel::QV8ProfilerDataModelPrivate::clearV8RootEvent() -{ - v8RootEvent.displayName = tr("<program>"); - v8RootEvent.eventHashStr = tr("<program>"); - v8RootEvent.functionName = tr("Main Program"); - - v8RootEvent.line = -1; - v8RootEvent.totalTime = 0; - v8RootEvent.totalPercent = 0; - v8RootEvent.selfTime = 0; - v8RootEvent.SelfTimeInPercent = 0; - v8RootEvent.eventId = -1; - - qDeleteAll(v8RootEvent.parentHash.values()); - qDeleteAll(v8RootEvent.childrenHash.values()); - v8RootEvent.parentHash.clear(); - v8RootEvent.childrenHash.clear(); -} - -void QV8ProfilerDataModel::save(QXmlStreamWriter &stream) -{ - stream.writeStartElement(QLatin1String("v8profile")); // v8 profiler output - stream.writeAttribute(QLatin1String("totalTime"), QString::number(d->v8MeasuredTime)); - foreach (QV8EventData *v8event, d->v8EventHash.values()) { - stream.writeStartElement(QLatin1String("event")); - stream.writeAttribute(QLatin1String("index"), - QString::number( - d->v8EventHash.keys().indexOf( - v8event->eventHashStr))); - stream.writeTextElement(QLatin1String("displayname"), v8event->displayName); - stream.writeTextElement(QLatin1String("functionname"), v8event->functionName); - if (!v8event->filename.isEmpty()) { - stream.writeTextElement(QLatin1String("filename"), v8event->filename); - stream.writeTextElement(QLatin1String("line"), QString::number(v8event->line)); - } - stream.writeTextElement(QLatin1String("totalTime"), QString::number(v8event->totalTime)); - stream.writeTextElement(QLatin1String("selfTime"), QString::number(v8event->selfTime)); - if (!v8event->childrenHash.isEmpty()) { - stream.writeStartElement(QLatin1String("childrenEvents")); - QStringList childrenIndexes; - QStringList childrenTimes; - QStringList parentTimes; - foreach (QV8EventSub *v8child, v8event->childrenHash.values()) { - childrenIndexes << QString::number(v8child->reference->eventId); - childrenTimes << QString::number(v8child->totalTime); - parentTimes << QString::number(v8child->totalTime); - } - - stream.writeAttribute(QLatin1String("list"), childrenIndexes.join(QLatin1String(", "))); - stream.writeAttribute(QLatin1String("childrenTimes"), childrenTimes.join(QLatin1String(", "))); - stream.writeAttribute(QLatin1String("parentTimes"), parentTimes.join(QLatin1String(", "))); - stream.writeEndElement(); - } - stream.writeEndElement(); - } - stream.writeEndElement(); // v8 profiler output -} - -void QV8ProfilerDataModel::load(QXmlStreamReader &stream) -{ - QHash <int, QV8EventData *> v8eventBuffer; - QHash <int, QString> childrenIndexes; - QHash <int, QString> childrenTimes; - QHash <int, QString> parentTimes; - QV8EventData *v8event = 0; - - // time computation - d->v8MeasuredTime = 0; - double cumulatedV8Time = 0; - - // get the v8 time - QXmlStreamAttributes attributes = stream.attributes(); - if (attributes.hasAttribute(QLatin1String("totalTime"))) - d->v8MeasuredTime = attributes.value(QLatin1String("totalTime")).toString().toDouble(); - - while (!stream.atEnd() && !stream.hasError()) { - QXmlStreamReader::TokenType token = stream.readNext(); - QString elementName = stream.name().toString(); - switch (token) { - case QXmlStreamReader::StartDocument : continue; - case QXmlStreamReader::StartElement : { - if (elementName == QLatin1String("event")) { - QXmlStreamAttributes attributes = stream.attributes(); - if (attributes.hasAttribute(QLatin1String("index"))) { - int ndx = attributes.value(QLatin1String("index")).toString().toInt(); - if (!v8eventBuffer.value(ndx)) - v8eventBuffer[ndx] = new QV8EventData; - v8event = v8eventBuffer[ndx]; - } else { - v8event = 0; - } - break; - } - - if (!v8event) - break; - - if (elementName == QLatin1String("childrenEvents")) { - QXmlStreamAttributes attributes = stream.attributes(); - int eventIndex = v8eventBuffer.key(v8event); - if (attributes.hasAttribute(QLatin1String("list"))) { - // store for later parsing (we haven't read all the events yet) - childrenIndexes[eventIndex] = attributes.value(QLatin1String("list")).toString(); - } - if (attributes.hasAttribute(QLatin1String("childrenTimes"))) { - childrenTimes[eventIndex] = - attributes.value(QLatin1String("childrenTimes")).toString(); - } - if (attributes.hasAttribute(QLatin1String("parentTimes"))) - parentTimes[eventIndex] = attributes.value(QLatin1String("parentTimes")).toString(); - } - - stream.readNext(); - if (stream.tokenType() != QXmlStreamReader::Characters) - break; - QString readData = stream.text().toString(); - - if (elementName == QLatin1String("displayname")) { - v8event->displayName = readData; - break; - } - - if (elementName == QLatin1String("functionname")) { - v8event->functionName = readData; - break; - } - - if (elementName == QLatin1String("filename")) { - v8event->filename = readData; - break; - } - - if (elementName == QLatin1String("line")) { - v8event->line = readData.toInt(); - break; - } - - if (elementName == QLatin1String("totalTime")) { - v8event->totalTime = readData.toDouble(); - cumulatedV8Time += v8event->totalTime; - break; - } - - if (elementName == QLatin1String("selfTime")) { - v8event->selfTime = readData.toDouble(); - break; - } - break; - } - case QXmlStreamReader::EndElement : { - if (elementName == QLatin1String("v8profile")) { - // done reading the v8 profile data - break; - } - } - default: break; - } - } - - // backwards compatibility - if (d->v8MeasuredTime == 0) - d->v8MeasuredTime = cumulatedV8Time; - - // find v8events' children and parents - typedef QHash <int, QString>::ConstIterator ChildIndexConstIt; - - const ChildIndexConstIt icend = childrenIndexes.constEnd(); - for (ChildIndexConstIt it = childrenIndexes.constBegin(); it != icend; ++it) { - const int parentIndex = it.key(); - const QStringList childrenStrings = it.value().split(QLatin1Char(',')); - QStringList childrenTimesStrings = childrenTimes.value(parentIndex).split(QLatin1String(", ")); - QStringList parentTimesStrings = parentTimes.value(parentIndex).split(QLatin1String(", ")); - for (int ndx = 0; ndx < childrenStrings.count(); ndx++) { - int childIndex = childrenStrings[ndx].toInt(); - if (v8eventBuffer.value(childIndex)) { - QV8EventSub *newChild = new QV8EventSub(v8eventBuffer[childIndex]); - QV8EventSub *newParent = new QV8EventSub(v8eventBuffer[parentIndex]); - if (childrenTimesStrings.count() > ndx) - newChild->totalTime = childrenTimesStrings[ndx].toDouble(); - if (parentTimesStrings.count() > ndx) - newParent->totalTime = parentTimesStrings[ndx].toDouble(); - v8eventBuffer[parentIndex]->childrenHash.insert( - newChild->reference->displayName, - newChild); - v8eventBuffer[childIndex]->parentHash.insert( - newParent->reference->displayName, - newParent); - } - } - } - // store v8 events - foreach (QV8EventData *storedV8Event, v8eventBuffer.values()) { - storedV8Event->eventHashStr = - getHashStringForV8Event( - storedV8Event->displayName, storedV8Event->functionName); - d->v8EventHash[storedV8Event->eventHashStr] = storedV8Event; - } - - d->collectV8Statistics(); - -} - -void QV8ProfilerDataModel::complete() -{ - collectV8Statistics(); - emit changed(); -} - -} // namespace Internal -} // namespace QmlProfiler |