aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/debugger
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/debugger')
-rw-r--r--src/qml/debugger/debugger.pri27
-rw-r--r--src/qml/debugger/qqmlabstractprofileradapter_p.h10
-rw-r--r--src/qml/debugger/qqmldebug.cpp17
-rw-r--r--src/qml/debugger/qqmldebug.h3
-rw-r--r--src/qml/debugger/qqmldebugconnector_p.h25
-rw-r--r--src/qml/debugger/qqmldebugservice.cpp33
-rw-r--r--src/qml/debugger/qqmldebugservice_p.h20
-rw-r--r--src/qml/debugger/qqmldebugserviceinterfaces_p.h57
-rw-r--r--src/qml/debugger/qqmldebugstatesdelegate_p.h7
-rw-r--r--src/qml/debugger/qqmlmemoryprofiler.cpp157
-rw-r--r--src/qml/debugger/qqmlmemoryprofiler_p.h96
-rw-r--r--src/qml/debugger/qqmlprofiler.cpp18
-rw-r--r--src/qml/debugger/qqmlprofiler_p.h94
-rw-r--r--src/qml/debugger/qqmlprofilerdefinitions_p.h4
14 files changed, 456 insertions, 112 deletions
diff --git a/src/qml/debugger/debugger.pri b/src/qml/debugger/debugger.pri
index 30a44eedd1..da1ab867d4 100644
--- a/src/qml/debugger/debugger.pri
+++ b/src/qml/debugger/debugger.pri
@@ -1,21 +1,28 @@
-contains(QT_CONFIG, no-qml-debug):DEFINES += QT_NO_QML_DEBUGGER
+contains(QT_CONFIG, no-qml-debug) {
+ DEFINES += QT_NO_QML_DEBUGGER
+ MODULE_DEFINES += QT_NO_QML_DEBUGGER
+} else {
+ HEADERS += \
+ $$PWD/qqmldebugpluginmanager_p.h \
+ $$PWD/qqmldebugservicefactory_p.h
-SOURCES += \
- $$PWD/qqmldebug.cpp \
- $$PWD/qqmldebugconnector.cpp \
- $$PWD/qqmldebugservice.cpp \
- $$PWD/qqmldebugserviceinterfaces.cpp \
- $$PWD/qqmlabstractprofileradapter.cpp \
- $$PWD/qqmlprofiler.cpp
+ SOURCES += \
+ $$PWD/qqmldebug.cpp \
+ $$PWD/qqmldebugconnector.cpp \
+ $$PWD/qqmldebugservice.cpp \
+ $$PWD/qqmlabstractprofileradapter.cpp \
+ $$PWD/qqmlmemoryprofiler.cpp \
+ $$PWD/qqmlprofiler.cpp \
+ $$PWD/qqmldebugserviceinterfaces.cpp
+}
HEADERS += \
$$PWD/qqmldebugconnector_p.h \
- $$PWD/qqmldebugpluginmanager_p.h \
$$PWD/qqmldebugservice_p.h \
- $$PWD/qqmldebugservicefactory_p.h \
$$PWD/qqmldebugserviceinterfaces_p.h \
$$PWD/qqmldebugstatesdelegate_p.h \
$$PWD/qqmldebug.h \
+ $$PWD/qqmlmemoryprofiler_p.h \
$$PWD/qqmlprofilerdefinitions_p.h \
$$PWD/qqmlabstractprofileradapter_p.h \
$$PWD/qqmlprofiler_p.h
diff --git a/src/qml/debugger/qqmlabstractprofileradapter_p.h b/src/qml/debugger/qqmlabstractprofileradapter_p.h
index 1104608055..6a05a80f37 100644
--- a/src/qml/debugger/qqmlabstractprofileradapter_p.h
+++ b/src/qml/debugger/qqmlabstractprofileradapter_p.h
@@ -59,6 +59,8 @@
QT_BEGIN_NAMESPACE
+#ifndef QT_NO_QML_DEBUGGER
+
class QQmlProfilerService;
class Q_QML_PRIVATE_EXPORT QQmlAbstractProfilerAdapter : public QObject, public QQmlProfilerDefinitions {
Q_OBJECT
@@ -71,13 +73,13 @@ public:
virtual ~QQmlAbstractProfilerAdapter() {}
void setService(QQmlProfilerService *new_service) { service = new_service; }
- virtual qint64 sendMessages(qint64 until, QList<QByteArray> &messages) = 0;
+ virtual qint64 sendMessages(qint64 until, QList<QByteArray> &messages, bool trackLocations) = 0;
void startProfiling(quint64 features);
void stopProfiling();
- void reportData() { emit dataRequested(); }
+ void reportData(bool trackLocations) { emit dataRequested(trackLocations); }
void stopWaiting() { waiting = false; }
void startWaiting() { waiting = true; }
@@ -94,7 +96,7 @@ signals:
void profilingDisabled();
void profilingDisabledWhileWaiting();
- void dataRequested();
+ void dataRequested(bool trackLocations);
void referenceTimeKnown(const QElapsedTimer &timer);
protected:
@@ -114,6 +116,8 @@ public:
#define QQmlAbstractProfilerAdapterFactory_iid "org.qt-project.Qt.QQmlAbstractProfilerAdapterFactory"
+#endif // QT_NO_QML_DEBUGGER
+
QT_END_NAMESPACE
#endif // QQMLABSTRACTPROFILERADAPTER_P_H
diff --git a/src/qml/debugger/qqmldebug.cpp b/src/qml/debugger/qqmldebug.cpp
index 557cce08d5..b2c4b139ee 100644
--- a/src/qml/debugger/qqmldebug.cpp
+++ b/src/qml/debugger/qqmldebug.cpp
@@ -47,15 +47,11 @@ QT_BEGIN_NAMESPACE
QQmlDebuggingEnabler::QQmlDebuggingEnabler(bool printWarning)
{
-#ifndef QQML_NO_DEBUG_PROTOCOL
if (!QQmlEnginePrivate::qml_debugging_enabled
&& printWarning) {
qDebug("QML debugging is enabled. Only use this in a safe environment.");
}
QQmlEnginePrivate::qml_debugging_enabled = true;
-#else
- Q_UNUSED(printWarning);
-#endif
}
/*!
@@ -105,11 +101,7 @@ QStringList QQmlDebuggingEnabler::profilerServices()
*/
void QQmlDebuggingEnabler::setServices(const QStringList &services)
{
-#ifndef QQML_NO_DEBUG_PROTOCOL
QQmlDebugConnector::setServices(services);
-#else
- Q_UNUSED(services);
-#endif
}
/*!
@@ -172,16 +164,9 @@ bool QQmlDebuggingEnabler::connectToLocalDebugger(const QString &socketFileName,
bool QQmlDebuggingEnabler::startDebugConnector(const QString &pluginName,
const QVariantHash &configuration)
{
-#ifndef QQML_NO_DEBUG_PROTOCOL
QQmlDebugConnector::setPluginKey(pluginName);
QQmlDebugConnector *connector = QQmlDebugConnector::instance();
- if (connector)
- return connector->open(configuration);
-#else
- Q_UNUSED(pluginName);
- Q_UNUSED(configuration);
-#endif
- return false;
+ return connector ? connector->open(configuration) : false;
}
enum { HookCount = 3 };
diff --git a/src/qml/debugger/qqmldebug.h b/src/qml/debugger/qqmldebug.h
index 660b9e4d46..fb41039867 100644
--- a/src/qml/debugger/qqmldebug.h
+++ b/src/qml/debugger/qqmldebug.h
@@ -46,6 +46,7 @@
QT_BEGIN_NAMESPACE
+#ifndef QT_NO_QML_DEBUGGER
struct Q_QML_EXPORT QQmlDebuggingEnabler
{
@@ -77,6 +78,8 @@ static QQmlDebuggingEnabler qQmlEnableDebuggingHelper(false);
static QQmlDebuggingEnabler qQmlEnableDebuggingHelper(true);
#endif
+#endif
+
QT_END_NAMESPACE
#endif // QQMLDEBUG_H
diff --git a/src/qml/debugger/qqmldebugconnector_p.h b/src/qml/debugger/qqmldebugconnector_p.h
index 05755250bd..0d3e2e2e47 100644
--- a/src/qml/debugger/qqmldebugconnector_p.h
+++ b/src/qml/debugger/qqmldebugconnector_p.h
@@ -59,6 +59,29 @@
QT_BEGIN_NAMESPACE
+#ifdef QT_NO_QML_DEBUGGER
+
+class Q_QML_PRIVATE_EXPORT QQmlDebugConnector
+{
+public:
+ static QQmlDebugConnector *instance() { return nullptr; }
+
+ template<class Service>
+ static Service *service() { return nullptr; }
+
+ bool hasEngine(QJSEngine *) const { return false; }
+ void addEngine(QJSEngine *) {}
+ void removeEngine(QJSEngine *) {}
+
+ bool open(const QVariantHash &configuration = QVariantHash())
+ {
+ Q_UNUSED(configuration);
+ return false;
+ }
+};
+
+#else
+
class QQmlDebugService;
class Q_QML_PRIVATE_EXPORT QQmlDebugConnector : public QObject
{
@@ -106,6 +129,8 @@ public:
#define QQmlDebugConnectorFactory_iid "org.qt-project.Qt.QQmlDebugConnectorFactory"
+#endif
+
QT_END_NAMESPACE
#endif // QQMLDEBUGCONNECTOR_H
diff --git a/src/qml/debugger/qqmldebugservice.cpp b/src/qml/debugger/qqmldebugservice.cpp
index b780735f48..b576c3bb85 100644
--- a/src/qml/debugger/qqmldebugservice.cpp
+++ b/src/qml/debugger/qqmldebugservice.cpp
@@ -132,7 +132,6 @@ public:
int nextId;
-private slots:
void remove(QObject *obj);
};
}
@@ -163,7 +162,7 @@ int QQmlDebugService::idForObject(QObject *object)
int id = hash->nextId++;
hash->ids.insert(id, object);
iter = hash->objects.insert(object, id);
- connect(object, SIGNAL(destroyed(QObject*)), hash, SLOT(remove(QObject*)));
+ connect(object, &QObject::destroyed, hash, &ObjectReferenceHash::remove);
}
return iter.value();
}
@@ -176,36 +175,6 @@ const QHash<int, QObject *> &QQmlDebugService::objectsForIds()
return objectReferenceHash()->ids;
}
-void QQmlDebugService::stateAboutToBeChanged(State)
-{
-}
-
-void QQmlDebugService::stateChanged(State)
-{
-}
-
-void QQmlDebugService::messageReceived(const QByteArray &)
-{
-}
-
-void QQmlDebugService::engineAboutToBeAdded(QJSEngine *engine)
-{
- emit attachedToEngine(engine);
-}
-
-void QQmlDebugService::engineAboutToBeRemoved(QJSEngine *engine)
-{
- emit detachedFromEngine(engine);
-}
-
-void QQmlDebugService::engineAdded(QJSEngine *)
-{
-}
-
-void QQmlDebugService::engineRemoved(QJSEngine *)
-{
-}
-
QT_END_NAMESPACE
#include "qqmldebugservice.moc"
diff --git a/src/qml/debugger/qqmldebugservice_p.h b/src/qml/debugger/qqmldebugservice_p.h
index 9ddc692ecc..42a57a39f2 100644
--- a/src/qml/debugger/qqmldebugservice_p.h
+++ b/src/qml/debugger/qqmldebugservice_p.h
@@ -58,6 +58,8 @@
QT_BEGIN_NAMESPACE
+#ifndef QT_NO_QML_DEBUGGER
+
class QJSEngine;
class QQmlDebugServicePrivate;
@@ -65,7 +67,6 @@ class Q_QML_PRIVATE_EXPORT QQmlDebugService : public QObject
{
Q_OBJECT
Q_DECLARE_PRIVATE(QQmlDebugService)
- Q_DISABLE_COPY(QQmlDebugService)
public:
~QQmlDebugService();
@@ -77,14 +78,15 @@ public:
State state() const;
void setState(State newState);
- virtual void stateAboutToBeChanged(State);
- virtual void stateChanged(State);
- virtual void messageReceived(const QByteArray &);
+ virtual void stateAboutToBeChanged(State) {}
+ virtual void stateChanged(State) {}
+ virtual void messageReceived(const QByteArray &) {}
+
+ virtual void engineAboutToBeAdded(QJSEngine *engine) { emit attachedToEngine(engine); }
+ virtual void engineAboutToBeRemoved(QJSEngine *engine) { emit detachedFromEngine(engine); }
- virtual void engineAboutToBeAdded(QJSEngine *);
- virtual void engineAboutToBeRemoved(QJSEngine *);
- virtual void engineAdded(QJSEngine *);
- virtual void engineRemoved(QJSEngine *);
+ virtual void engineAdded(QJSEngine *) {}
+ virtual void engineRemoved(QJSEngine *) {}
static const QHash<int, QObject *> &objectsForIds();
static int idForObject(QObject *);
@@ -101,6 +103,8 @@ signals:
void messagesToClient(const QString &name, const QList<QByteArray> &messages);
};
+#endif
+
QT_END_NAMESPACE
#endif // QQMLDEBUGSERVICE_H
diff --git a/src/qml/debugger/qqmldebugserviceinterfaces_p.h b/src/qml/debugger/qqmldebugserviceinterfaces_p.h
index 8f66779872..ca6293c3ec 100644
--- a/src/qml/debugger/qqmldebugserviceinterfaces_p.h
+++ b/src/qml/debugger/qqmldebugserviceinterfaces_p.h
@@ -62,7 +62,46 @@
QT_BEGIN_NAMESPACE
-class Q_QML_PRIVATE_EXPORT QV4DebugService : protected QQmlDebugService
+class QWindow;
+class QQuickWindow;
+
+#ifdef QT_NO_QML_DEBUGGER
+
+struct QV4DebugService
+{
+ void signalEmitted(const QString &) {}
+};
+
+struct QQmlProfilerService
+{
+ void startProfiling(QJSEngine *engine, quint64 features = std::numeric_limits<quint64>::max())
+ {
+ Q_UNUSED(engine);
+ Q_UNUSED(features);
+ }
+
+ void stopProfiling(QJSEngine *) {}
+};
+
+struct QQmlEngineDebugService
+{
+ void objectCreated(QJSEngine *, QObject *) {}
+ virtual void setStatesDelegate(QQmlDebugStatesDelegate *) {}
+};
+
+struct QQmlInspectorService {
+ void addWindow(QQuickWindow *) {}
+ void setParentWindow(QQuickWindow *, QWindow *) {}
+ void removeWindow(QQuickWindow *) {}
+};
+
+struct QDebugMessageService {};
+struct QQmlEngineControlService {};
+struct QQmlNativeDebugService {};
+
+#else
+
+class Q_QML_PRIVATE_EXPORT QV4DebugService : public QQmlDebugService
{
Q_OBJECT
public:
@@ -77,7 +116,7 @@ protected:
QQmlDebugService(s_key, version, parent) {}
};
-class Q_QML_PRIVATE_EXPORT QQmlProfilerService : protected QQmlDebugService
+class Q_QML_PRIVATE_EXPORT QQmlProfilerService : public QQmlDebugService
{
Q_OBJECT
public:
@@ -99,7 +138,7 @@ protected:
QQmlDebugService(s_key, version, parent) {}
};
-class Q_QML_PRIVATE_EXPORT QQmlEngineDebugService : protected QQmlDebugService
+class Q_QML_PRIVATE_EXPORT QQmlEngineDebugService : public QQmlDebugService
{
Q_OBJECT
public:
@@ -117,9 +156,7 @@ protected:
QQmlBoundSignal *nextSignal(QQmlBoundSignal *prev) { return prev->m_nextSignal; }
};
-class QWindow;
-class QQuickWindow;
-class Q_QML_PRIVATE_EXPORT QQmlInspectorService : protected QQmlDebugService
+class Q_QML_PRIVATE_EXPORT QQmlInspectorService : public QQmlDebugService
{
Q_OBJECT
public:
@@ -136,7 +173,7 @@ protected:
QQmlDebugService(s_key, version, parent) {}
};
-class Q_QML_PRIVATE_EXPORT QDebugMessageService : protected QQmlDebugService
+class Q_QML_PRIVATE_EXPORT QDebugMessageService : public QQmlDebugService
{
Q_OBJECT
public:
@@ -151,7 +188,7 @@ protected:
QQmlDebugService(s_key, version, parent) {}
};
-class Q_QML_PRIVATE_EXPORT QQmlEngineControlService : protected QQmlDebugService
+class Q_QML_PRIVATE_EXPORT QQmlEngineControlService : public QQmlDebugService
{
Q_OBJECT
public:
@@ -165,7 +202,7 @@ protected:
};
-class Q_QML_PRIVATE_EXPORT QQmlNativeDebugService : protected QQmlDebugService
+class Q_QML_PRIVATE_EXPORT QQmlNativeDebugService : public QQmlDebugService
{
Q_OBJECT
@@ -178,6 +215,8 @@ protected:
static const QString s_key;
};
+#endif
+
QT_END_NAMESPACE
#endif // QQMLDEBUGSERVICEINTERFACES_P_H
diff --git a/src/qml/debugger/qqmldebugstatesdelegate_p.h b/src/qml/debugger/qqmldebugstatesdelegate_p.h
index 42c4e94b50..95f727fb2d 100644
--- a/src/qml/debugger/qqmldebugstatesdelegate_p.h
+++ b/src/qml/debugger/qqmldebugstatesdelegate_p.h
@@ -57,6 +57,11 @@
QT_BEGIN_NAMESPACE
+#ifdef QT_NO_QML_DEBUGGER
+
+class QQmlDebugStatesDelegate {};
+
+#else
class QQmlContext;
class QQmlProperty;
@@ -90,6 +95,8 @@ private:
Q_DISABLE_COPY(QQmlDebugStatesDelegate)
};
+#endif
+
QT_END_NAMESPACE
#endif // QQMLDEBUGSTATESDELEGATE_P_H
diff --git a/src/qml/debugger/qqmlmemoryprofiler.cpp b/src/qml/debugger/qqmlmemoryprofiler.cpp
new file mode 100644
index 0000000000..60f6d96eaf
--- /dev/null
+++ b/src/qml/debugger/qqmlmemoryprofiler.cpp
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** 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: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 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 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.
+**
+** 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 "qqmlmemoryprofiler_p.h"
+#include <QUrl>
+
+QT_BEGIN_NAMESPACE
+
+enum LibraryState
+{
+ Unloaded,
+ Failed,
+ Loaded
+};
+
+static LibraryState state = Unloaded;
+
+typedef void (qmlmemprofile_stats)(int *allocCount, int *bytesAllocated);
+typedef void (qmlmemprofile_clear)();
+typedef void (qmlmemprofile_enable)();
+typedef void (qmlmemprofile_disable)();
+typedef void (qmlmemprofile_push_location)(const char *filename, int lineNumber);
+typedef void (qmlmemprofile_pop_location)();
+typedef void (qmlmemprofile_save)(const char *filename);
+typedef int (qmlmemprofile_is_enabled)();
+
+static qmlmemprofile_stats *memprofile_stats;
+static qmlmemprofile_clear *memprofile_clear;
+static qmlmemprofile_enable *memprofile_enable;
+static qmlmemprofile_disable *memprofile_disable;
+static qmlmemprofile_push_location *memprofile_push_location;
+static qmlmemprofile_pop_location *memprofile_pop_location;
+static qmlmemprofile_save *memprofile_save;
+static qmlmemprofile_is_enabled *memprofile_is_enabled;
+
+#ifndef QT_NO_LIBRARY
+extern QFunctionPointer qt_linux_find_symbol_sys(const char *symbol);
+#endif
+
+static bool openLibrary()
+{
+#if defined(Q_OS_LINUX) && !defined(QT_NO_LIBRARY)
+ if (state == Unloaded) {
+ memprofile_stats = (qmlmemprofile_stats *) qt_linux_find_symbol_sys("qmlmemprofile_stats");
+ memprofile_clear = (qmlmemprofile_clear *) qt_linux_find_symbol_sys("qmlmemprofile_clear");
+ memprofile_enable = (qmlmemprofile_enable *) qt_linux_find_symbol_sys("qmlmemprofile_enable");
+ memprofile_disable = (qmlmemprofile_disable *) qt_linux_find_symbol_sys("qmlmemprofile_disable");
+ memprofile_push_location = (qmlmemprofile_push_location *) qt_linux_find_symbol_sys("qmlmemprofile_push_location");
+ memprofile_pop_location = (qmlmemprofile_pop_location *) qt_linux_find_symbol_sys("qmlmemprofile_pop_location");
+ memprofile_save = (qmlmemprofile_save *) qt_linux_find_symbol_sys("qmlmemprofile_save");
+ memprofile_is_enabled = (qmlmemprofile_is_enabled *) qt_linux_find_symbol_sys("qmlmemprofile_is_enabled");
+
+ if (memprofile_stats && memprofile_clear && memprofile_enable && memprofile_disable &&
+ memprofile_push_location && memprofile_pop_location && memprofile_save && memprofile_is_enabled)
+ state = Loaded;
+ else
+ state = Failed;
+ }
+#endif // Q_OS_LINUX
+
+ return state == Loaded;
+}
+
+QQmlMemoryScope::QQmlMemoryScope(const QUrl &url)
+ : QQmlMemoryScope(url.path().toUtf8().constData())
+{
+}
+
+QQmlMemoryScope::QQmlMemoryScope(const char *string) : pushed(false)
+{
+ if (openLibrary() && memprofile_is_enabled()) {
+ memprofile_push_location(string, 0);
+ pushed = true;
+ }
+}
+
+QQmlMemoryScope::~QQmlMemoryScope()
+{
+ if (pushed)
+ memprofile_pop_location();
+}
+
+bool QQmlMemoryProfiler::isEnabled()
+{
+ if (openLibrary())
+ return memprofile_is_enabled();
+
+ return false;
+}
+
+void QQmlMemoryProfiler::enable()
+{
+ if (openLibrary())
+ memprofile_enable();
+}
+
+void QQmlMemoryProfiler::disable()
+{
+ if (openLibrary())
+ memprofile_disable();
+}
+
+void QQmlMemoryProfiler::clear()
+{
+ if (openLibrary())
+ memprofile_clear();
+}
+
+void QQmlMemoryProfiler::stats(int *allocCount, int *bytesAllocated)
+{
+ if (openLibrary())
+ memprofile_stats(allocCount, bytesAllocated);
+}
+
+void QQmlMemoryProfiler::save(const char *filename)
+{
+ if (openLibrary())
+ memprofile_save(filename);
+}
+
+QT_END_NAMESPACE
diff --git a/src/qml/debugger/qqmlmemoryprofiler_p.h b/src/qml/debugger/qqmlmemoryprofiler_p.h
new file mode 100644
index 0000000000..59f08704ca
--- /dev/null
+++ b/src/qml/debugger/qqmlmemoryprofiler_p.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** 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: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 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 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.
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef QQMLMEMORYPROFILER_H
+#define QQMLMEMORYPROFILER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qtqmlglobal_p.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifdef QT_NO_QML_DEBUGGER
+
+#define QML_MEMORY_SCOPE_URL(url)
+#define QML_MEMORY_SCOPE_STRING(s)
+
+#else
+
+class QUrl;
+
+class Q_QML_PRIVATE_EXPORT QQmlMemoryScope
+{
+public:
+ explicit QQmlMemoryScope(const QUrl &url);
+ explicit QQmlMemoryScope(const char *string);
+ ~QQmlMemoryScope();
+
+private:
+ bool pushed;
+};
+
+class Q_QML_PRIVATE_EXPORT QQmlMemoryProfiler
+{
+public:
+ static void enable();
+ static void disable();
+ static bool isEnabled();
+
+ static void clear();
+ static void stats(int *allocCount, int *bytesAllocated);
+ static void save(const char *filename);
+};
+
+#define QML_MEMORY_SCOPE_URL(url) QQmlMemoryScope _qml_memory_scope(url)
+#define QML_MEMORY_SCOPE_STRING(s) QQmlMemoryScope _qml_memory_scope(s)
+
+#endif
+
+QT_END_NAMESPACE
+#endif // QQMLMEMORYPROFILER_H
diff --git a/src/qml/debugger/qqmlprofiler.cpp b/src/qml/debugger/qqmlprofiler.cpp
index 629d5cb7b8..ffba731b13 100644
--- a/src/qml/debugger/qqmlprofiler.cpp
+++ b/src/qml/debugger/qqmlprofiler.cpp
@@ -59,19 +59,21 @@ void QQmlProfiler::startProfiling(quint64 features)
void QQmlProfiler::stopProfiling()
{
featuresEnabled = false;
- reportData();
+ reportData(true);
+ m_locations.clear();
}
-void QQmlProfiler::reportData()
+void QQmlProfiler::reportData(bool trackLocations)
{
LocationHash resolved;
resolved.reserve(m_locations.size());
- for (auto it = m_locations.constBegin(), end = m_locations.constEnd(); it != end; ++it)
- resolved.insert(it.key(), it.value());
-
- // This unrefs all the objects. We have to make sure we do this in the GUI thread. Also, it's
- // a good idea to release the memory before creating the packets to be sent.
- m_locations.clear();
+ for (auto it = m_locations.begin(), end = m_locations.end(); it != end; ++it) {
+ if (!trackLocations || !it->sent) {
+ resolved.insert(it.key(), it.value());
+ if (trackLocations)
+ it->sent = true;
+ }
+ }
QVector<QQmlProfilerData> data;
data.swap(m_data);
diff --git a/src/qml/debugger/qqmlprofiler_p.h b/src/qml/debugger/qqmlprofiler_p.h
index 1380599fb7..6643695d11 100644
--- a/src/qml/debugger/qqmlprofiler_p.h
+++ b/src/qml/debugger/qqmlprofiler_p.h
@@ -55,7 +55,6 @@
#include <private/qqmlboundsignal_p.h>
#include <private/qfinitestack_p.h>
#include <private/qqmlbinding_p.h>
-#include <private/qqmlcompiler_p.h>
#include "qqmlprofilerdefinitions_p.h"
#include "qqmlabstractprofileradapter_p.h"
@@ -64,6 +63,54 @@
QT_BEGIN_NAMESPACE
+#ifdef QT_NO_QML_DEBUGGER
+
+#define Q_QML_PROFILE_IF_ENABLED(feature, profiler, Code)
+#define Q_QML_PROFILE(feature, profiler, Method)
+#define Q_QML_OC_PROFILE(member, Code)
+
+struct QQmlProfiler {};
+
+struct QQmlBindingProfiler
+{
+ QQmlBindingProfiler(quintptr, QQmlBinding *, QV4::FunctionObject *) {}
+};
+
+struct QQmlHandlingSignalProfiler
+{
+ QQmlHandlingSignalProfiler(quintptr, QQmlBoundSignalExpression *) {}
+};
+
+struct QQmlCompilingProfiler
+{
+ QQmlCompilingProfiler(quintptr, QQmlDataBlob *) {}
+};
+
+struct QQmlVmeProfiler {
+ QQmlVmeProfiler() {}
+
+ void init(quintptr, int) {}
+
+ const QV4::CompiledData::Object *pop() { return nullptr; }
+ void push(const QV4::CompiledData::Object *) {}
+
+ static const quintptr profiler = 0;
+};
+
+struct QQmlObjectCreationProfiler
+{
+ QQmlObjectCreationProfiler(quintptr, const QV4::CompiledData::Object *) {}
+ void update(QV4::CompiledData::CompilationUnit *, const QV4::CompiledData::Object *,
+ const QString &, const QUrl &) {}
+};
+
+struct QQmlObjectCompletionProfiler
+{
+ QQmlObjectCompletionProfiler(QQmlVmeProfiler *) {}
+};
+
+#else
+
#define Q_QML_PROFILE_IF_ENABLED(feature, profiler, Code)\
if (profiler && (profiler->featuresEnabled & (1 << feature))) {\
Code;\
@@ -73,6 +120,9 @@ QT_BEGIN_NAMESPACE
#define Q_QML_PROFILE(feature, profiler, Method)\
Q_QML_PROFILE_IF_ENABLED(feature, profiler, profiler->Method)
+#define Q_QML_OC_PROFILE(member, Code)\
+ Q_QML_PROFILE_IF_ENABLED(QQmlProfilerDefinitions::ProfileCreating, member.profiler, Code)
+
// This struct is somewhat dangerous to use:
// The messageType is a bit field. You can pack multiple messages into
// one object, e.g. RangeStart and RangeLocation. Each one will be read
@@ -95,7 +145,7 @@ struct Q_AUTOTEST_EXPORT QQmlProfilerData : public QQmlProfilerDefinitions
Q_DECLARE_TYPEINFO(QQmlProfilerData, Q_MOVABLE_TYPE);
-class QQmlProfiler : public QObject, public QQmlProfilerDefinitions {
+class Q_QML_PRIVATE_EXPORT QQmlProfiler : public QObject, public QQmlProfilerDefinitions {
Q_OBJECT
public:
@@ -146,26 +196,27 @@ public:
// Unfortunately we have to resolve the locations right away because the QML context might not
// be available anymore when we send the data.
struct RefLocation : public Location {
- RefLocation() : Location(), locationType(MaximumRangeType), ref(nullptr)
+ RefLocation() : Location(), locationType(MaximumRangeType), ref(nullptr), sent(false)
{}
RefLocation(QQmlBinding *binding, QV4::FunctionObject *function) :
Location(function->sourceLocation()), locationType(Binding),
- ref(new BindingRefCount(binding), QQmlRefPointer<QQmlRefCount>::Adopt)
+ ref(new BindingRefCount(binding), QQmlRefPointer<QQmlRefCount>::Adopt), sent(false)
{}
- RefLocation(QQmlCompiledData *ref, const QUrl &url, const QV4::CompiledData::Object *obj,
+ RefLocation(QV4::CompiledData::CompilationUnit *ref, const QUrl &url, const QV4::CompiledData::Object *obj,
const QString &type) :
Location(QQmlSourceLocation(type, obj->location.line, obj->location.column), url),
- locationType(Creating), ref(ref)
+ locationType(Creating), ref(ref), sent(false)
{}
RefLocation(QQmlBoundSignalExpression *ref) :
- Location(ref->sourceLocation()), locationType(HandlingSignal), ref(ref)
+ Location(ref->sourceLocation()), locationType(HandlingSignal), ref(ref), sent(false)
{}
RefLocation(QQmlDataBlob *ref) :
- Location(QQmlSourceLocation(), ref->url()), locationType(Compiling), ref(ref)
+ Location(QQmlSourceLocation(), ref->url()), locationType(Compiling), ref(ref),
+ sent(false)
{}
bool isValid() const
@@ -175,6 +226,7 @@ public:
RangeType locationType;
QQmlRefPointer<QQmlRefCount> ref;
+ bool sent;
};
typedef QHash<quintptr, Location> LocationHash;
@@ -217,11 +269,6 @@ public:
location = RefLocation(expression);
}
- void startCreating()
- {
- m_data.append(QQmlProfilerData(m_timer.nsecsElapsed(), 1 << RangeStart, Creating));
- }
-
void startCreating(const QV4::CompiledData::Object *obj)
{
m_data.append(QQmlProfilerData(m_timer.nsecsElapsed(),
@@ -229,14 +276,10 @@ public:
Creating, id(obj)));
}
- void updateCreating(const QV4::CompiledData::Object *obj, QQmlCompiledData *ref,
+ void updateCreating(const QV4::CompiledData::Object *obj, QV4::CompiledData::CompilationUnit *ref,
const QUrl &url, const QString &type)
{
quintptr locationId(id(obj));
- m_data.append(QQmlProfilerData(m_timer.nsecsElapsed(),
- (1 << RangeLocation | 1 << RangeData),
- Creating, locationId));
-
RefLocation &location = m_locations[locationId];
if (!location.isValid())
location = RefLocation(ref, url, obj, type);
@@ -258,10 +301,9 @@ public:
return reinterpret_cast<quintptr>(pointer);
}
-public slots:
void startProfiling(quint64 features);
void stopProfiling();
- void reportData();
+ void reportData(bool trackLocations);
void setTimer(const QElapsedTimer &timer) { m_timer = timer; }
signals:
@@ -357,15 +399,13 @@ private:
QFiniteStack<const QV4::CompiledData::Object *> ranges;
};
-#define Q_QML_OC_PROFILE(member, Code)\
- Q_QML_PROFILE_IF_ENABLED(QQmlProfilerDefinitions::ProfileCreating, member.profiler, Code)
-
class QQmlObjectCreationProfiler {
public:
- QQmlObjectCreationProfiler(QQmlProfiler *profiler) : profiler(profiler)
+ QQmlObjectCreationProfiler(QQmlProfiler *profiler, const QV4::CompiledData::Object *obj)
+ : profiler(profiler)
{
- Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCreating, profiler, startCreating());
+ Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCreating, profiler, startCreating(obj));
}
~QQmlObjectCreationProfiler()
@@ -373,7 +413,7 @@ public:
Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCreating, profiler, endRange<QQmlProfilerDefinitions::Creating>());
}
- void update(QQmlCompiledData *ref, const QV4::CompiledData::Object *obj,
+ void update(QV4::CompiledData::CompilationUnit *ref, const QV4::CompiledData::Object *obj,
const QString &typeName, const QUrl &url)
{
profiler->updateCreating(obj, ref, url, typeName);
@@ -406,4 +446,6 @@ QT_END_NAMESPACE
Q_DECLARE_METATYPE(QVector<QQmlProfilerData>)
Q_DECLARE_METATYPE(QQmlProfiler::LocationHash)
+#endif // QT_NO_QML_DEBUGGER
+
#endif // QQMLPROFILER_P_H
diff --git a/src/qml/debugger/qqmlprofilerdefinitions_p.h b/src/qml/debugger/qqmlprofilerdefinitions_p.h
index 2b2eda22e1..c6ae4593a9 100644
--- a/src/qml/debugger/qqmlprofilerdefinitions_p.h
+++ b/src/qml/debugger/qqmlprofilerdefinitions_p.h
@@ -56,6 +56,8 @@
QT_BEGIN_NAMESPACE
+#ifndef QT_NO_QML_DEBUGGER
+
struct QQmlProfilerDefinitions {
enum Message {
Event,
@@ -161,6 +163,8 @@ struct QQmlProfilerDefinitions {
};
};
+#endif // QT_NO_QML_DEBUGGER
+
QT_END_NAMESPACE
#endif