diff options
author | Ulf Hermann <[email protected]> | 2014-09-03 19:28:35 +0200 |
---|---|---|
committer | Ulf Hermann <[email protected]> | 2014-09-11 11:41:27 +0200 |
commit | 1de6e7b8e0ee465f642e1b2f5a14611e52a7e8c2 (patch) | |
tree | 3ac952d6e7539c0fda1fe3c9cd7f16ace849c91a /src/qml | |
parent | 85627c26afb087975fe2e57f91837c9314d54ba7 (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 <[email protected]>
Diffstat (limited to 'src/qml')
-rw-r--r-- | src/qml/debugger/qqmlabstractprofileradapter.cpp | 10 | ||||
-rw-r--r-- | src/qml/debugger/qqmlabstractprofileradapter_p.h | 13 | ||||
-rw-r--r-- | src/qml/debugger/qqmlprofiler.cpp | 14 | ||||
-rw-r--r-- | src/qml/debugger/qqmlprofiler_p.h | 41 | ||||
-rw-r--r-- | src/qml/debugger/qqmlprofilerdefinitions_p.h | 16 | ||||
-rw-r--r-- | src/qml/debugger/qqmlprofilerservice.cpp | 25 | ||||
-rw-r--r-- | src/qml/debugger/qqmlprofilerservice_p.h | 4 | ||||
-rw-r--r-- | src/qml/debugger/qv4profileradapter.cpp | 7 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4profiling.cpp | 38 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4profiling_p.h | 18 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 2 |
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)); } |