diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2016-09-09 10:25:46 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2016-09-14 08:34:47 +0000 |
commit | fbb45e5a578832b47bdad86906a1edcf71875efe (patch) | |
tree | a50d7289f4796a4eacb1a842e6a57b0e4beb77b3 /src | |
parent | 0eb1301b5c8f16e627a4ac020296aa00ef27470c (diff) | |
download | qt-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.cpp | 27 | ||||
-rw-r--r-- | src/plugins/qmlprofiler/flamegraphmodel.h | 4 |
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; |