forked from qt-creator/qt-creator
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>
This commit is contained in:
@@ -44,7 +44,9 @@ FlameGraphModel::FlameGraphModel(QmlProfilerModelManager *modelManager,
|
|||||||
{
|
{
|
||||||
m_modelManager = modelManager;
|
m_modelManager = modelManager;
|
||||||
m_callStack.append(QmlEvent());
|
m_callStack.append(QmlEvent());
|
||||||
m_stackTop = &m_stackBottom;
|
m_compileStack.append(QmlEvent());
|
||||||
|
m_callStackTop = &m_stackBottom;
|
||||||
|
m_compileStackTop = &m_stackBottom;
|
||||||
connect(modelManager, &QmlProfilerModelManager::stateChanged,
|
connect(modelManager, &QmlProfilerModelManager::stateChanged,
|
||||||
this, &FlameGraphModel::onModelManagerStateChanged);
|
this, &FlameGraphModel::onModelManagerStateChanged);
|
||||||
connect(modelManager->notesModel(), &Timeline::TimelineNotesModel::changed,
|
connect(modelManager->notesModel(), &Timeline::TimelineNotesModel::changed,
|
||||||
@@ -64,8 +66,11 @@ void FlameGraphModel::clear()
|
|||||||
beginResetModel();
|
beginResetModel();
|
||||||
m_stackBottom = FlameGraphData(0, -1, 1);
|
m_stackBottom = FlameGraphData(0, -1, 1);
|
||||||
m_callStack.clear();
|
m_callStack.clear();
|
||||||
|
m_compileStack.clear();
|
||||||
m_callStack.append(QmlEvent());
|
m_callStack.append(QmlEvent());
|
||||||
m_stackTop = &m_stackBottom;
|
m_compileStack.append(QmlEvent());
|
||||||
|
m_callStackTop = &m_stackBottom;
|
||||||
|
m_compileStackTop = &m_stackBottom;
|
||||||
m_typeIdsWithNotes.clear();
|
m_typeIdsWithNotes.clear();
|
||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
@@ -99,16 +104,20 @@ void FlameGraphModel::loadEvent(const QmlEvent &event, const QmlEventType &type)
|
|||||||
if (m_stackBottom.children.isEmpty())
|
if (m_stackBottom.children.isEmpty())
|
||||||
beginResetModel();
|
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) {
|
if (event.rangeStage() == RangeEnd) {
|
||||||
m_stackTop->duration += event.timestamp() - potentialParent->timestamp();
|
stackTop->duration += event.timestamp() - potentialParent->timestamp();
|
||||||
m_callStack.pop();
|
stack.pop();
|
||||||
m_stackTop = m_stackTop->parent;
|
stackTop = stackTop->parent;
|
||||||
potentialParent = &(m_callStack.top());
|
potentialParent = &(stack.top());
|
||||||
} else {
|
} else {
|
||||||
QTC_ASSERT(event.rangeStage() == RangeStart, return);
|
QTC_ASSERT(event.rangeStage() == RangeStart, return);
|
||||||
m_callStack.push(event);
|
stack.push(event);
|
||||||
m_stackTop = pushChild(m_stackTop, event);
|
stackTop = pushChild(stackTop, event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -102,8 +102,10 @@ private:
|
|||||||
|
|
||||||
// used by binding loop detection
|
// used by binding loop detection
|
||||||
QStack<QmlEvent> m_callStack;
|
QStack<QmlEvent> m_callStack;
|
||||||
|
QStack<QmlEvent> m_compileStack;
|
||||||
FlameGraphData m_stackBottom;
|
FlameGraphData m_stackBottom;
|
||||||
FlameGraphData *m_stackTop;
|
FlameGraphData *m_callStackTop;
|
||||||
|
FlameGraphData *m_compileStackTop;
|
||||||
|
|
||||||
int m_modelId;
|
int m_modelId;
|
||||||
QmlProfilerModelManager *m_modelManager;
|
QmlProfilerModelManager *m_modelManager;
|
||||||
|
Reference in New Issue
Block a user