diff --git a/src/plugins/qmlprofiler/memoryusagemodel.cpp b/src/plugins/qmlprofiler/memoryusagemodel.cpp index d07b40df2fb..b0541fa7d00 100644 --- a/src/plugins/qmlprofiler/memoryusagemodel.cpp +++ b/src/plugins/qmlprofiler/memoryusagemodel.cpp @@ -177,11 +177,19 @@ void MemoryUsageModel::loadEvent(const QmlEvent &event, const QmlEventType &type m_currentUsage = allocation.size; if (m_currentUsageIndex != -1) { - insertEnd(m_currentUsageIndex, - event.timestamp() - startTime(m_currentUsageIndex) - 1); + qint64 duration = event.timestamp() - startTime(m_currentUsageIndex); + if (duration > 0) { + insertEnd(m_currentUsageIndex, duration - 1); + m_currentUsageIndex = insertStart(event.timestamp(), SmallItem); + m_data.insert(m_currentUsageIndex, allocation); + } else { + // Ignore ranges of 0 duration. We only need to keep track of the sizes. + m_data[m_currentUsageIndex] = allocation; + } + } else { + m_currentUsageIndex = insertStart(event.timestamp(), SmallItem); + m_data.insert(m_currentUsageIndex, allocation); } - m_currentUsageIndex = insertStart(event.timestamp(), SmallItem); - m_data.insert(m_currentUsageIndex, allocation); m_continuation = m_continuation | ContinueUsage; } } @@ -201,11 +209,22 @@ void MemoryUsageModel::loadEvent(const QmlEvent &event, const QmlEventType &type if (m_currentSize > m_maxSize) m_maxSize = m_currentSize; - if (m_currentJSHeapIndex != -1) - insertEnd(m_currentJSHeapIndex, - event.timestamp() - startTime(m_currentJSHeapIndex) - 1); - m_currentJSHeapIndex = insertStart(event.timestamp(), type.detailType()); - m_data.insert(m_currentJSHeapIndex, allocation); + + if (m_currentJSHeapIndex != -1) { + qint64 duration = event.timestamp() - startTime(m_currentJSHeapIndex); + if (duration > 0){ + insertEnd(m_currentJSHeapIndex, duration - 1); + m_currentJSHeapIndex = insertStart(event.timestamp(), type.detailType()); + m_data.insert(m_currentJSHeapIndex, allocation); + } else { + // Ignore ranges of 0 duration. We only need to keep track of the sizes. + m_data[m_currentJSHeapIndex] = allocation; + } + } else { + m_currentJSHeapIndex = insertStart(event.timestamp(), type.detailType()); + m_data.insert(m_currentJSHeapIndex, allocation); + } + m_continuation = m_continuation | ContinueAllocation; } } @@ -215,10 +234,10 @@ void MemoryUsageModel::finalize() { if (m_currentJSHeapIndex != -1) insertEnd(m_currentJSHeapIndex, modelManager()->traceTime()->endTime() - - startTime(m_currentJSHeapIndex) - 1); + startTime(m_currentJSHeapIndex)); if (m_currentUsageIndex != -1) insertEnd(m_currentUsageIndex, modelManager()->traceTime()->endTime() - - startTime(m_currentUsageIndex) - 1); + startTime(m_currentUsageIndex)); computeNesting(); diff --git a/src/plugins/qmlprofiler/pixmapcachemodel.cpp b/src/plugins/qmlprofiler/pixmapcachemodel.cpp index e21fcca8231..b38256c9a8c 100644 --- a/src/plugins/qmlprofiler/pixmapcachemodel.cpp +++ b/src/plugins/qmlprofiler/pixmapcachemodel.cpp @@ -214,8 +214,6 @@ void PixmapCacheModel::loadEvent(const QmlEvent &event, const QmlEventType &type break; } case PixmapCacheCountChanged: {// Cache Size Changed Event - pixmapStartTime = event.timestamp() + 1; // delay 1 ns for proper sorting - bool uncache = m_cumulatedCount > event.number(2); m_cumulatedCount = event.number(2); qint64 pixSize = 0; @@ -433,11 +431,16 @@ void PixmapCacheModel::computeMaxCacheSize() void PixmapCacheModel::resizeUnfinishedLoads() { - // all the "load start" events with duration 0 continue till the end of the trace - for (int i = 0; i < count(); i++) { - if (m_data[i].pixmapEventType == PixmapCacheModel::PixmapLoadingStarted && - duration(i) == 0) { - insertEnd(i, modelManager()->traceTime()->endTime() - startTime(i)); + // all the unfinished "load start" events continue till the end of the trace + for (auto pixmap = m_pixmaps.begin(), pixmapsEnd = m_pixmaps.end(); + pixmap != pixmapsEnd; ++pixmap) { + for (auto size = pixmap->sizes.begin(), sizesEnd = pixmap->sizes.end(); size != sizesEnd; + ++size) { + if (size->loadState == Loading) { + insertEnd(size->started, + modelManager()->traceTime()->endTime() - startTime(size->started)); + size->loadState = Error; + } } } } @@ -477,17 +480,26 @@ int PixmapCacheModel::updateCacheCount(int lastCacheSizeEvent, { newEvent.pixmapEventType = PixmapCacheCountChanged; newEvent.rowNumberCollapsed = 1; + newEvent.typeId = typeId; - qint64 prevSize = 0; + int index = lastCacheSizeEvent; if (lastCacheSizeEvent != -1) { - prevSize = m_data[lastCacheSizeEvent].cacheSize; - insertEnd(lastCacheSizeEvent, pixmapStartTime - startTime(lastCacheSizeEvent)); + newEvent.cacheSize = m_data[lastCacheSizeEvent].cacheSize + pixSize; + qint64 duration = pixmapStartTime - startTime(lastCacheSizeEvent); + if (duration > 0) { + insertEnd(lastCacheSizeEvent, duration); + index = insertStart(pixmapStartTime, 0); + m_data.insert(index, newEvent); + } else { + // If the timestamps are the same, just replace it + m_data[index] = newEvent; + } + } else { + newEvent.cacheSize = pixSize; + index = insertStart(pixmapStartTime, 0); + m_data.insert(index, newEvent); } - newEvent.cacheSize = prevSize + pixSize; - newEvent.typeId = typeId; - int index = insertStart(pixmapStartTime, 0); - m_data.insert(index, newEvent); return index; } diff --git a/src/plugins/qmlprofiler/qmlprofilerdatamodel.cpp b/src/plugins/qmlprofiler/qmlprofilerdatamodel.cpp index c5908924926..cdce5ccdcbb 100644 --- a/src/plugins/qmlprofiler/qmlprofilerdatamodel.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerdatamodel.cpp @@ -187,6 +187,15 @@ void QmlProfilerDataModel::QmlProfilerDataModelPrivate::rewriteType(int typeInde detailsRewriter->requestDetailsForLocation(typeIndex, type.location()); } +static bool isStateful(const QmlEventType &type) +{ + // Events of these types carry state that has to be taken into account when adding later events: + // PixmapCacheEvent: Total size of the cache and size of pixmap currently being loaded + // MemoryAllocation: Total size of the JS heap and the amount of it currently in use + const Message message = type.message(); + return message == PixmapCacheEvent || message == MemoryAllocation; +} + void QmlProfilerDataModel::replayEvents(qint64 rangeStart, qint64 rangeEnd, QmlProfilerModelManager::EventLoader loader) const { @@ -209,8 +218,12 @@ void QmlProfilerDataModel::replayEvents(qint64 rangeStart, qint64 rangeEnd, stack.push(event); else if (event.rangeStage() == RangeEnd) stack.pop(); + continue; + } else if (isStateful(type)) { + event.setTimestamp(rangeStart); + } else { + continue; } - continue; } else if (event.timestamp() > rangeEnd) { if (type.rangeType() != MaximumRangeType) { if (event.rangeStage() == RangeEnd) { @@ -224,8 +237,12 @@ void QmlProfilerDataModel::replayEvents(qint64 rangeStart, qint64 rangeEnd, } else if (event.rangeStage() == RangeStart) { stack.push(event); } + continue; + } else if (isStateful(type)) { + event.setTimestamp(rangeEnd); + } else { + continue; } - continue; } else if (!stack.isEmpty()) { foreach (QmlEvent stashed, stack) { stashed.setTimestamp(rangeStart);