diff options
Diffstat (limited to 'src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp')
-rw-r--r-- | src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp | 138 |
1 files changed, 81 insertions, 57 deletions
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp index a5ee494ced..e17722bb3d 100644 --- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp +++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp @@ -1,31 +1,37 @@ /**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtQml module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** @@ -35,9 +41,11 @@ #include "qv4profileradapter.h" #include "qqmlprofileradapter.h" #include "qqmlprofilerservicefactory.h" -#include <private/qqmlengine_p.h> +#include "qqmldebugpacket.h" + +#include <private/qjsengine_p.h> +#include <private/qqmldebugpluginmanager_p.h> -#include <QtCore/qdatastream.h> #include <QtCore/qurl.h> #include <QtCore/qtimer.h> #include <QtCore/qthread.h> @@ -45,11 +53,19 @@ QT_BEGIN_NAMESPACE +Q_QML_DEBUG_PLUGIN_LOADER(QQmlAbstractProfilerAdapter) + QQmlProfilerServiceImpl::QQmlProfilerServiceImpl(QObject *parent) : QQmlConfigurableDebugService<QQmlProfilerService>(1, parent), m_waitingForStop(false) { m_timer.start(); + QQmlAbstractProfilerAdapter *quickAdapter = + loadQQmlAbstractProfilerAdapter(QLatin1String("QQuickProfilerAdapter")); + if (quickAdapter) { + addGlobalProfiler(quickAdapter); + quickAdapter->setService(this); + } } QQmlProfilerServiceImpl::~QQmlProfilerServiceImpl() @@ -75,8 +91,8 @@ void QQmlProfilerServiceImpl::dataReady(QQmlAbstractProfilerAdapter *profiler) } m_startTimes.insert(0, profiler); if (dataComplete) { - QList<QQmlEngine *> enginesToRelease; - foreach (QQmlEngine *engine, m_stoppingEngines) { + QList<QJSEngine *> enginesToRelease; + foreach (QJSEngine *engine, m_stoppingEngines) { foreach (QQmlAbstractProfilerAdapter *engineProfiler, m_engineProfilers.values(engine)) { if (m_startTimes.values().contains(engineProfiler)) { enginesToRelease.append(engine); @@ -85,27 +101,30 @@ void QQmlProfilerServiceImpl::dataReady(QQmlAbstractProfilerAdapter *profiler) } } sendMessages(); - foreach (QQmlEngine *engine, enginesToRelease) { + foreach (QJSEngine *engine, enginesToRelease) { m_stoppingEngines.removeOne(engine); emit detachedFromEngine(engine); } } } -void QQmlProfilerServiceImpl::engineAboutToBeAdded(QQmlEngine *engine) +void QQmlProfilerServiceImpl::engineAboutToBeAdded(QJSEngine *engine) { Q_ASSERT_X(QThread::currentThread() == engine->thread(), Q_FUNC_INFO, "QML profilers have to be added from the engine thread"); QMutexLocker lock(&m_configMutex); - QQmlProfilerAdapter *qmlAdapter = new QQmlProfilerAdapter(this, QQmlEnginePrivate::get(engine)); + if (QQmlEngine *qmlEngine = qobject_cast<QQmlEngine *>(engine)) { + QQmlProfilerAdapter *qmlAdapter = + new QQmlProfilerAdapter(this, QQmlEnginePrivate::get(qmlEngine)); + addEngineProfiler(qmlAdapter, engine); + } QV4ProfilerAdapter *v4Adapter = new QV4ProfilerAdapter(this, QV8Engine::getV4(engine->handle())); - addEngineProfiler(qmlAdapter, engine); addEngineProfiler(v4Adapter, engine); QQmlConfigurableDebugService<QQmlProfilerService>::engineAboutToBeAdded(engine); } -void QQmlProfilerServiceImpl::engineAdded(QQmlEngine *engine) +void QQmlProfilerServiceImpl::engineAdded(QJSEngine *engine) { Q_ASSERT_X(QThread::currentThread() == engine->thread(), Q_FUNC_INFO, "QML profilers have to be added from the engine thread"); @@ -115,7 +134,7 @@ void QQmlProfilerServiceImpl::engineAdded(QQmlEngine *engine) profiler->stopWaiting(); } -void QQmlProfilerServiceImpl::engineAboutToBeRemoved(QQmlEngine *engine) +void QQmlProfilerServiceImpl::engineAboutToBeRemoved(QJSEngine *engine) { Q_ASSERT_X(QThread::currentThread() == engine->thread(), Q_FUNC_INFO, "QML profilers have to be removed from the engine thread"); @@ -135,7 +154,7 @@ void QQmlProfilerServiceImpl::engineAboutToBeRemoved(QQmlEngine *engine) } } -void QQmlProfilerServiceImpl::engineRemoved(QQmlEngine *engine) +void QQmlProfilerServiceImpl::engineRemoved(QJSEngine *engine) { Q_ASSERT_X(QThread::currentThread() == engine->thread(), Q_FUNC_INFO, "QML profilers have to be removed from the engine thread"); @@ -148,7 +167,7 @@ void QQmlProfilerServiceImpl::engineRemoved(QQmlEngine *engine) m_engineProfilers.remove(engine); } -void QQmlProfilerServiceImpl::addEngineProfiler(QQmlAbstractProfilerAdapter *profiler, QQmlEngine *engine) +void QQmlProfilerServiceImpl::addEngineProfiler(QQmlAbstractProfilerAdapter *profiler, QJSEngine *engine) { profiler->moveToThread(thread()); profiler->synchronize(m_timer); @@ -176,7 +195,6 @@ void QQmlProfilerServiceImpl::removeGlobalProfiler(QQmlAbstractProfilerAdapter * QMutexLocker lock(&m_configMutex); removeProfilerFromStartTimes(profiler); m_globalProfilers.removeOne(profiler); - delete profiler; } void QQmlProfilerServiceImpl::removeProfilerFromStartTimes(const QQmlAbstractProfilerAdapter *profiler) @@ -198,12 +216,17 @@ void QQmlProfilerServiceImpl::removeProfilerFromStartTimes(const QQmlAbstractPro * * If any engine profiler is started like that also start all global profilers. */ -void QQmlProfilerServiceImpl::startProfiling(QQmlEngine *engine, quint64 features) +void QQmlProfilerServiceImpl::startProfiling(QJSEngine *engine, quint64 features) { QMutexLocker lock(&m_configMutex); - QByteArray message; - QQmlDebugStream d(&message, QIODevice::WriteOnly); + if (features & static_cast<quint64>(1) << ProfileDebugMessages) { + if (QDebugMessageService *messageService = + QQmlDebugConnector::instance()->service<QDebugMessageService>()) + messageService->synchronizeTime(m_timer); + } + + QQmlDebugPacket d; d << m_timer.nsecsElapsed() << (int)Event << (int)StartTrace; bool startedAny = false; @@ -217,8 +240,8 @@ void QQmlProfilerServiceImpl::startProfiling(QQmlEngine *engine, quint64 feature if (startedAny) d << idForObject(engine); } else { - QSet<QQmlEngine *> engines; - for (QMultiHash<QQmlEngine *, QQmlAbstractProfilerAdapter *>::iterator i(m_engineProfilers.begin()); + QSet<QJSEngine *> engines; + for (QMultiHash<QJSEngine *, QQmlAbstractProfilerAdapter *>::iterator i(m_engineProfilers.begin()); i != m_engineProfilers.end(); ++i) { if (!i.value()->isRunning()) { engines << i.key(); @@ -226,7 +249,7 @@ void QQmlProfilerServiceImpl::startProfiling(QQmlEngine *engine, quint64 feature startedAny = true; } } - foreach (QQmlEngine *profiledEngine, engines) + foreach (QJSEngine *profiledEngine, engines) d << idForObject(profiledEngine); } @@ -239,7 +262,7 @@ void QQmlProfilerServiceImpl::startProfiling(QQmlEngine *engine, quint64 feature emit startFlushTimer(); } - emit messageToClient(name(), message); + emit messageToClient(name(), d.data()); } /*! @@ -249,14 +272,14 @@ void QQmlProfilerServiceImpl::startProfiling(QQmlEngine *engine, quint64 feature * If afterwards no more engine profilers are running, also stop all global profilers. Otherwise * only make them report their data. */ -void QQmlProfilerServiceImpl::stopProfiling(QQmlEngine *engine) +void QQmlProfilerServiceImpl::stopProfiling(QJSEngine *engine) { QMutexLocker lock(&m_configMutex); QList<QQmlAbstractProfilerAdapter *> stopping; QList<QQmlAbstractProfilerAdapter *> reporting; bool stillRunning = false; - for (QMultiHash<QQmlEngine *, QQmlAbstractProfilerAdapter *>::iterator i(m_engineProfilers.begin()); + for (QMultiHash<QJSEngine *, QQmlAbstractProfilerAdapter *>::iterator i(m_engineProfilers.begin()); i != m_engineProfilers.end(); ++i) { if (i.value()->isRunning()) { if (engine == 0 || i.key() == engine) { @@ -299,15 +322,13 @@ void QQmlProfilerServiceImpl::sendMessages() { QList<QByteArray> messages; - QByteArray data; - + QQmlDebugPacket traceEnd; if (m_waitingForStop) { - QQmlDebugStream traceEnd(&data, QIODevice::WriteOnly); traceEnd << m_timer.nsecsElapsed() << (int)Event << (int)EndTrace; - QSet<QQmlEngine *> seen; + QSet<QJSEngine *> seen; foreach (QQmlAbstractProfilerAdapter *profiler, m_startTimes) { - for (QMultiHash<QQmlEngine *, QQmlAbstractProfilerAdapter *>::iterator i(m_engineProfilers.begin()); + for (QMultiHash<QJSEngine *, QQmlAbstractProfilerAdapter *>::iterator i(m_engineProfilers.begin()); i != m_engineProfilers.end(); ++i) { if (i.value() == profiler && !seen.contains(i.key())) { seen << i.key(); @@ -320,23 +341,25 @@ void QQmlProfilerServiceImpl::sendMessages() while (!m_startTimes.empty()) { QQmlAbstractProfilerAdapter *first = m_startTimes.begin().value(); m_startTimes.erase(m_startTimes.begin()); - if (!m_startTimes.empty()) { - qint64 next = first->sendMessages(m_startTimes.begin().key(), messages); - if (next != -1) - m_startTimes.insert(next, first); - } else { - first->sendMessages(std::numeric_limits<qint64>::max(), messages); + qint64 next = first->sendMessages(m_startTimes.isEmpty() ? + std::numeric_limits<qint64>::max() : + m_startTimes.begin().key(), messages); + if (next != -1) + m_startTimes.insert(next, first); + + if (messages.length() >= QQmlAbstractProfilerAdapter::s_numMessagesPerBatch) { + emit messagesToClient(name(), messages); + messages.clear(); } } if (m_waitingForStop) { //indicate completion - messages << data; - data.clear(); + messages << traceEnd.data(); - QQmlDebugStream ds(&data, QIODevice::WriteOnly); + QQmlDebugPacket ds; ds << (qint64)-1 << (int)Complete; - messages << data; + messages << ds.data(); m_waitingForStop = false; } @@ -360,8 +383,10 @@ void QQmlProfilerServiceImpl::stateAboutToBeChanged(QQmlDebugService::State newS // Stop all profiling and send the data before we get disabled. if (newState != Enabled) { - foreach (QQmlEngine *engine, m_engineProfilers.keys()) - stopProfiling(engine); + for (auto it = m_engineProfilers.keyBegin(), end = m_engineProfilers.keyEnd(); + it != end; ++it) { + stopProfiling(*it); + } } } @@ -369,8 +394,7 @@ void QQmlProfilerServiceImpl::messageReceived(const QByteArray &message) { QMutexLocker lock(&m_configMutex); - QByteArray rwData = message; - QQmlDebugStream stream(&rwData, QIODevice::ReadOnly); + QQmlDebugPacket stream(message); int engineId = -1; quint64 features = std::numeric_limits<quint64>::max(); @@ -397,9 +421,9 @@ void QQmlProfilerServiceImpl::messageReceived(const QByteArray &message) // If engineId == -1 objectForId() and then the cast will return 0. if (enabled) - startProfiling(qobject_cast<QQmlEngine *>(objectForId(engineId)), features); + startProfiling(qobject_cast<QJSEngine *>(objectForId(engineId)), features); else - stopProfiling(qobject_cast<QQmlEngine *>(objectForId(engineId))); + stopProfiling(qobject_cast<QJSEngine *>(objectForId(engineId))); stopWaiting(); } |