summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2016-09-09 10:25:46 +0200
committerUlf Hermann <ulf.hermann@qt.io>2016-09-14 08:34:47 +0000
commitfbb45e5a578832b47bdad86906a1edcf71875efe (patch)
treea50d7289f4796a4eacb1a842e6a57b0e4beb77b3 /src
parent0eb1301b5c8f16e627a4ac020296aa00ef27470c (diff)
downloadqt-creator-fbb45e5a578832b47bdad86906a1edcf71875efe.tar.gz
QmlProfiler: Keep Compiling events separate in flame graph
The QML compiler can run asynchronously and produce ranges that don't match up with other QML/JS ranges. The flame graph model assumes that all ranges are perfectly nested, and produces incorrect data if they aren't. The compile ranges are perfectly nested among themselves, and the other QML/JS ranges are also perfectly nested among themselves, so we can fix this by keeping separate stacks for them. Change-Id: If4ea251c6a2e74bd04e142cf184937600ea31a87 Reviewed-by: Kai Koehne <kai.koehne@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/qmlprofiler/flamegraphmodel.cpp27
-rw-r--r--src/plugins/qmlprofiler/flamegraphmodel.h4
2 files changed, 21 insertions, 10 deletions
diff --git a/src/plugins/qmlprofiler/flamegraphmodel.cpp b/src/plugins/qmlprofiler/flamegraphmodel.cpp
index 74eb70793a..fe8d758d05 100644
--- a/src/plugins/qmlprofiler/flamegraphmodel.cpp
+++ b/src/plugins/qmlprofiler/flamegraphmodel.cpp
@@ -44,7 +44,9 @@ FlameGraphModel::FlameGraphModel(QmlProfilerModelManager *modelManager,
{
m_modelManager = modelManager;
m_callStack.append(QmlEvent());
- m_stackTop = &m_stackBottom;
+ m_compileStack.append(QmlEvent());
+ m_callStackTop = &m_stackBottom;
+ m_compileStackTop = &m_stackBottom;
connect(modelManager, &QmlProfilerModelManager::stateChanged,
this, &FlameGraphModel::onModelManagerStateChanged);
connect(modelManager->notesModel(), &Timeline::TimelineNotesModel::changed,
@@ -64,8 +66,11 @@ void FlameGraphModel::clear()
beginResetModel();
m_stackBottom = FlameGraphData(0, -1, 1);
m_callStack.clear();
+ m_compileStack.clear();
m_callStack.append(QmlEvent());
- m_stackTop = &m_stackBottom;
+ m_compileStack.append(QmlEvent());
+ m_callStackTop = &m_stackBottom;
+ m_compileStackTop = &m_stackBottom;
m_typeIdsWithNotes.clear();
endResetModel();
}
@@ -99,16 +104,20 @@ void FlameGraphModel::loadEvent(const QmlEvent &event, const QmlEventType &type)
if (m_stackBottom.children.isEmpty())
beginResetModel();
- const QmlEvent *potentialParent = &(m_callStack.top());
+ const bool isCompiling = (type.rangeType() == Compiling);
+ QStack<QmlEvent> &stack = isCompiling ? m_compileStack : m_callStack;
+ FlameGraphData *&stackTop = isCompiling ? m_compileStackTop : m_callStackTop;
+
+ const QmlEvent *potentialParent = &(stack.top());
if (event.rangeStage() == RangeEnd) {
- m_stackTop->duration += event.timestamp() - potentialParent->timestamp();
- m_callStack.pop();
- m_stackTop = m_stackTop->parent;
- potentialParent = &(m_callStack.top());
+ stackTop->duration += event.timestamp() - potentialParent->timestamp();
+ stack.pop();
+ stackTop = stackTop->parent;
+ potentialParent = &(stack.top());
} else {
QTC_ASSERT(event.rangeStage() == RangeStart, return);
- m_callStack.push(event);
- m_stackTop = pushChild(m_stackTop, event);
+ stack.push(event);
+ stackTop = pushChild(stackTop, event);
}
}
diff --git a/src/plugins/qmlprofiler/flamegraphmodel.h b/src/plugins/qmlprofiler/flamegraphmodel.h
index b01cd5fa23..f4092bf437 100644
--- a/src/plugins/qmlprofiler/flamegraphmodel.h
+++ b/src/plugins/qmlprofiler/flamegraphmodel.h
@@ -102,8 +102,10 @@ private:
// used by binding loop detection
QStack<QmlEvent> m_callStack;
+ QStack<QmlEvent> m_compileStack;
FlameGraphData m_stackBottom;
- FlameGraphData *m_stackTop;
+ FlameGraphData *m_callStackTop;
+ FlameGraphData *m_compileStackTop;
int m_modelId;
QmlProfilerModelManager *m_modelManager;