aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@digia.com>2013-11-27 12:58:13 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-11-29 11:35:16 +0100
commit17c8fa04ce00a332310793b0e21991ab19c74e0d (patch)
treecf4b6fff05c5c0b553ef4b03806687a6df2ab19e /src/qml
parente0a0b81427f311464a9dbfcd7bf297229a6100e1 (diff)
Add a stack-based object creation profiler
The simple instantiate-in-context way of profiling object creation doesn't work anymore because the VME's contexts don't necessarily map to C++ contexts anymore. The new profiler introduces two stacks of contexts, one for currently running ranges (such as components) and one for ranges that will be revived later to profile componentComplete() and similar things. Task-number: QTCREATORBUG-10631 Change-Id: Idf19b2adf062bc9c185b3bb5ff5229381f577645 Reviewed-by: Ulf Hermann <ulf.hermann@digia.com> Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/debugger/qqmlprofilerservice.cpp124
-rw-r--r--src/qml/debugger/qqmlprofilerservice_p.h49
2 files changed, 173 insertions, 0 deletions
diff --git a/src/qml/debugger/qqmlprofilerservice.cpp b/src/qml/debugger/qqmlprofilerservice.cpp
index 0ba939cdca..9daa6acd5e 100644
--- a/src/qml/debugger/qqmlprofilerservice.cpp
+++ b/src/qml/debugger/qqmlprofilerservice.cpp
@@ -425,4 +425,128 @@ void QQmlProfilerService::messageReceived(const QByteArray &message)
m_initializeCondition.wakeAll();
}
+void QQmlVmeProfiler::Data::clear()
+{
+ url = QUrl();
+ line = 0;
+ column = 0;
+ typeName = QString();
+}
+
+void QQmlVmeProfiler::start(const QUrl &url, int line, int column, const QString &typeName)
+{
+ Q_ASSERT_X(enabled, Q_FUNC_INFO, "method called although profiler is not enabled.");
+ if (enabled) {
+ switchRange();
+ updateLocation(url, line, column);
+ updateTypeName(typeName);
+ }
+}
+
+void QQmlVmeProfiler::start()
+{
+ Q_ASSERT_X(enabled, Q_FUNC_INFO, "method called although profiler is not enabled.");
+ if (enabled) {
+ currentRange.clear();
+ switchRange();
+ }
+}
+
+void QQmlVmeProfiler::switchRange()
+{
+ if (running)
+ QQmlProfilerService::instance->endRange(QQmlProfilerService::Creating);
+ else
+ running = true;
+ QQmlProfilerService::instance->startRange(QQmlProfilerService::Creating);
+}
+
+void QQmlVmeProfiler::updateLocation(const QUrl &url, int line, int column)
+{
+ Q_ASSERT_X(enabled, Q_FUNC_INFO, "method called although profiler is not enabled.");
+ Q_ASSERT_X(running, Q_FUNC_INFO, "trying to update location on stopped profiler");
+ if (enabled && running) {
+ currentRange.url = url;
+ currentRange.line = line;
+ currentRange.column = column;
+ QQmlProfilerService::instance->rangeLocation(
+ QQmlProfilerService::Creating, url, line, column);
+ }
+}
+
+void QQmlVmeProfiler::updateTypeName(const QString &typeName)
+{
+ Q_ASSERT_X(enabled, Q_FUNC_INFO, "method called although profiler is not enabled.");
+ Q_ASSERT_X(running, Q_FUNC_INFO, "trying to update typeName on stopped profiler");
+ if (enabled && running) {
+ currentRange.typeName = typeName;
+ QQmlProfilerService::instance->rangeData(QQmlProfilerService::Creating, typeName);
+ }
+}
+
+void QQmlVmeProfiler::pop()
+{
+ Q_ASSERT_X(enabled, Q_FUNC_INFO, "method called although profiler is not enabled.");
+ Q_ASSERT_X(ranges.count() > 0, Q_FUNC_INFO, "trying to pop an invalid profiler");
+ if (enabled && ranges.count() > 0) {
+ start();
+ currentRange = ranges.pop();
+ QQmlProfilerService::instance->rangeLocation(
+ QQmlProfilerService::Creating, currentRange.url, currentRange.line, currentRange.column);
+ QQmlProfilerService::instance->rangeData(QQmlProfilerService::Creating, currentRange.typeName);
+ }
+}
+
+void QQmlVmeProfiler::push()
+{
+ Q_ASSERT_X(enabled, Q_FUNC_INFO, "method called although profiler is not enabled.");
+ Q_ASSERT_X(running, Q_FUNC_INFO, "trying to push stopped profiler");
+ if (enabled && running)
+ ranges.push(currentRange);
+}
+
+void QQmlVmeProfiler::clear()
+{
+ Q_ASSERT_X(enabled, Q_FUNC_INFO, "method called although profiler is not enabled.");
+ if (enabled) {
+ stop();
+ ranges.clear();
+ for (int i = 0; i < backgroundRanges.count(); ++i) {
+ QQmlProfilerService::instance->endRange(QQmlProfilerService::Creating);
+ }
+ backgroundRanges.clear();
+ }
+}
+
+void QQmlVmeProfiler::stop()
+{
+ Q_ASSERT_X(enabled, Q_FUNC_INFO, "method called although profiler is not enabled.");
+ if (enabled && running) {
+ QQmlProfilerService::instance->endRange(QQmlProfilerService::Creating);
+ currentRange.clear();
+ running = false;
+ }
+}
+
+void QQmlVmeProfiler::background()
+{
+ Q_ASSERT_X(enabled, Q_FUNC_INFO, "method called although profiler is not enabled.");
+ Q_ASSERT_X(running, Q_FUNC_INFO, "trying to push stopped profiler to the background.");
+ if (enabled && running) {
+ backgroundRanges.push(currentRange);
+ running = false;
+ }
+}
+
+void QQmlVmeProfiler::foreground()
+{
+ Q_ASSERT_X(enabled, Q_FUNC_INFO, "method called although profiler is not enabled.");
+ Q_ASSERT_X(backgroundRanges.count() > 0, Q_FUNC_INFO, "trying to foreground stopped profiler.");
+ if (enabled && backgroundRanges.count() > 0) {
+ stop();
+ currentRange = backgroundRanges.pop();
+ running = true;
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/qml/debugger/qqmlprofilerservice_p.h b/src/qml/debugger/qqmlprofilerservice_p.h
index 52a1dead09..c2e9eb421a 100644
--- a/src/qml/debugger/qqmlprofilerservice_p.h
+++ b/src/qml/debugger/qqmlprofilerservice_p.h
@@ -225,6 +225,7 @@ private:
friend struct QQmlBindingProfiler;
friend struct QQmlHandlingSignalProfiler;
+ friend struct QQmlVmeProfiler;
friend struct QQmlCompilingProfiler;
friend struct QQmlPixmapProfiler;
};
@@ -298,6 +299,54 @@ struct QQmlCompilingProfiler {
bool enabled;
};
+struct QQmlVmeProfiler {
+public:
+ const bool enabled;
+
+ struct Data {
+ Data() : line(0), column(0) {}
+ QUrl url;
+ int line;
+ int column;
+ QString typeName;
+ void clear();
+ };
+
+ QQmlVmeProfiler() :
+ enabled(QQmlProfilerService::instance ? QQmlProfilerService::instance->profilingEnabled() : false),
+ running(false)
+ {}
+
+ ~QQmlVmeProfiler()
+ {
+ if (enabled)
+ clear();
+ }
+
+ void clear();
+
+ void start(const QUrl &url, int line, int column, const QString &typeName);
+ void start();
+ void stop();
+
+ void updateLocation(const QUrl &url, int line, int column);
+ void updateTypeName(const QString &typeName);
+
+ void pop();
+ void push();
+
+ void background();
+ void foreground();
+
+private:
+ void switchRange();
+
+ Data currentRange;
+ QStack<Data> ranges;
+ QStack<Data> backgroundRanges;
+ bool running;
+};
+
struct QQmlPixmapProfiler {
QQmlPixmapProfiler() {
QQmlProfilerService *instance = QQmlProfilerService::instance;