forked from qt-creator/qt-creator
QmlProfiler: Always dispatch memory and pixmap events
These events carry state which needs to be tracked even if they are outside the current range. Change-Id: Ia4bc34010f81cec29cd934ce2fefa0c337aef11f Task-number: QTCREATORBUG-16552 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
This commit is contained in:
@@ -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_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);
|
||||
|
||||
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();
|
||||
|
@@ -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<qint32>(2);
|
||||
m_cumulatedCount = event.number<qint32>(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;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
} else if (!stack.isEmpty()) {
|
||||
foreach (QmlEvent stashed, stack) {
|
||||
stashed.setTimestamp(rangeStart);
|
||||
|
Reference in New Issue
Block a user