summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2016-05-11 15:57:25 +0200
committerUlf Hermann <ulf.hermann@qt.io>2016-05-27 09:47:59 +0000
commit17ee4990d1efc2a3ff242ae8ebc6ce1ad6d1caff (patch)
treea28330fe319556cc2ffa4f6cfa0c7d4c003dc653
parentb67b3160b6e4e6762e45a04c706c2881a1965c97 (diff)
downloadqt-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.qml1
-rw-r--r--src/plugins/qmlprofilerextension/flamegraph.cpp32
-rw-r--r--src/plugins/qmlprofilerextension/flamegraph.h20
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);
};