aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/qmltooling/qmldbg_profiler
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/qmltooling/qmldbg_profiler')
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qmldbg_profiler.pro3
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp72
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.h62
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp122
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.h40
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp138
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.h67
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservicefactory.cpp38
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservicefactory.h34
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp198
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.h64
11 files changed, 492 insertions, 346 deletions
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qmldbg_profiler.pro b/src/plugins/qmltooling/qmldbg_profiler/qmldbg_profiler.pro
index 4fcfb41a8c..4629a7b81e 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qmldbg_profiler.pro
+++ b/src/plugins/qmltooling/qmldbg_profiler/qmldbg_profiler.pro
@@ -1,5 +1,5 @@
TARGET = qmldbg_profiler
-QT = qml-private core-private
+QT = qml-private core-private packetprotocol-private
SOURCES += \
$$PWD/qqmlenginecontrolservice.cpp \
@@ -10,6 +10,7 @@ SOURCES += \
HEADERS += \
$$PWD/../shared/qqmlconfigurabledebugservice.h \
+ $$PWD/../shared/qqmldebugpacket.h \
$$PWD/qqmlenginecontrolservice.h \
$$PWD/qqmlprofileradapter.h \
$$PWD/qqmlprofilerservice.h \
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp
index 4f131ac481..6b653d5a54 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp
@@ -1,56 +1,61 @@
/****************************************************************************
**
-** 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$
**
****************************************************************************/
#include "qqmlenginecontrolservice.h"
-#include <QQmlEngine>
+#include "qqmldebugpacket.h"
+#include <QJSEngine>
QT_BEGIN_NAMESPACE
-const QString QQmlEngineControlService::s_key = QStringLiteral("EngineControl");
-
-QQmlEngineControlService::QQmlEngineControlService(QObject *parent) :
- QQmlDebugService(s_key, 1, parent)
+QQmlEngineControlServiceImpl::QQmlEngineControlServiceImpl(QObject *parent) :
+ QQmlEngineControlService(1, parent)
{
}
-void QQmlEngineControlService::messageReceived(const QByteArray &message)
+void QQmlEngineControlServiceImpl::messageReceived(const QByteArray &message)
{
QMutexLocker lock(&dataMutex);
- QQmlDebugStream d(message);
+ QQmlDebugPacket d(message);
int command;
int engineId;
d >> command >> engineId;
- QQmlEngine *engine = qobject_cast<QQmlEngine *>(objectForId(engineId));
+ QJSEngine *engine = qobject_cast<QJSEngine *>(objectForId(engineId));
if (command == StartWaitingEngine && startingEngines.contains(engine)) {
startingEngines.removeOne(engine);
emit attachedToEngine(engine);
@@ -60,7 +65,7 @@ void QQmlEngineControlService::messageReceived(const QByteArray &message)
}
}
-void QQmlEngineControlService::engineAboutToBeAdded(QQmlEngine *engine)
+void QQmlEngineControlServiceImpl::engineAboutToBeAdded(QJSEngine *engine)
{
QMutexLocker lock(&dataMutex);
if (state() == Enabled) {
@@ -73,7 +78,7 @@ void QQmlEngineControlService::engineAboutToBeAdded(QQmlEngine *engine)
}
}
-void QQmlEngineControlService::engineAboutToBeRemoved(QQmlEngine *engine)
+void QQmlEngineControlServiceImpl::engineAboutToBeRemoved(QJSEngine *engine)
{
QMutexLocker lock(&dataMutex);
if (state() == Enabled) {
@@ -86,7 +91,7 @@ void QQmlEngineControlService::engineAboutToBeRemoved(QQmlEngine *engine)
}
}
-void QQmlEngineControlService::engineAdded(QQmlEngine *engine)
+void QQmlEngineControlServiceImpl::engineAdded(QJSEngine *engine)
{
if (state() == Enabled) {
QMutexLocker lock(&dataMutex);
@@ -96,7 +101,7 @@ void QQmlEngineControlService::engineAdded(QQmlEngine *engine)
}
}
-void QQmlEngineControlService::engineRemoved(QQmlEngine *engine)
+void QQmlEngineControlServiceImpl::engineRemoved(QJSEngine *engine)
{
if (state() == Enabled) {
QMutexLocker lock(&dataMutex);
@@ -106,22 +111,21 @@ void QQmlEngineControlService::engineRemoved(QQmlEngine *engine)
}
}
-void QQmlEngineControlService::sendMessage(QQmlEngineControlService::MessageType type, QQmlEngine *engine)
+void QQmlEngineControlServiceImpl::sendMessage(QQmlEngineControlServiceImpl::MessageType type, QJSEngine *engine)
{
- QByteArray message;
- QQmlDebugStream d(&message, QIODevice::WriteOnly);
- d << type << idForObject(engine);
- emit messageToClient(name(), message);
+ QQmlDebugPacket d;
+ d << int(type) << idForObject(engine);
+ emit messageToClient(name(), d.data());
}
-void QQmlEngineControlService::stateChanged(State)
+void QQmlEngineControlServiceImpl::stateChanged(State)
{
// We flush everything for any kind of state change, to avoid complicated timing issues.
QMutexLocker lock(&dataMutex);
- foreach (QQmlEngine *engine, startingEngines)
+ foreach (QJSEngine *engine, startingEngines)
emit attachedToEngine(engine);
startingEngines.clear();
- foreach (QQmlEngine *engine, stoppingEngines)
+ foreach (QJSEngine *engine, stoppingEngines)
emit detachedFromEngine(engine);
stoppingEngines.clear();
}
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.h b/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.h
index e2a93e562a..1138310820 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.h
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.h
@@ -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,7 +41,7 @@
#define QQMLENGINECONTROLSERVICE_H
#include <QMutex>
-#include <private/qqmldebugservice_p.h>
+#include <private/qqmldebugserviceinterfaces_p.h>
//
// W A R N I N G
@@ -50,11 +56,9 @@
QT_BEGIN_NAMESPACE
-class QQmlEngineControlService : public QQmlDebugService
+class QQmlEngineControlServiceImpl : public QQmlEngineControlService
{
public:
- static const QString s_key;
-
enum MessageType {
EngineAboutToBeAdded,
EngineAdded,
@@ -67,22 +71,24 @@ public:
StopWaitingEngine
};
- QQmlEngineControlService(QObject *parent = 0);
+ QQmlEngineControlServiceImpl(QObject *parent = 0);
protected:
+ friend class QQmlProfilerServiceFactory;
+
QMutex dataMutex;
- QList<QQmlEngine *> startingEngines;
- QList<QQmlEngine *> stoppingEngines;
+ QList<QJSEngine *> startingEngines;
+ QList<QJSEngine *> stoppingEngines;
- void messageReceived(const QByteArray &);
- void engineAboutToBeAdded(QQmlEngine *);
- void engineAboutToBeRemoved(QQmlEngine *);
- void engineAdded(QQmlEngine *);
- void engineRemoved(QQmlEngine *);
+ void messageReceived(const QByteArray &) Q_DECL_OVERRIDE;
+ void engineAboutToBeAdded(QJSEngine *) Q_DECL_OVERRIDE;
+ void engineAboutToBeRemoved(QJSEngine *) Q_DECL_OVERRIDE;
+ void engineAdded(QJSEngine *) Q_DECL_OVERRIDE;
+ void engineRemoved(QJSEngine *) Q_DECL_OVERRIDE;
- void sendMessage(MessageType type, QQmlEngine *engine);
+ void sendMessage(MessageType type, QJSEngine *engine);
- void stateChanged(State);
+ void stateChanged(State) Q_DECL_OVERRIDE;
};
QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp
index 245900abae..a193ddea0b 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp
@@ -1,44 +1,53 @@
/****************************************************************************
**
-** 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$
**
****************************************************************************/
#include "qqmlprofileradapter.h"
+#include "qqmldebugpacket.h"
+
#include <private/qqmldebugserviceinterfaces_p.h>
QT_BEGIN_NAMESPACE
QQmlProfilerAdapter::QQmlProfilerAdapter(QQmlProfilerService *service, QQmlEnginePrivate *engine) :
- QQmlAbstractProfilerAdapter(service), next(0)
+ next(0)
{
+ setService(service);
engine->enableProfiler();
connect(this, SIGNAL(profilingEnabled(quint64)), engine->profiler, SLOT(startProfiling(quint64)));
connect(this, SIGNAL(profilingEnabledWhileWaiting(quint64)),
@@ -49,74 +58,81 @@ QQmlProfilerAdapter::QQmlProfilerAdapter(QQmlProfilerService *service, QQmlEngin
connect(this, SIGNAL(dataRequested()), engine->profiler, SLOT(reportData()));
connect(this, SIGNAL(referenceTimeKnown(QElapsedTimer)),
engine->profiler, SLOT(setTimer(QElapsedTimer)));
- connect(engine->profiler, SIGNAL(dataReady(QVector<QQmlProfilerData>)),
- this, SLOT(receiveData(QVector<QQmlProfilerData>)));
+ connect(engine->profiler,
+ SIGNAL(dataReady(QVector<QQmlProfilerData>,QQmlProfiler::LocationHash)),
+ this,
+ SLOT(receiveData(QVector<QQmlProfilerData>,QQmlProfiler::LocationHash)));
}
// convert to QByteArrays that can be sent to the debug client
// use of QDataStream can skew results
// (see tst_qqmldebugtrace::trace() benchmark)
-static void qQmlProfilerDataToByteArrays(const QQmlProfilerData *d, QList<QByteArray> &messages)
+static void qQmlProfilerDataToByteArrays(const QQmlProfilerData &d,
+ const QQmlProfiler::LocationHash &locations,
+ QList<QByteArray> &messages)
{
- QByteArray data;
- Q_ASSERT_X(((d->messageType | d->detailType) & (1 << 31)) == 0, Q_FUNC_INFO,
- "You can use at most 31 message types and 31 detail types.");
- for (uint decodedMessageType = 0; (d->messageType >> decodedMessageType) != 0;
+ QQmlDebugPacket ds;
+ Q_ASSERT_X((d.messageType & (1 << 31)) == 0, Q_FUNC_INFO,
+ "You can use at most 31 message types.");
+ for (quint32 decodedMessageType = 0; (d.messageType >> decodedMessageType) != 0;
++decodedMessageType) {
- if ((d->messageType & (1 << decodedMessageType)) == 0)
+ if ((d.messageType & (1 << decodedMessageType)) == 0)
continue;
- for (uint decodedDetailType = 0; (d->detailType >> decodedDetailType) != 0;
- ++decodedDetailType) {
- if ((d->detailType & (1 << decodedDetailType)) == 0)
- continue;
+ //### using QDataStream is relatively expensive
+ ds << d.time << decodedMessageType << static_cast<quint32>(d.detailType);
- //### using QDataStream is relatively expensive
- QQmlDebugStream ds(&data, QIODevice::WriteOnly);
- ds << d->time << decodedMessageType << decodedDetailType;
+ QQmlProfiler::Location l = locations.value(d.locationId);
- switch (decodedMessageType) {
- case QQmlProfilerDefinitions::RangeStart:
- if (decodedDetailType == (int)QQmlProfilerDefinitions::Binding)
- ds << QQmlProfilerDefinitions::QmlBinding;
- break;
- case QQmlProfilerDefinitions::RangeData:
- ds << (d->detailString.isEmpty() ? d->detailUrl.toString() : d->detailString);
- break;
- case QQmlProfilerDefinitions::RangeLocation:
- ds << (d->detailUrl.isEmpty() ? d->detailString : d->detailUrl.toString()) << d->x
- << d->y;
- break;
- case QQmlProfilerDefinitions::RangeEnd: break;
- default:
- Q_ASSERT_X(false, Q_FUNC_INFO, "Invalid message type.");
- break;
- }
- messages << data;
- data.clear();
+ switch (decodedMessageType) {
+ case QQmlProfilerDefinitions::RangeStart:
+ case QQmlProfilerDefinitions::RangeEnd:
+ break;
+ case QQmlProfilerDefinitions::RangeData:
+ ds << (l.location.sourceFile.isEmpty() ? l.url.toString() : l.location.sourceFile);
+ break;
+ case QQmlProfilerDefinitions::RangeLocation:
+ ds << (l.url.isEmpty() ? l.location.sourceFile : l.url.toString())
+ << static_cast<qint32>(l.location.line) << static_cast<qint32>(l.location.column);
+ break;
+ default:
+ Q_ASSERT_X(false, Q_FUNC_INFO, "Invalid message type.");
+ break;
}
+ messages.append(ds.squeezedData());
+ ds.clear();
}
}
qint64 QQmlProfilerAdapter::sendMessages(qint64 until, QList<QByteArray> &messages)
{
while (next != data.length()) {
- if (data[next].time > until)
- return data[next].time;
- qQmlProfilerDataToByteArrays(&(data[next++]), messages);
+ const QQmlProfilerData &nextData = data.at(next);
+ if (nextData.time > until || messages.length() > s_numMessagesPerBatch)
+ return nextData.time;
+ qQmlProfilerDataToByteArrays(nextData, locations, messages);
+ ++next;
}
next = 0;
data.clear();
+ locations.clear();
return -1;
}
-void QQmlProfilerAdapter::receiveData(const QVector<QQmlProfilerData> &new_data)
+void QQmlProfilerAdapter::receiveData(const QVector<QQmlProfilerData> &new_data,
+ const QQmlProfiler::LocationHash &new_locations)
{
if (data.isEmpty())
data = new_data;
else
data.append(new_data);
+
+ if (locations.isEmpty())
+ locations = new_locations;
+ else
+ locations.unite(new_locations);
+
service->dataReady(this);
}
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.h b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.h
index eceb58ce3a..7e13b6c479 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.h
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.h
@@ -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$
**
@@ -54,13 +60,15 @@ class QQmlProfilerAdapter : public QQmlAbstractProfilerAdapter {
Q_OBJECT
public:
QQmlProfilerAdapter(QQmlProfilerService *service, QQmlEnginePrivate *engine);
- qint64 sendMessages(qint64 until, QList<QByteArray> &messages);
+ qint64 sendMessages(qint64 until, QList<QByteArray> &messages) Q_DECL_OVERRIDE;
public slots:
- void receiveData(const QVector<QQmlProfilerData> &new_data);
+ void receiveData(const QVector<QQmlProfilerData> &new_data,
+ const QQmlProfiler::LocationHash &locations);
private:
QVector<QQmlProfilerData> data;
+ QQmlProfiler::LocationHash locations;
int next;
};
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();
}
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.h b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.h
index 9b139ffabb..6490e77f44 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.h
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.h
@@ -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$
**
@@ -64,8 +70,6 @@
QT_BEGIN_NAMESPACE
class QUrl;
-class QQmlEngine;
-
class QQmlProfilerServiceImpl :
public QQmlConfigurableDebugService<QQmlProfilerService>,
@@ -74,21 +78,22 @@ class QQmlProfilerServiceImpl :
Q_OBJECT
public:
- void engineAboutToBeAdded(QQmlEngine *engine);
- void engineAboutToBeRemoved(QQmlEngine *engine);
- void engineAdded(QQmlEngine *engine);
- void engineRemoved(QQmlEngine *engine);
+ void engineAboutToBeAdded(QJSEngine *engine) Q_DECL_OVERRIDE;
+ void engineAboutToBeRemoved(QJSEngine *engine) Q_DECL_OVERRIDE;
+ void engineAdded(QJSEngine *engine) Q_DECL_OVERRIDE;
+ void engineRemoved(QJSEngine *engine) Q_DECL_OVERRIDE;
- void addGlobalProfiler(QQmlAbstractProfilerAdapter *profiler);
- void removeGlobalProfiler(QQmlAbstractProfilerAdapter *profiler);
+ void addGlobalProfiler(QQmlAbstractProfilerAdapter *profiler) Q_DECL_OVERRIDE;
+ void removeGlobalProfiler(QQmlAbstractProfilerAdapter *profiler) Q_DECL_OVERRIDE;
- void startProfiling(QQmlEngine *engine, quint64 features = std::numeric_limits<quint64>::max());
- void stopProfiling(QQmlEngine *engine);
+ void startProfiling(QJSEngine *engine,
+ quint64 features = std::numeric_limits<quint64>::max()) Q_DECL_OVERRIDE;
+ void stopProfiling(QJSEngine *engine) Q_DECL_OVERRIDE;
QQmlProfilerServiceImpl(QObject *parent = 0);
- ~QQmlProfilerServiceImpl();
+ ~QQmlProfilerServiceImpl() Q_DECL_OVERRIDE;
- void dataReady(QQmlAbstractProfilerAdapter *profiler);
+ void dataReady(QQmlAbstractProfilerAdapter *profiler) Q_DECL_OVERRIDE;
signals:
void startFlushTimer();
@@ -98,14 +103,14 @@ private slots:
void flush();
protected:
- virtual void stateAboutToBeChanged(State state);
- virtual void messageReceived(const QByteArray &);
+ virtual void stateAboutToBeChanged(State state) Q_DECL_OVERRIDE;
+ virtual void messageReceived(const QByteArray &) Q_DECL_OVERRIDE;
private:
friend class QQmlProfilerServiceFactory;
void sendMessages();
- void addEngineProfiler(QQmlAbstractProfilerAdapter *profiler, QQmlEngine *engine);
+ void addEngineProfiler(QQmlAbstractProfilerAdapter *profiler, QJSEngine *engine);
void removeProfilerFromStartTimes(const QQmlAbstractProfilerAdapter *profiler);
QElapsedTimer m_timer;
@@ -113,8 +118,8 @@ private:
bool m_waitingForStop;
QList<QQmlAbstractProfilerAdapter *> m_globalProfilers;
- QMultiHash<QQmlEngine *, QQmlAbstractProfilerAdapter *> m_engineProfilers;
- QList<QQmlEngine *> m_stoppingEngines;
+ QMultiHash<QJSEngine *, QQmlAbstractProfilerAdapter *> m_engineProfilers;
+ QList<QJSEngine *> m_stoppingEngines;
QMultiMap<qint64, QQmlAbstractProfilerAdapter *> m_startTimes;
};
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservicefactory.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservicefactory.cpp
index 83c2075246..19100b6e8f 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservicefactory.cpp
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservicefactory.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$
**
@@ -42,8 +48,8 @@ QQmlDebugService *QQmlProfilerServiceFactory::create(const QString &key)
if (key == QQmlProfilerServiceImpl::s_key)
return new QQmlProfilerServiceImpl(this);
- if (key == QQmlEngineControlService::s_key)
- return new QQmlEngineControlService(this);
+ if (key == QQmlEngineControlServiceImpl::s_key)
+ return new QQmlEngineControlServiceImpl(this);
return 0;
}
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservicefactory.h b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservicefactory.h
index b570136e5b..772e53bde7 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservicefactory.h
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservicefactory.h
@@ -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$
**
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp b/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp
index 24e01f4c68..68a71a5524 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp
+++ b/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.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$
**
@@ -37,12 +43,17 @@
QT_BEGIN_NAMESPACE
QV4ProfilerAdapter::QV4ProfilerAdapter(QQmlProfilerService *service, QV4::ExecutionEngine *engine) :
- QQmlAbstractProfilerAdapter(service), dataPos(0), memoryPos(0)
+ m_functionCallPos(0), m_memoryPos(0)
{
+ setService(service);
engine->enableProfiler();
connect(this, SIGNAL(profilingEnabled(quint64)),
- engine->profiler, SLOT(startProfiling(quint64)));
+ this, SLOT(forwardEnabled(quint64)));
connect(this, SIGNAL(profilingEnabledWhileWaiting(quint64)),
+ this, SLOT(forwardEnabledWhileWaiting(quint64)), Qt::DirectConnection);
+ connect(this, SIGNAL(v4ProfilingEnabled(quint64)),
+ engine->profiler, SLOT(startProfiling(quint64)));
+ connect(this, SIGNAL(v4ProfilingEnabledWhileWaiting(quint64)),
engine->profiler, SLOT(startProfiling(quint64)), Qt::DirectConnection);
connect(this, SIGNAL(profilingDisabled()), engine->profiler, SLOT(stopProfiling()));
connect(this, SIGNAL(profilingDisabledWhileWaiting()), engine->profiler, SLOT(stopProfiling()),
@@ -50,38 +61,44 @@ QV4ProfilerAdapter::QV4ProfilerAdapter(QQmlProfilerService *service, QV4::Execut
connect(this, SIGNAL(dataRequested()), engine->profiler, SLOT(reportData()));
connect(this, SIGNAL(referenceTimeKnown(QElapsedTimer)),
engine->profiler, SLOT(setTimer(QElapsedTimer)));
- connect(engine->profiler, SIGNAL(dataReady(QVector<QV4::Profiling::FunctionCallProperties>,
+ connect(engine->profiler, SIGNAL(dataReady(QV4::Profiling::FunctionLocationHash,
+ QVector<QV4::Profiling::FunctionCallProperties>,
QVector<QV4::Profiling::MemoryAllocationProperties>)),
- this, SLOT(receiveData(QVector<QV4::Profiling::FunctionCallProperties>,
+ this, SLOT(receiveData(QV4::Profiling::FunctionLocationHash,
+ QVector<QV4::Profiling::FunctionCallProperties>,
QVector<QV4::Profiling::MemoryAllocationProperties>)));
}
-qint64 QV4ProfilerAdapter::appendMemoryEvents(qint64 until, QList<QByteArray> &messages)
+qint64 QV4ProfilerAdapter::appendMemoryEvents(qint64 until, QList<QByteArray> &messages,
+ QQmlDebugPacket &d)
{
- QByteArray message;
- while (memory_data.length() > memoryPos && memory_data[memoryPos].timestamp <= until) {
- QQmlDebugStream d(&message, QIODevice::WriteOnly);
- QV4::Profiling::MemoryAllocationProperties &props = memory_data[memoryPos];
+ // Make it const, so that we cannot accidentally detach it.
+ const QVector<QV4::Profiling::MemoryAllocationProperties> &memoryData = m_memoryData;
+
+ while (memoryData.length() > m_memoryPos && memoryData[m_memoryPos].timestamp <= until) {
+ const QV4::Profiling::MemoryAllocationProperties &props = memoryData[m_memoryPos];
d << props.timestamp << MemoryAllocation << props.type << props.size;
- ++memoryPos;
- messages.append(message);
+ ++m_memoryPos;
+ messages.append(d.squeezedData());
+ d.clear();
}
- return memory_data.length() == memoryPos ? -1 : memory_data[memoryPos].timestamp;
+ return memoryData.length() == m_memoryPos ? -1 : memoryData[m_memoryPos].timestamp;
}
qint64 QV4ProfilerAdapter::finalizeMessages(qint64 until, QList<QByteArray> &messages,
- qint64 callNext)
+ qint64 callNext, QQmlDebugPacket &d)
{
if (callNext == -1) {
- data.clear();
- dataPos = 0;
+ m_functionLocations.clear();
+ m_functionCallData.clear();
+ m_functionCallPos = 0;
}
- qint64 memoryNext = appendMemoryEvents(until, messages);
+ qint64 memoryNext = appendMemoryEvents(until, messages, d);
if (memoryNext == -1) {
- memory_data.clear();
- memoryPos = 0;
+ m_memoryData.clear();
+ m_memoryPos = 0;
return callNext;
}
@@ -90,64 +107,97 @@ qint64 QV4ProfilerAdapter::finalizeMessages(qint64 until, QList<QByteArray> &mes
qint64 QV4ProfilerAdapter::sendMessages(qint64 until, QList<QByteArray> &messages)
{
- QByteArray message;
+ QQmlDebugPacket d;
+
+ // Make it const, so that we cannot accidentally detach it.
+ const QVector<QV4::Profiling::FunctionCallProperties> &functionCallData = m_functionCallData;
+ const QV4::Profiling::FunctionLocationHash &functionLocations = m_functionLocations;
+
while (true) {
- while (!stack.isEmpty() && (dataPos == data.length() ||
- stack.top() <= data[dataPos].start)) {
- if (stack.top() > until)
- return finalizeMessages(until, messages, stack.top());
-
- appendMemoryEvents(stack.top(), messages);
- QQmlDebugStream d(&message, QIODevice::WriteOnly);
- d << stack.pop() << RangeEnd << Javascript;
- messages.append(message);
+ while (!m_stack.isEmpty() &&
+ (m_functionCallPos == functionCallData.length() ||
+ m_stack.top() <= functionCallData[m_functionCallPos].start)) {
+ if (m_stack.top() > until || messages.length() > s_numMessagesPerBatch)
+ return finalizeMessages(until, messages, m_stack.top(), d);
+
+ appendMemoryEvents(m_stack.top(), messages, d);
+ d << m_stack.pop() << RangeEnd << Javascript;
+ messages.append(d.squeezedData());
+ d.clear();
}
- while (dataPos != data.length() && (stack.empty() || data[dataPos].start < stack.top())) {
- const QV4::Profiling::FunctionCallProperties &props = data[dataPos];
- if (props.start > until)
- return finalizeMessages(until, messages, props.start);
-
- appendMemoryEvents(props.start, messages);
-
- QQmlDebugStream d_start(&message, QIODevice::WriteOnly);
- d_start << props.start << RangeStart << Javascript;
- messages.push_back(message);
- message.clear();
- QQmlDebugStream d_location(&message, QIODevice::WriteOnly);
- d_location << props.start << RangeLocation << Javascript << props.file << props.line
- << props.column;
- messages.push_back(message);
- message.clear();
- QQmlDebugStream d_data(&message, QIODevice::WriteOnly);
- d_data << props.start << RangeData << Javascript << props.name;
- messages.push_back(message);
- message.clear();
- stack.push(props.end);
- ++dataPos;
+ while (m_functionCallPos != functionCallData.length() &&
+ (m_stack.empty() || functionCallData[m_functionCallPos].start < m_stack.top())) {
+ const QV4::Profiling::FunctionCallProperties &props =
+ functionCallData[m_functionCallPos];
+ if (props.start > until || messages.length() > s_numMessagesPerBatch)
+ return finalizeMessages(until, messages, props.start, d);
+
+ appendMemoryEvents(props.start, messages, d);
+ auto location = functionLocations.constFind(props.id);
+ Q_ASSERT(location != functionLocations.constEnd());
+
+ d << props.start << RangeStart << Javascript;
+ messages.push_back(d.squeezedData());
+ d.clear();
+ d << props.start << RangeLocation << Javascript << location->file << location->line
+ << location->column;
+ messages.push_back(d.squeezedData());
+ d.clear();
+ d << props.start << RangeData << Javascript << location->name;
+ messages.push_back(d.squeezedData());
+ d.clear();
+ m_stack.push(props.end);
+ ++m_functionCallPos;
}
- if (stack.empty() && dataPos == data.length())
- return finalizeMessages(until, messages, -1);
+ if (m_stack.empty() && m_functionCallPos == functionCallData.length())
+ return finalizeMessages(until, messages, -1, d);
}
}
void QV4ProfilerAdapter::receiveData(
- const QVector<QV4::Profiling::FunctionCallProperties> &new_data,
- const QVector<QV4::Profiling::MemoryAllocationProperties> &new_memory_data)
+ const QV4::Profiling::FunctionLocationHash &locations,
+ const QVector<QV4::Profiling::FunctionCallProperties> &functionCallData,
+ const QVector<QV4::Profiling::MemoryAllocationProperties> &memoryData)
{
// In rare cases it could be that another flush or stop event is processed while data from
// the previous one is still pending. In that case we just append the data.
+ if (m_functionLocations.isEmpty())
+ m_functionLocations = locations;
+ else
+ m_functionLocations.unite(locations);
- if (data.isEmpty())
- data = new_data;
+ if (m_functionCallData.isEmpty())
+ m_functionCallData = functionCallData;
else
- data.append(new_data);
+ m_functionCallData.append(functionCallData);
- if (memory_data.isEmpty())
- memory_data = new_memory_data;
+ if (m_memoryData.isEmpty())
+ m_memoryData = memoryData;
else
- memory_data.append(new_memory_data);
+ m_memoryData.append(memoryData);
service->dataReady(this);
}
+quint64 QV4ProfilerAdapter::translateFeatures(quint64 qmlFeatures)
+{
+ quint64 v4Features = 0;
+ const quint64 one = 1;
+ if (qmlFeatures & (one << ProfileJavaScript))
+ v4Features |= (one << QV4::Profiling::FeatureFunctionCall);
+ if (qmlFeatures & (one << ProfileMemory))
+ v4Features |= (one << QV4::Profiling::FeatureMemoryAllocation);
+ return v4Features;
+}
+
+void QV4ProfilerAdapter::forwardEnabled(quint64 features)
+{
+ emit v4ProfilingEnabled(translateFeatures(features));
+}
+
+void QV4ProfilerAdapter::forwardEnabledWhileWaiting(quint64 features)
+{
+ emit v4ProfilingEnabledWhileWaiting(translateFeatures(features));
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.h b/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.h
index cea3da72e3..968825c346 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.h
+++ b/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.h
@@ -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$
**
@@ -47,6 +53,7 @@
#include <private/qv4profiling_p.h>
#include <private/qqmlabstractprofileradapter_p.h>
+#include "qqmldebugpacket.h"
#include <QStack>
#include <QList>
@@ -62,18 +69,31 @@ public:
virtual qint64 sendMessages(qint64 until, QList<QByteArray> &messages);
+signals:
+ void v4ProfilingEnabled(quint64 v4Features);
+ void v4ProfilingEnabledWhileWaiting(quint64 v4Features);
+
public slots:
- void receiveData(const QVector<QV4::Profiling::FunctionCallProperties> &,
+ void receiveData(const QV4::Profiling::FunctionLocationHash &,
+ const QVector<QV4::Profiling::FunctionCallProperties> &,
const QVector<QV4::Profiling::MemoryAllocationProperties> &);
+private slots:
+ void forwardEnabled(quint64 features);
+ void forwardEnabledWhileWaiting(quint64 features);
+
private:
- QVector<QV4::Profiling::FunctionCallProperties> data;
- QVector<QV4::Profiling::MemoryAllocationProperties> memory_data;
- int dataPos;
- int memoryPos;
- QStack<qint64> stack;
- qint64 appendMemoryEvents(qint64 until, QList<QByteArray> &messages);
- qint64 finalizeMessages(qint64 until, QList<QByteArray> &messages, qint64 callNext);
+ QV4::Profiling::FunctionLocationHash m_functionLocations;
+ QVector<QV4::Profiling::FunctionCallProperties> m_functionCallData;
+ QVector<QV4::Profiling::MemoryAllocationProperties> m_memoryData;
+ int m_functionCallPos;
+ int m_memoryPos;
+ QStack<qint64> m_stack;
+ qint64 appendMemoryEvents(qint64 until, QList<QByteArray> &messages, QQmlDebugPacket &d);
+ qint64 finalizeMessages(qint64 until, QList<QByteArray> &messages, qint64 callNext,
+ QQmlDebugPacket &d);
+
+ static quint64 translateFeatures(quint64 qmlFeatures);
};
QT_END_NAMESPACE