diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2016-05-11 15:57:25 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2016-05-27 09:47:59 +0000 |
commit | 17ee4990d1efc2a3ff242ae8ebc6ce1ad6d1caff (patch) | |
tree | a28330fe319556cc2ffa4f6cfa0c7d4c003dc653 | |
parent | b67b3160b6e4e6762e45a04c706c2881a1965c97 (diff) | |
download | qt-creator-17ee4990d1efc2a3ff242ae8ebc6ce1ad6d1caff.tar.gz |
QmlProfiler: Allow for a maximum depth in flame graph view
It gets unwieldy and eventually it produces a stack overflow if you
have insane recursion.
Change-Id: I8ae6bf018572d9b240aec01d5d3319544799e9bb
Reviewed-by: Christian Kandeler <christian.kandeler@theqtcompany.com>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
-rw-r--r-- | src/plugins/qmlprofilerextension/FlameGraphView.qml | 1 | ||||
-rw-r--r-- | src/plugins/qmlprofilerextension/flamegraph.cpp | 32 | ||||
-rw-r--r-- | src/plugins/qmlprofilerextension/flamegraph.h | 20 |
3 files changed, 39 insertions, 14 deletions
diff --git a/src/plugins/qmlprofilerextension/FlameGraphView.qml b/src/plugins/qmlprofilerextension/FlameGraphView.qml index e834d1fad2..01e8600137 100644 --- a/src/plugins/qmlprofilerextension/FlameGraphView.qml +++ b/src/plugins/qmlprofilerextension/FlameGraphView.qml @@ -61,6 +61,7 @@ ScrollView { model: flameGraphModel sizeRole: FlameGraphModel.Duration sizeThreshold: 0.002 + maximumDepth: 25 y: flickable.height > height ? flickable.height - height : 0 delegate: Item { diff --git a/src/plugins/qmlprofilerextension/flamegraph.cpp b/src/plugins/qmlprofilerextension/flamegraph.cpp index 1b7ba97826..17d7bbee91 100644 --- a/src/plugins/qmlprofilerextension/flamegraph.cpp +++ b/src/plugins/qmlprofilerextension/flamegraph.cpp @@ -126,7 +126,8 @@ QObject *FlameGraph::appendChild(QObject *parentObject, QQuickItem *parentItem, } -int FlameGraph::buildNode(const QModelIndex &parentIndex, QObject *parentObject, int depth) +int FlameGraph::buildNode(const QModelIndex &parentIndex, QObject *parentObject, int depth, + int maximumDepth) { qreal position = 0; qreal skipped = 0; @@ -135,18 +136,23 @@ int FlameGraph::buildNode(const QModelIndex &parentIndex, QObject *parentObject, QQmlContext *context = qmlContext(this); int rowCount = m_model->rowCount(parentIndex); int childrenDepth = depth; - for (int row = 0; row < rowCount; ++row) { - QModelIndex childIndex = m_model->index(row, 0, parentIndex); - qreal size = m_model->data(childIndex, m_sizeRole).toReal(); - if (size / m_model->data(QModelIndex(), m_sizeRole).toReal() < m_sizeThreshold) { - skipped += size; - continue; + if (depth == maximumDepth - 1) { + skipped = parentSize; + } else { + for (int row = 0; row < rowCount; ++row) { + QModelIndex childIndex = m_model->index(row, 0, parentIndex); + qreal size = m_model->data(childIndex, m_sizeRole).toReal(); + if (size / m_model->data(QModelIndex(), m_sizeRole).toReal() < m_sizeThreshold) { + skipped += size; + continue; + } + + QObject *childObject = appendChild(parentObject, parentItem, context, childIndex, + position / parentSize, size / parentSize); + position += size; + childrenDepth = qMax(childrenDepth, buildNode(childIndex, childObject, depth + 1, + maximumDepth)); } - - QObject *childObject = appendChild(parentObject, parentItem, context, childIndex, - position / parentSize, size / parentSize); - position += size; - childrenDepth = qMax(childrenDepth, buildNode(childIndex, childObject, depth + 1)); } if (skipped > 0) { @@ -169,7 +175,7 @@ void FlameGraph::rebuild() return; } - m_depth = buildNode(QModelIndex(), this, 0); + m_depth = buildNode(QModelIndex(), this, 0, m_maximumDepth); emit depthChanged(m_depth); } diff --git a/src/plugins/qmlprofilerextension/flamegraph.h b/src/plugins/qmlprofilerextension/flamegraph.h index 832752c3b8..d61cb1075c 100644 --- a/src/plugins/qmlprofilerextension/flamegraph.h +++ b/src/plugins/qmlprofilerextension/flamegraph.h @@ -109,6 +109,8 @@ class FlameGraph : public QQuickItem Q_PROPERTY(int sizeRole READ sizeRole WRITE setSizeRole NOTIFY sizeRoleChanged) Q_PROPERTY(qreal sizeThreshold READ sizeThreshold WRITE setSizeThreshold NOTIFY sizeThresholdChanged) + Q_PROPERTY(int maximumDepth READ maximumDepth WRITE setMaximumDepth + NOTIFY maximumDepthChanged) Q_PROPERTY(int depth READ depth NOTIFY depthChanged) public: @@ -128,6 +130,19 @@ public: int depth() const; + int maximumDepth() const + { + return m_maximumDepth; + } + + void setMaximumDepth(int maximumDepth) + { + if (maximumDepth != m_maximumDepth) { + m_maximumDepth = maximumDepth; + emit maximumDepthChanged(); + } + } + static FlameGraphAttached *qmlAttachedProperties(QObject *object); signals: @@ -136,6 +151,7 @@ signals: void sizeRoleChanged(int role); void sizeThresholdChanged(qreal threshold); void depthChanged(int depth); + void maximumDepthChanged(); private slots: void rebuild(); @@ -146,8 +162,10 @@ private: int m_sizeRole = 0; int m_depth = 0; qreal m_sizeThreshold = 0; + int m_maximumDepth = std::numeric_limits<int>::max(); - int buildNode(const QModelIndex &parentIndex, QObject *parentObject, int depth); + int buildNode(const QModelIndex &parentIndex, QObject *parentObject, int depth, + int maximumDepth); QObject *appendChild(QObject *parentObject, QQuickItem *parentItem, QQmlContext *context, const QModelIndex &childIndex, qreal position, qreal size); }; |