aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@digia.com>2014-09-03 19:28:35 +0200
committerUlf Hermann <ulf.hermann@digia.com>2014-09-11 11:41:27 +0200
commit1de6e7b8e0ee465f642e1b2f5a14611e52a7e8c2 (patch)
tree3ac952d6e7539c0fda1fe3c9cd7f16ace849c91a /src/qml
parent85627c26afb087975fe2e57f91837c9314d54ba7 (diff)
Select specific features to be recorded when profiling QML
Some features, like the memory profiler, create huge amounts of data. Often enough, we're not actually interested in all the data available from the profiler and collecting it all can lead to excessive memory consumption. This change enables us to optionally turn various aspects of QML profiling off. Task-number: QTBUG-41118 Change-Id: I7bb223414e24eb903124ffa6e0896af6ce974e49 Reviewed-by: Gunnar Sletta <gunnar@sletta.org>
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/debugger/qqmlabstractprofileradapter.cpp10
-rw-r--r--src/qml/debugger/qqmlabstractprofileradapter_p.h13
-rw-r--r--src/qml/debugger/qqmlprofiler.cpp14
-rw-r--r--src/qml/debugger/qqmlprofiler_p.h41
-rw-r--r--src/qml/debugger/qqmlprofilerdefinitions_p.h16
-rw-r--r--src/qml/debugger/qqmlprofilerservice.cpp25
-rw-r--r--src/qml/debugger/qqmlprofilerservice_p.h4
-rw-r--r--src/qml/debugger/qv4profileradapter.cpp7
-rw-r--r--src/qml/jsruntime/qv4profiling.cpp38
-rw-r--r--src/qml/jsruntime/qv4profiling_p.h18
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp2
11 files changed, 112 insertions, 76 deletions
diff --git a/src/qml/debugger/qqmlabstractprofileradapter.cpp b/src/qml/debugger/qqmlabstractprofileradapter.cpp
index 1267503226..165772335a 100644
--- a/src/qml/debugger/qqmlabstractprofileradapter.cpp
+++ b/src/qml/debugger/qqmlabstractprofileradapter.cpp
@@ -69,13 +69,13 @@ QT_BEGIN_NAMESPACE
* If the profiler's thread is waiting for an initial start signal we can emit the signal over a
* \c Qt::DirectConnection to avoid the delay of the event loop.
*/
-void QQmlAbstractProfilerAdapter::startProfiling()
+void QQmlAbstractProfilerAdapter::startProfiling(quint64 features)
{
if (waiting)
- emit profilingEnabledWhileWaiting();
+ emit profilingEnabledWhileWaiting(features);
else
- emit profilingEnabled();
- running = true;
+ emit profilingEnabled(features);
+ featuresEnabled = features;
}
/*!
@@ -90,7 +90,7 @@ void QQmlAbstractProfilerAdapter::stopProfiling() {
emit profilingDisabledWhileWaiting();
else
emit profilingDisabled();
- running = false;
+ featuresEnabled = 0;
}
/*!
diff --git a/src/qml/debugger/qqmlabstractprofileradapter_p.h b/src/qml/debugger/qqmlabstractprofileradapter_p.h
index f06d51e8f7..03f6645178 100644
--- a/src/qml/debugger/qqmlabstractprofileradapter_p.h
+++ b/src/qml/debugger/qqmlabstractprofileradapter_p.h
@@ -59,12 +59,12 @@ class Q_QML_PRIVATE_EXPORT QQmlAbstractProfilerAdapter : public QObject, public
public:
QQmlAbstractProfilerAdapter(QQmlProfilerService *service) :
- service(service), waiting(true), running(false) {}
+ service(service), waiting(true), featuresEnabled(0) {}
virtual ~QQmlAbstractProfilerAdapter() {}
virtual qint64 sendMessages(qint64 until, QList<QByteArray> &messages) = 0;
- void startProfiling();
+ void startProfiling(quint64 features);
void stopProfiling();
@@ -73,13 +73,14 @@ public:
void stopWaiting() { waiting = false; }
void startWaiting() { waiting = true; }
- bool isRunning() const { return running; }
+ bool isRunning() const { return featuresEnabled != 0; }
+ quint64 features() const { return featuresEnabled; }
void synchronize(const QElapsedTimer &t) { emit referenceTimeKnown(t); }
signals:
- void profilingEnabled();
- void profilingEnabledWhileWaiting();
+ void profilingEnabled(quint64 features);
+ void profilingEnabledWhileWaiting(quint64 features);
void profilingDisabled();
void profilingDisabledWhileWaiting();
@@ -92,7 +93,7 @@ protected:
private:
bool waiting;
- bool running;
+ quint64 featuresEnabled;
};
QT_END_NAMESPACE
diff --git a/src/qml/debugger/qqmlprofiler.cpp b/src/qml/debugger/qqmlprofiler.cpp
index 3a647e704d..b102201ff1 100644
--- a/src/qml/debugger/qqmlprofiler.cpp
+++ b/src/qml/debugger/qqmlprofiler.cpp
@@ -82,9 +82,9 @@ QQmlProfilerAdapter::QQmlProfilerAdapter(QQmlProfilerService *service, QQmlEngin
QQmlAbstractProfilerAdapter(service)
{
engine->enableProfiler();
- connect(this, SIGNAL(profilingEnabled()), engine->profiler, SLOT(startProfiling()));
- connect(this, SIGNAL(profilingEnabledWhileWaiting()),
- engine->profiler, SLOT(startProfiling()), Qt::DirectConnection);
+ connect(this, SIGNAL(profilingEnabled(quint64)), engine->profiler, SLOT(startProfiling(quint64)));
+ connect(this, SIGNAL(profilingEnabledWhileWaiting(quint64)),
+ engine->profiler, SLOT(startProfiling(quint64)), Qt::DirectConnection);
connect(this, SIGNAL(profilingDisabled()), engine->profiler, SLOT(stopProfiling()));
connect(this, SIGNAL(profilingDisabledWhileWaiting()),
engine->profiler, SLOT(stopProfiling()), Qt::DirectConnection);
@@ -111,21 +111,21 @@ void QQmlProfilerAdapter::receiveData(const QList<QQmlProfilerData> &new_data)
}
-QQmlProfiler::QQmlProfiler() : enabled(false)
+QQmlProfiler::QQmlProfiler() : featuresEnabled(0)
{
static int metatype = qRegisterMetaType<QList<QQmlProfilerData> >();
Q_UNUSED(metatype);
m_timer.start();
}
-void QQmlProfiler::startProfiling()
+void QQmlProfiler::startProfiling(quint64 features)
{
- enabled = true;
+ featuresEnabled = features;
}
void QQmlProfiler::stopProfiling()
{
- enabled = false;
+ featuresEnabled = false;
reportData();
m_data.clear();
}
diff --git a/src/qml/debugger/qqmlprofiler_p.h b/src/qml/debugger/qqmlprofiler_p.h
index 02cdbf0a4e..13e6b8ddae 100644
--- a/src/qml/debugger/qqmlprofiler_p.h
+++ b/src/qml/debugger/qqmlprofiler_p.h
@@ -56,14 +56,14 @@
QT_BEGIN_NAMESPACE
-#define Q_QML_PROFILE_IF_ENABLED(profiler, Code)\
- if (profiler && profiler->enabled) {\
+#define Q_QML_PROFILE_IF_ENABLED(feature, profiler, Code)\
+ if (profiler && (profiler->featuresEnabled & (1 << feature))) {\
Code;\
} else\
(void)0
-#define Q_QML_PROFILE(profiler, Method)\
- Q_QML_PROFILE_IF_ENABLED(profiler, profiler->Method)
+#define Q_QML_PROFILE(feature, profiler, Method)\
+ Q_QML_PROFILE_IF_ENABLED(feature, profiler, profiler->Method)
// This struct is somewhat dangerous to use:
// The messageType is a bit field. You can pack multiple messages into
@@ -162,10 +162,10 @@ public:
QQmlProfiler();
- bool enabled;
+ quint64 featuresEnabled;
public slots:
- void startProfiling();
+ void startProfiling(quint64 features);
void stopProfiling();
void reportData();
void setTimer(const QElapsedTimer &timer) { m_timer = timer; }
@@ -204,12 +204,14 @@ struct QQmlBindingProfiler : public QQmlProfilerHelper {
QQmlBindingProfiler(QQmlProfiler *profiler, const QString &url, int line, int column) :
QQmlProfilerHelper(profiler)
{
- Q_QML_PROFILE(profiler, startBinding(url, line, column));
+ Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileBinding, profiler,
+ startBinding(url, line, column));
}
~QQmlBindingProfiler()
{
- Q_QML_PROFILE(profiler, endRange<Binding>());
+ Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileBinding, profiler,
+ endRange<Binding>());
}
};
@@ -217,12 +219,14 @@ struct QQmlHandlingSignalProfiler : public QQmlProfilerHelper {
QQmlHandlingSignalProfiler(QQmlProfiler *profiler, QQmlBoundSignalExpression *expression) :
QQmlProfilerHelper(profiler)
{
- Q_QML_PROFILE(profiler, startHandlingSignal(expression->sourceLocation()));
+ Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileHandlingSignal, profiler,
+ startHandlingSignal(expression->sourceLocation()));
}
~QQmlHandlingSignalProfiler()
{
- Q_QML_PROFILE(profiler, endRange<QQmlProfiler::HandlingSignal>());
+ Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileHandlingSignal, profiler,
+ endRange<QQmlProfiler::HandlingSignal>());
}
};
@@ -230,12 +234,12 @@ struct QQmlCompilingProfiler : public QQmlProfilerHelper {
QQmlCompilingProfiler(QQmlProfiler *profiler, const QString &name) :
QQmlProfilerHelper(profiler)
{
- Q_QML_PROFILE(profiler, startCompiling(name));
+ Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCompiling, profiler, startCompiling(name));
}
~QQmlCompilingProfiler()
{
- Q_QML_PROFILE(profiler, endRange<Compiling>());
+ Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCompiling, profiler, endRange<Compiling>());
}
};
@@ -278,20 +282,20 @@ private:
QFiniteStack<Data> ranges;
};
-#define Q_QML_OC_PROFILE(profilerMember, Code)\
- Q_QML_PROFILE_IF_ENABLED(profilerMember.profiler, Code)
+#define Q_QML_OC_PROFILE(member, Code)\
+ Q_QML_PROFILE_IF_ENABLED(QQmlProfilerDefinitions::ProfileCreating, member.profiler, Code)
class QQmlObjectCreationProfiler : public QQmlVmeProfiler::Data {
public:
QQmlObjectCreationProfiler(QQmlProfiler *profiler) : profiler(profiler)
{
- Q_QML_PROFILE(profiler, startCreating());
+ Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCreating, profiler, startCreating());
}
~QQmlObjectCreationProfiler()
{
- Q_QML_PROFILE(profiler, endRange<QQmlProfilerDefinitions::Creating>());
+ Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCreating, profiler, endRange<QQmlProfilerDefinitions::Creating>());
}
void update(const QString &typeName, const QUrl &url, int line, int column)
@@ -312,7 +316,7 @@ public:
QQmlObjectCompletionProfiler(QQmlVmeProfiler *parent) :
profiler(parent->profiler)
{
- Q_QML_PROFILE_IF_ENABLED(profiler, {
+ Q_QML_PROFILE_IF_ENABLED(QQmlProfilerDefinitions::ProfileCreating, profiler, {
QQmlVmeProfiler::Data data = parent->pop();
profiler->startCreating(data.m_typeName, data.m_url, data.m_line, data.m_column);
});
@@ -320,7 +324,8 @@ public:
~QQmlObjectCompletionProfiler()
{
- Q_QML_PROFILE(profiler, endRange<QQmlProfilerDefinitions::Creating>());
+ Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCreating, profiler,
+ endRange<QQmlProfilerDefinitions::Creating>());
}
private:
QQmlProfiler *profiler;
diff --git a/src/qml/debugger/qqmlprofilerdefinitions_p.h b/src/qml/debugger/qqmlprofilerdefinitions_p.h
index 92bab93300..e8ee98433d 100644
--- a/src/qml/debugger/qqmlprofilerdefinitions_p.h
+++ b/src/qml/debugger/qqmlprofilerdefinitions_p.h
@@ -122,6 +122,22 @@ struct QQmlProfilerDefinitions {
};
typedef QV4::Profiling::MemoryType MemoryType;
+
+ enum ProfileFeature {
+ ProfileJavaScript = QV4::Profiling::FeatureFunctionCall,
+ ProfileMemory = QV4::Profiling::FeatureMemoryAllocation,
+ ProfilePixmapCache,
+ ProfileSceneGraph,
+ ProfileAnimations,
+ ProfilePainting,
+ ProfileCompiling,
+ ProfileCreating,
+ ProfileBinding,
+ ProfileHandlingSignal,
+ ProfileInputEvents,
+
+ MaximumProfileFeature
+ };
};
QT_END_NAMESPACE
diff --git a/src/qml/debugger/qqmlprofilerservice.cpp b/src/qml/debugger/qqmlprofilerservice.cpp
index 6157d2f191..5ec8178f32 100644
--- a/src/qml/debugger/qqmlprofilerservice.cpp
+++ b/src/qml/debugger/qqmlprofilerservice.cpp
@@ -171,12 +171,12 @@ void QQmlProfilerService::addGlobalProfiler(QQmlAbstractProfilerAdapter *profile
// Global profiler, not connected to a specific engine.
// Global profilers are started whenever any engine profiler is started and stopped when
// all engine profilers are stopped.
- foreach (QQmlAbstractProfilerAdapter *engineProfiler, m_engineProfilers) {
- if (engineProfiler->isRunning()) {
- profiler->startProfiling();
- break;
- }
- }
+ quint64 features = 0;
+ foreach (QQmlAbstractProfilerAdapter *engineProfiler, m_engineProfilers)
+ features |= engineProfiler->features();
+
+ if (features != 0)
+ profiler->startProfiling(features);
}
void QQmlProfilerService::removeGlobalProfiler(QQmlAbstractProfilerAdapter *profiler)
@@ -206,7 +206,7 @@ void QQmlProfilerService::removeProfilerFromStartTimes(const QQmlAbstractProfile
*
* If any engine profiler is started like that also start all global profilers.
*/
-void QQmlProfilerService::startProfiling(QQmlEngine *engine)
+void QQmlProfilerService::startProfiling(QQmlEngine *engine, quint64 features)
{
QMutexLocker lock(configMutex());
@@ -218,7 +218,7 @@ void QQmlProfilerService::startProfiling(QQmlEngine *engine)
if (engine != 0) {
foreach (QQmlAbstractProfilerAdapter *profiler, m_engineProfilers.values(engine)) {
if (!profiler->isRunning()) {
- profiler->startProfiling();
+ profiler->startProfiling(features);
startedAny = true;
}
}
@@ -230,7 +230,7 @@ void QQmlProfilerService::startProfiling(QQmlEngine *engine)
i != m_engineProfilers.end(); ++i) {
if (!i.value()->isRunning()) {
engines << i.key();
- i.value()->startProfiling();
+ i.value()->startProfiling(features);
startedAny = true;
}
}
@@ -241,7 +241,7 @@ void QQmlProfilerService::startProfiling(QQmlEngine *engine)
if (startedAny) {
foreach (QQmlAbstractProfilerAdapter *profiler, m_globalProfilers) {
if (!profiler->isRunning())
- profiler->startProfiling();
+ profiler->startProfiling(features);
}
}
@@ -359,14 +359,17 @@ void QQmlProfilerService::messageReceived(const QByteArray &message)
QQmlDebugStream stream(&rwData, QIODevice::ReadOnly);
int engineId = -1;
+ quint64 features = std::numeric_limits<quint64>::max();
bool enabled;
stream >> enabled;
if (!stream.atEnd())
stream >> engineId;
+ if (!stream.atEnd())
+ stream >> features;
// If engineId == -1 objectForId() and then the cast will return 0.
if (enabled)
- startProfiling(qobject_cast<QQmlEngine *>(objectForId(engineId)));
+ startProfiling(qobject_cast<QQmlEngine *>(objectForId(engineId)), features);
else
stopProfiling(qobject_cast<QQmlEngine *>(objectForId(engineId)));
diff --git a/src/qml/debugger/qqmlprofilerservice_p.h b/src/qml/debugger/qqmlprofilerservice_p.h
index 5405905861..c4c40adc4f 100644
--- a/src/qml/debugger/qqmlprofilerservice_p.h
+++ b/src/qml/debugger/qqmlprofilerservice_p.h
@@ -78,8 +78,8 @@ public:
void addGlobalProfiler(QQmlAbstractProfilerAdapter *profiler);
void removeGlobalProfiler(QQmlAbstractProfilerAdapter *profiler);
- void startProfiling(QQmlEngine *engine = 0);
- void stopProfiling(QQmlEngine *engine = 0);
+ void startProfiling(QQmlEngine *engine, quint64 features = std::numeric_limits<quint64>::max());
+ void stopProfiling(QQmlEngine *engine);
QQmlProfilerService();
~QQmlProfilerService();
diff --git a/src/qml/debugger/qv4profileradapter.cpp b/src/qml/debugger/qv4profileradapter.cpp
index 19a6ea3e74..a5492ce805 100644
--- a/src/qml/debugger/qv4profileradapter.cpp
+++ b/src/qml/debugger/qv4profileradapter.cpp
@@ -41,9 +41,10 @@ QV4ProfilerAdapter::QV4ProfilerAdapter(QQmlProfilerService *service, QV4::Execut
QQmlAbstractProfilerAdapter(service)
{
engine->enableProfiler();
- connect(this, SIGNAL(profilingEnabled()), engine->profiler, SLOT(startProfiling()));
- connect(this, SIGNAL(profilingEnabledWhileWaiting()), engine->profiler, SLOT(startProfiling()),
- Qt::DirectConnection);
+ connect(this, SIGNAL(profilingEnabled(quint64)),
+ engine->profiler, SLOT(startProfiling(quint64)));
+ connect(this, SIGNAL(profilingEnabledWhileWaiting(quint64)),
+ engine->profiler, SLOT(startProfiling(quint64)), Qt::DirectConnection);
connect(this, SIGNAL(profilingDisabled()), engine->profiler, SLOT(stopProfiling()));
connect(this, SIGNAL(profilingDisabledWhileWaiting()), engine->profiler, SLOT(stopProfiling()),
Qt::DirectConnection);
diff --git a/src/qml/jsruntime/qv4profiling.cpp b/src/qml/jsruntime/qv4profiling.cpp
index 693af854da..f1bd1d55d9 100644
--- a/src/qml/jsruntime/qv4profiling.cpp
+++ b/src/qml/jsruntime/qv4profiling.cpp
@@ -53,7 +53,7 @@ FunctionCallProperties FunctionCall::resolve() const
}
-Profiler::Profiler(QV4::ExecutionEngine *engine) : enabled(false), m_engine(engine)
+Profiler::Profiler(QV4::ExecutionEngine *engine) : featuresEnabled(0), m_engine(engine)
{
static int metatype = qRegisterMetaType<QList<QV4::Profiling::FunctionCallProperties> >();
static int metatype2 = qRegisterMetaType<QList<QV4::Profiling::MemoryAllocationProperties> >();
@@ -69,7 +69,7 @@ struct FunctionCallComparator {
void Profiler::stopProfiling()
{
- enabled = false;
+ featuresEnabled = 0;
reportData();
}
@@ -85,27 +85,29 @@ void Profiler::reportData()
emit dataReady(resolved, m_memory_data);
}
-void Profiler::startProfiling()
+void Profiler::startProfiling(quint64 features)
{
- if (!enabled) {
+ if (featuresEnabled == 0) {
m_data.clear();
m_memory_data.clear();
- qint64 timestamp = m_timer.nsecsElapsed();
- MemoryAllocationProperties heap = {timestamp,
- (qint64)m_engine->memoryManager->getAllocatedMem(),
- HeapPage};
- m_memory_data.append(heap);
- MemoryAllocationProperties small = {timestamp,
- (qint64)m_engine->memoryManager->getUsedMem(),
- SmallItem};
- m_memory_data.append(small);
- MemoryAllocationProperties large = {timestamp,
- (qint64)m_engine->memoryManager->getLargeItemsMem(),
- LargeItem};
- m_memory_data.append(large);
+ if (features & (1 << FeatureMemoryAllocation)) {
+ qint64 timestamp = m_timer.nsecsElapsed();
+ MemoryAllocationProperties heap = {timestamp,
+ (qint64)m_engine->memoryManager->getAllocatedMem(),
+ HeapPage};
+ m_memory_data.append(heap);
+ MemoryAllocationProperties small = {timestamp,
+ (qint64)m_engine->memoryManager->getUsedMem(),
+ SmallItem};
+ m_memory_data.append(small);
+ MemoryAllocationProperties large = {timestamp,
+ (qint64)m_engine->memoryManager->getLargeItemsMem(),
+ LargeItem};
+ m_memory_data.append(large);
+ }
- enabled = true;
+ featuresEnabled = features;
}
}
diff --git a/src/qml/jsruntime/qv4profiling_p.h b/src/qml/jsruntime/qv4profiling_p.h
index f115137c86..8224f8a851 100644
--- a/src/qml/jsruntime/qv4profiling_p.h
+++ b/src/qml/jsruntime/qv4profiling_p.h
@@ -46,6 +46,11 @@ namespace QV4 {
namespace Profiling {
+enum Features {
+ FeatureFunctionCall,
+ FeatureMemoryAllocation
+};
+
enum MemoryType {
HeapPage,
LargeItem,
@@ -106,15 +111,18 @@ private:
};
#define Q_V4_PROFILE_ALLOC(engine, size, type)\
- (engine->profiler && engine->profiler->enabled ?\
+ (engine->profiler &&\
+ (engine->profiler->featuresEnabled & (1 << Profiling::FeatureMemoryAllocation)) ?\
engine->profiler->trackAlloc(size, type) : size)
#define Q_V4_PROFILE_DEALLOC(engine, pointer, size, type) \
- (engine->profiler && engine->profiler->enabled ?\
+ (engine->profiler &&\
+ (engine->profiler->featuresEnabled & (1 << Profiling::FeatureMemoryAllocation)) ?\
engine->profiler->trackDealloc(pointer, size, type) : pointer)
#define Q_V4_PROFILE(engine, ctx, function)\
- ((engine->profiler && engine->profiler->enabled) ?\
+ (engine->profiler &&\
+ (engine->profiler->featuresEnabled & (1 << Profiling::FeatureFunctionCall)) ?\
Profiling::FunctionCallProfiler::profileCall(engine->profiler, ctx, function) :\
function->code(ctx, function->codeData))
@@ -138,11 +146,11 @@ public:
return pointer;
}
- bool enabled;
+ quint64 featuresEnabled;
public slots:
void stopProfiling();
- void startProfiling();
+ void startProfiling(quint64 features);
void reportData();
void setTimer(const QElapsedTimer &timer) { m_timer = timer; }
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 0ad60e01ab..a827e96ab1 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -93,7 +93,7 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QQmlCompile
sharedState->rootContext = 0;
QQmlProfiler *profiler = QQmlEnginePrivate::get(engine)->profiler;
- Q_QML_PROFILE_IF_ENABLED(profiler,
+ Q_QML_PROFILE_IF_ENABLED(QQmlProfilerDefinitions::ProfileCreating, profiler,
sharedState->profiler.init(profiler, compiledData->totalParserStatusCount));
}