diff options
| author | Ulf Hermann <ulf.hermann@qt.io> | 2016-04-29 18:38:54 +0200 |
|---|---|---|
| committer | Ulf Hermann <ulf.hermann@qt.io> | 2016-05-23 12:32:01 +0000 |
| commit | 0f513bc91e2fbea628455c625d372b9fd99de338 (patch) | |
| tree | 05f435639473d0bf55c1a5dd96766dbb25d19605 | |
| parent | 914e1e1fe1a9c2ec42f011b56fb3d8f37163d7df (diff) | |
| download | qt-creator-0f513bc91e2fbea628455c625d372b9fd99de338.tar.gz | |
QmlProfiler: Use a temporary file to store the master event list
As we only ever iterate the master event list in a linear fashion, we
can use a temporary file to store it. This should allow for larger
traces to be handled without running out of memory.
Change-Id: I0d2aea6f998458fe5f426f6fef0f6937e915ae68
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
4 files changed, 31 insertions, 32 deletions
diff --git a/src/plugins/qmlprofiler/qmlprofilerdatamodel.cpp b/src/plugins/qmlprofiler/qmlprofilerdatamodel.cpp index 9223fee48a..fdb864ea65 100644 --- a/src/plugins/qmlprofiler/qmlprofilerdatamodel.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerdatamodel.cpp @@ -34,6 +34,7 @@ #include <QUrl> #include <QDebug> #include <QStack> +#include <QTemporaryFile> #include <algorithm> namespace QmlProfiler { @@ -46,7 +47,6 @@ public: int resolveStackTop(); QVector<QmlEventType> eventTypes; - QVector<QmlEvent> eventList; QHash<QmlEventType, int> eventTypeIds; QStack<QmlTypedEvent> rangesInProgress; @@ -54,6 +54,9 @@ public: QmlProfilerModelManager *modelManager; int modelId; Internal::QmlProfilerDetailsRewriter *detailsRewriter; + + QTemporaryFile file; + QDataStream eventStream; }; QString getDisplayName(const QmlEventType &event) @@ -117,6 +120,8 @@ QmlProfilerDataModel::QmlProfilerDataModel(Utils::FileInProjectFinder *fileFinde this, &QmlProfilerDataModel::detailsChanged); connect(d->detailsRewriter, &QmlProfilerDetailsRewriter::eventDetailsChanged, this, &QmlProfilerDataModel::allTypesLoaded); + d->file.open(); + d->eventStream.setDevice(&d->file); } QmlProfilerDataModel::~QmlProfilerDataModel() @@ -138,25 +143,22 @@ void QmlProfilerDataModel::setData(qint64 traceStart, qint64 traceEnd, { Q_D(QmlProfilerDataModel); d->modelManager->traceTime()->setTime(traceStart, traceEnd); - d->eventList = events; d->eventTypes = types; for (int id = 0; id < types.count(); ++id) d->eventTypeIds[types[id]] = id; - foreach (const QmlEvent &event, d->eventList) + foreach (const QmlEvent &event, events) { d->modelManager->dispatch(event, d->eventTypes[event.typeIndex()]); -} - -int QmlProfilerDataModel::count() const -{ - Q_D(const QmlProfilerDataModel); - return d->eventList.count(); + d->eventStream << event; + } } void QmlProfilerDataModel::clear() { Q_D(QmlProfilerDataModel); - d->eventList.clear(); + d->file.remove(); + d->file.open(); + d->eventStream.setDevice(&d->file); d->eventTypes.clear(); d->eventTypeIds.clear(); d->rangesInProgress.clear(); @@ -166,7 +168,7 @@ void QmlProfilerDataModel::clear() bool QmlProfilerDataModel::isEmpty() const { Q_D(const QmlProfilerDataModel); - return d->eventList.isEmpty(); + return d->file.pos() == 0; } inline static uint qHash(const QmlEventType &type) @@ -234,8 +236,8 @@ int QmlProfilerDataModel::QmlProfilerDataModelPrivate::resolveStackTop() typeIndex = resolveType(typedEvent.type); typedEvent.event.setTypeIndex(typeIndex); - eventList.append(typedEvent.event); - modelManager->dispatch(eventList.last(), eventTypes[typeIndex]); + eventStream << typedEvent.event; + modelManager->dispatch(typedEvent.event, eventTypes[typeIndex]); return typeIndex; } @@ -256,9 +258,9 @@ void QmlProfilerDataModel::addEvent(const QmlEvent &event, const QmlEventType &t case RangeEnd: { int typeIndex = d->resolveStackTop(); QTC_ASSERT(typeIndex != -1, break); - d->eventList.append(event); - QmlEvent &appended = d->eventList.last(); + QmlEvent appended = event; appended.setTypeIndex(typeIndex); + d->eventStream << appended; d->modelManager->dispatch(appended, d->eventTypes[typeIndex]); d->rangesInProgress.pop(); break; @@ -270,10 +272,10 @@ void QmlProfilerDataModel::addEvent(const QmlEvent &event, const QmlEventType &t d->rangesInProgress.top().type.location = type.location; break; default: { - d->eventList.append(event); - QmlEvent &appended = d->eventList.last(); + QmlEvent appended = event; int typeIndex = d->resolveType(type); appended.setTypeIndex(typeIndex); + d->eventStream << appended; d->modelManager->dispatch(appended, d->eventTypes[typeIndex]); break; } @@ -285,7 +287,15 @@ void QmlProfilerDataModel::replayEvents(qint64 rangeStart, qint64 rangeEnd, { Q_D(const QmlProfilerDataModel); QStack<QmlEvent> stack; - foreach (const QmlEvent &event, d->eventList) { + QmlEvent event; + QFile file(d->file.fileName()); + file.open(QIODevice::ReadOnly); + QDataStream stream(&file); + while (!stream.atEnd()) { + stream >> event; + if (stream.status() == QDataStream::ReadPastEnd) + break; + const QmlEventType &type = d->eventTypes[event.typeIndex()]; if (rangeStart != -1 && rangeEnd != -1) { if (event.timestamp() < rangeStart) { @@ -324,18 +334,10 @@ void QmlProfilerDataModel::replayEvents(qint64 rangeStart, qint64 rangeEnd, } } -qint64 QmlProfilerDataModel::lastTimeMark() const -{ - Q_D(const QmlProfilerDataModel); - if (d->eventList.isEmpty()) - return 0; - - return d->eventList.last().timestamp(); -} - void QmlProfilerDataModel::finalize() { Q_D(QmlProfilerDataModel); + d->file.flush(); d->detailsRewriter->reloadDocuments(); } diff --git a/src/plugins/qmlprofiler/qmlprofilerdatamodel.h b/src/plugins/qmlprofiler/qmlprofilerdatamodel.h index ffd6d5e662..579b2f6b04 100644 --- a/src/plugins/qmlprofiler/qmlprofilerdatamodel.h +++ b/src/plugins/qmlprofiler/qmlprofilerdatamodel.h @@ -49,14 +49,12 @@ public: void setData(qint64 traceStart, qint64 traceEnd, const QVector<QmlEventType> &types, const QVector<QmlEvent> &events); - int count() const; void clear(); bool isEmpty() const; void addEvent(const QmlEvent &event, const QmlEventType &type); void replayEvents(qint64 startTime, qint64 endTime, QmlProfilerModelManager::EventLoader loader) const; void finalize(); - qint64 lastTimeMark() const; signals: void allTypesLoaded(); diff --git a/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp b/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp index 4333acbbfd..c5ab27ccf5 100644 --- a/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp +++ b/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp @@ -343,7 +343,7 @@ void QmlProfilerModelManager::load(const QString &filename) reader->eventTypes(), reader->events()); d->notesModel->setNotes(reader->notes()); setRecordedFeatures(reader->loadedFeatures()); - d->traceTime->increaseEndTime(d->model->lastTimeMark()); + d->traceTime->increaseEndTime(reader->events().last().timestamp()); delete reader; acquiringDone(); }, Qt::QueuedConnection); diff --git a/src/plugins/qmlprofiler/qmlprofilertracefile.cpp b/src/plugins/qmlprofiler/qmlprofilertracefile.cpp index 8a2d18880a..5f2428f253 100644 --- a/src/plugins/qmlprofiler/qmlprofilertracefile.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertracefile.cpp @@ -522,8 +522,7 @@ void QmlProfilerFileWriter::setFuture(QFutureInterface<void> *future) void QmlProfilerFileWriter::save(QIODevice *device) { if (m_future) { - m_future->setProgressRange( - 0, qMax(m_model->eventTypes().size() + m_model->count() + m_notes.size(), 1)); + m_future->setProgressRange(0, qMax(m_model->eventTypes().size() + m_notes.size(), 1)); m_future->setProgressValue(0); m_newProgressValue = 0; } |
