diff options
Diffstat (limited to 'src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp')
-rw-r--r-- | src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp | 87 |
1 files changed, 55 insertions, 32 deletions
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp index edeb364f60..462401a093 100644 --- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp +++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp @@ -41,7 +41,6 @@ #include "qv4profileradapter.h" #include "qqmlprofileradapter.h" #include "qqmlprofilerservicefactory.h" -#include "qqmldebugpacket.h" #include <private/qjsengine_p.h> #include <private/qqmldebugpluginmanager_p.h> @@ -59,7 +58,7 @@ Q_QML_DEBUG_PLUGIN_LOADER(QQmlAbstractProfilerAdapter) QQmlProfilerServiceImpl::QQmlProfilerServiceImpl(QObject *parent) : QQmlConfigurableDebugService<QQmlProfilerService>(1, parent), - m_waitingForStop(false), m_useMessageTypes(false) + m_waitingForStop(false), m_globalEnabled(false), m_globalFeatures(0) { m_timer.start(); QQmlAbstractProfilerAdapter *quickAdapter = @@ -119,11 +118,14 @@ void QQmlProfilerServiceImpl::engineAboutToBeAdded(QJSEngine *engine) QMutexLocker lock(&m_configMutex); if (QQmlEngine *qmlEngine = qobject_cast<QQmlEngine *>(engine)) { - QQmlProfilerAdapter *qmlAdapter = - new QQmlProfilerAdapter(this, QQmlEnginePrivate::get(qmlEngine)); + QQmlEnginePrivate *enginePrivate = QQmlEnginePrivate::get(qmlEngine); + QQmlProfilerAdapter *qmlAdapter = new QQmlProfilerAdapter(this, enginePrivate); addEngineProfiler(qmlAdapter, engine); + QQmlProfilerAdapter *compileAdapter + = new QQmlProfilerAdapter(this, &(enginePrivate->typeLoader)); + addEngineProfiler(compileAdapter, engine); } - QV4ProfilerAdapter *v4Adapter = new QV4ProfilerAdapter(this, QV8Engine::getV4(engine->handle())); + QV4ProfilerAdapter *v4Adapter = new QV4ProfilerAdapter(this, engine->handle()); addEngineProfiler(v4Adapter, engine); QQmlConfigurableDebugService<QQmlProfilerService>::engineAboutToBeAdded(engine); } @@ -134,6 +136,10 @@ void QQmlProfilerServiceImpl::engineAdded(QJSEngine *engine) "QML profilers have to be added from the engine thread"); QMutexLocker lock(&m_configMutex); + + if (m_globalEnabled) + startProfiling(engine, m_globalFeatures); + const auto range = qAsConst(m_engineProfilers).equal_range(engine); for (auto it = range.first; it != range.second; ++it) (*it)->stopWaiting(); @@ -237,9 +243,9 @@ void QQmlProfilerServiceImpl::startProfiling(QJSEngine *engine, quint64 features QQmlDebugPacket d; - d << m_timer.nsecsElapsed() << (int)Event << (int)StartTrace; + d << m_timer.nsecsElapsed() << static_cast<qint32>(Event) << static_cast<qint32>(StartTrace); bool startedAny = false; - if (engine != 0) { + if (engine != nullptr) { const auto range = qAsConst(m_engineProfilers).equal_range(engine); for (auto it = range.first; it != range.second; ++it) { QQmlAbstractProfilerAdapter *profiler = *it; @@ -251,6 +257,9 @@ void QQmlProfilerServiceImpl::startProfiling(QJSEngine *engine, quint64 features if (startedAny) d << idForObject(engine); } else { + m_globalEnabled = true; + m_globalFeatures = features; + QSet<QJSEngine *> engines; for (QMultiHash<QJSEngine *, QQmlAbstractProfilerAdapter *>::iterator i(m_engineProfilers.begin()); i != m_engineProfilers.end(); ++i) { @@ -271,9 +280,8 @@ void QQmlProfilerServiceImpl::startProfiling(QJSEngine *engine, quint64 features } emit startFlushTimer(); + emit messageToClient(name(), d.data()); } - - emit messageToClient(name(), d.data()); } /*! @@ -289,14 +297,18 @@ void QQmlProfilerServiceImpl::stopProfiling(QJSEngine *engine) QList<QQmlAbstractProfilerAdapter *> stopping; QList<QQmlAbstractProfilerAdapter *> reporting; + if (engine == nullptr) + m_globalEnabled = false; + bool stillRunning = false; for (QMultiHash<QJSEngine *, QQmlAbstractProfilerAdapter *>::iterator i(m_engineProfilers.begin()); i != m_engineProfilers.end(); ++i) { if (i.value()->isRunning()) { - if (engine == 0 || i.key() == engine) { - m_startTimes.insert(-1, i.value()); + m_startTimes.insert(-1, i.value()); + if (engine == nullptr || i.key() == engine) { stopping << i.value(); } else { + reporting << i.value(); stillRunning = true; } } @@ -320,7 +332,7 @@ void QQmlProfilerServiceImpl::stopProfiling(QJSEngine *engine) m_waitingForStop = true; for (QQmlAbstractProfilerAdapter *profiler : qAsConst(reporting)) - profiler->reportData(m_useMessageTypes); + profiler->reportData(); for (QQmlAbstractProfilerAdapter *profiler : qAsConst(stopping)) profiler->stopProfiling(); @@ -335,7 +347,8 @@ void QQmlProfilerServiceImpl::sendMessages() QQmlDebugPacket traceEnd; if (m_waitingForStop) { - traceEnd << m_timer.nsecsElapsed() << (int)Event << (int)EndTrace; + traceEnd << m_timer.nsecsElapsed() << static_cast<qint32>(Event) + << static_cast<qint32>(EndTrace); QSet<QJSEngine *> seen; for (QQmlAbstractProfilerAdapter *profiler : qAsConst(m_startTimes)) { @@ -354,8 +367,7 @@ void QQmlProfilerServiceImpl::sendMessages() m_startTimes.erase(m_startTimes.begin()); qint64 next = first->sendMessages(m_startTimes.isEmpty() ? std::numeric_limits<qint64>::max() : - m_startTimes.begin().key(), messages, - m_useMessageTypes); + m_startTimes.begin().key(), messages); if (next != -1) m_startTimes.insert(next, first); @@ -365,25 +377,32 @@ void QQmlProfilerServiceImpl::sendMessages() } } + bool stillRunning = false; + for (const QQmlAbstractProfilerAdapter *profiler : qAsConst(m_engineProfilers)) { + if (profiler->isRunning()) { + stillRunning = true; + break; + } + } + if (m_waitingForStop) { - //indicate completion + // EndTrace can be sent multiple times, as it's engine specific. messages << traceEnd.data(); - QQmlDebugPacket ds; - ds << (qint64)-1 << (int)Complete; - messages << ds.data(); - m_waitingForStop = false; + if (!stillRunning) { + // Complete is only sent once, when no engines are running anymore. + QQmlDebugPacket ds; + ds << static_cast<qint64>(-1) << static_cast<qint32>(Complete); + messages << ds.data(); + m_waitingForStop = false; + } } emit messagesToClient(name(), messages); // Restart flushing if any profilers are still running - for (const QQmlAbstractProfilerAdapter *profiler : qAsConst(m_engineProfilers)) { - if (profiler->isRunning()) { - emit startFlushTimer(); - break; - } - } + if (stillRunning) + emit startFlushTimer(); } void QQmlProfilerServiceImpl::stateAboutToBeChanged(QQmlDebugService::State newState) @@ -411,7 +430,7 @@ void QQmlProfilerServiceImpl::messageReceived(const QByteArray &message) int engineId = -1; quint64 features = std::numeric_limits<quint64>::max(); bool enabled; - uint flushInterval = 0; + quint32 flushInterval = 0; stream >> enabled; if (!stream.atEnd()) stream >> engineId; @@ -419,7 +438,9 @@ void QQmlProfilerServiceImpl::messageReceived(const QByteArray &message) stream >> features; if (!stream.atEnd()) { stream >> flushInterval; - m_flushTimer.setInterval(flushInterval); + m_flushTimer.setInterval( + static_cast<int>(qMin(flushInterval, + static_cast<quint32>(std::numeric_limits<int>::max())))); auto timerStart = static_cast<void(QTimer::*)()>(&QTimer::start); if (flushInterval > 0) { connect(&m_flushTimer, &QTimer::timeout, this, &QQmlProfilerServiceImpl::flush); @@ -432,13 +453,15 @@ void QQmlProfilerServiceImpl::messageReceived(const QByteArray &message) &m_flushTimer, &QTimer::stop); } } + + bool useMessageTypes = false; if (!stream.atEnd()) - stream >> m_useMessageTypes; + stream >> useMessageTypes; // If engineId == -1 objectForId() and then the cast will return 0. - if (enabled) + if (enabled && useMessageTypes) // If the client doesn't support message types don't profile. startProfiling(qobject_cast<QJSEngine *>(objectForId(engineId)), features); - else + else if (!enabled) // On stopProfiling the client doesn't repeat useMessageTypes. stopProfiling(qobject_cast<QJSEngine *>(objectForId(engineId))); stopWaiting(); @@ -464,7 +487,7 @@ void QQmlProfilerServiceImpl::flush() } for (QQmlAbstractProfilerAdapter *profiler : qAsConst(reporting)) - profiler->reportData(m_useMessageTypes); + profiler->reportData(); } QT_END_NAMESPACE |