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/qqmlprofileradapter.cpp95
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.h4
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp25
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.h5
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp79
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.h16
6 files changed, 126 insertions, 98 deletions
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp
index a193ddea0b..90e817e2fc 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp
@@ -48,69 +48,86 @@ QQmlProfilerAdapter::QQmlProfilerAdapter(QQmlProfilerService *service, QQmlEngin
next(0)
{
setService(service);
- engine->enableProfiler();
- connect(this, SIGNAL(profilingEnabled(quint64)), engine->profiler, SLOT(startProfiling(quint64)));
- connect(this, SIGNAL(profilingEnabledWhileWaiting(quint64)),
- engine->profiler, SLOT(startProfiling(quint64)), Qt::DirectConnection);
- connect(this, SIGNAL(profilingDisabled()), engine->profiler, SLOT(stopProfiling()));
- connect(this, SIGNAL(profilingDisabledWhileWaiting()),
- engine->profiler, SLOT(stopProfiling()), Qt::DirectConnection);
- 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>,QQmlProfiler::LocationHash)),
- this,
- SLOT(receiveData(QVector<QQmlProfilerData>,QQmlProfiler::LocationHash)));
+ engine->profiler = new QQmlProfiler;
+ connect(this, &QQmlProfilerAdapter::profilingEnabled,
+ engine->profiler, &QQmlProfiler::startProfiling);
+ connect(this, &QQmlAbstractProfilerAdapter::profilingEnabledWhileWaiting,
+ engine->profiler, &QQmlProfiler::startProfiling, Qt::DirectConnection);
+ connect(this, &QQmlAbstractProfilerAdapter::profilingDisabled,
+ engine->profiler, &QQmlProfiler::stopProfiling);
+ connect(this, &QQmlAbstractProfilerAdapter::profilingDisabledWhileWaiting,
+ engine->profiler, &QQmlProfiler::stopProfiling, Qt::DirectConnection);
+ connect(this, &QQmlAbstractProfilerAdapter::dataRequested,
+ engine->profiler, &QQmlProfiler::reportData);
+ connect(this, &QQmlAbstractProfilerAdapter::referenceTimeKnown,
+ engine->profiler, &QQmlProfiler::setTimer);
+ connect(engine->profiler, &QQmlProfiler::dataReady,
+ this, &QQmlProfilerAdapter::receiveData);
}
// 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,
- const QQmlProfiler::LocationHash &locations,
- QList<QByteArray> &messages)
+ QQmlProfiler::LocationHash &locations,
+ QList<QByteArray> &messages,
+ bool trackLocations)
{
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)
- continue;
-
- //### using QDataStream is relatively expensive
- ds << d.time << decodedMessageType << static_cast<quint32>(d.detailType);
-
- QQmlProfiler::Location l = locations.value(d.locationId);
+ if (decodedMessageType == QQmlProfilerDefinitions::RangeData
+ || (d.messageType & (1 << decodedMessageType)) == 0) {
+ continue; // RangeData is sent together with RangeLocation
+ }
- 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;
+ if (decodedMessageType == QQmlProfilerDefinitions::RangeEnd
+ || decodedMessageType == QQmlProfilerDefinitions::RangeStart) {
+ ds << d.time << decodedMessageType << static_cast<quint32>(d.detailType);
+ if (trackLocations && d.locationId != 0)
+ ds << static_cast<qint64>(d.locationId);
+ } else {
+ auto i = locations.find(d.locationId);
+ if (i != locations.end()) {
+ ds << d.time << decodedMessageType << static_cast<quint32>(d.detailType);
+ ds << (i->url.isEmpty() ? i->location.sourceFile : i->url.toString())
+ << static_cast<qint32>(i->location.line)
+ << static_cast<qint32>(i->location.column);
+ if (d.messageType & (1 << QQmlProfilerDefinitions::RangeData)) {
+ // Send both, location and data ...
+ if (trackLocations)
+ ds << static_cast<qint64>(d.locationId);
+ messages.append(ds.squeezedData());
+ ds.clear();
+ ds << d.time << int(QQmlProfilerDefinitions::RangeData)
+ << static_cast<quint32>(d.detailType)
+ << (i->location.sourceFile.isEmpty() ? i->url.toString() :
+ i->location.sourceFile);
+ }
+ if (trackLocations) {
+ ds << static_cast<qint64>(d.locationId);
+ locations.erase(i); // ... so that we can erase here without missing anything.
+ }
+ } else {
+ // Skip RangeData and RangeLocation: We've already sent them
+ continue;
+ }
}
messages.append(ds.squeezedData());
ds.clear();
}
}
-qint64 QQmlProfilerAdapter::sendMessages(qint64 until, QList<QByteArray> &messages)
+qint64 QQmlProfilerAdapter::sendMessages(qint64 until, QList<QByteArray> &messages,
+ bool trackLocations)
{
while (next != data.length()) {
const QQmlProfilerData &nextData = data.at(next);
if (nextData.time > until || messages.length() > s_numMessagesPerBatch)
return nextData.time;
- qQmlProfilerDataToByteArrays(nextData, locations, messages);
+ qQmlProfilerDataToByteArrays(nextData, locations, messages, trackLocations);
++next;
}
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.h b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.h
index 7e13b6c479..1fee5c389f 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.h
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.h
@@ -60,9 +60,9 @@ class QQmlProfilerAdapter : public QQmlAbstractProfilerAdapter {
Q_OBJECT
public:
QQmlProfilerAdapter(QQmlProfilerService *service, QQmlEnginePrivate *engine);
- qint64 sendMessages(qint64 until, QList<QByteArray> &messages) Q_DECL_OVERRIDE;
+ qint64 sendMessages(qint64 until, QList<QByteArray> &messages,
+ bool trackLocations) Q_DECL_OVERRIDE;
-public slots:
void receiveData(const QVector<QQmlProfilerData> &new_data,
const QQmlProfiler::LocationHash &locations);
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp
index e17722bb3d..dba2fd3cc3 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp
@@ -57,7 +57,7 @@ Q_QML_DEBUG_PLUGIN_LOADER(QQmlAbstractProfilerAdapter)
QQmlProfilerServiceImpl::QQmlProfilerServiceImpl(QObject *parent) :
QQmlConfigurableDebugService<QQmlProfilerService>(1, parent),
- m_waitingForStop(false)
+ m_waitingForStop(false), m_useMessageTypes(false)
{
m_timer.start();
QQmlAbstractProfilerAdapter *quickAdapter =
@@ -309,7 +309,7 @@ void QQmlProfilerServiceImpl::stopProfiling(QJSEngine *engine)
m_waitingForStop = true;
foreach (QQmlAbstractProfilerAdapter *profiler, reporting)
- profiler->reportData();
+ profiler->reportData(m_useMessageTypes);
foreach (QQmlAbstractProfilerAdapter *profiler, stopping)
profiler->stopProfiling();
@@ -343,7 +343,8 @@ void QQmlProfilerServiceImpl::sendMessages()
m_startTimes.erase(m_startTimes.begin());
qint64 next = first->sendMessages(m_startTimes.isEmpty() ?
std::numeric_limits<qint64>::max() :
- m_startTimes.begin().key(), messages);
+ m_startTimes.begin().key(), messages,
+ m_useMessageTypes);
if (next != -1)
m_startTimes.insert(next, first);
@@ -408,16 +409,20 @@ void QQmlProfilerServiceImpl::messageReceived(const QByteArray &message)
if (!stream.atEnd()) {
stream >> flushInterval;
m_flushTimer.setInterval(flushInterval);
+ auto timerStart = static_cast<void(QTimer::*)()>(&QTimer::start);
if (flushInterval > 0) {
- connect(&m_flushTimer, SIGNAL(timeout()), this, SLOT(flush()));
- connect(this, SIGNAL(startFlushTimer()), &m_flushTimer, SLOT(start()));
- connect(this, SIGNAL(stopFlushTimer()), &m_flushTimer, SLOT(stop()));
+ connect(&m_flushTimer, &QTimer::timeout, this, &QQmlProfilerServiceImpl::flush);
+ connect(this, &QQmlProfilerServiceImpl::startFlushTimer, &m_flushTimer, timerStart);
+ connect(this, &QQmlProfilerServiceImpl::stopFlushTimer, &m_flushTimer, &QTimer::stop);
} else {
- disconnect(&m_flushTimer, SIGNAL(timeout()), this, SLOT(flush()));
- disconnect(this, SIGNAL(startFlushTimer()), &m_flushTimer, SLOT(start()));
- disconnect(this, SIGNAL(stopFlushTimer()), &m_flushTimer, SLOT(stop()));
+ disconnect(&m_flushTimer, &QTimer::timeout, this, &QQmlProfilerServiceImpl::flush);
+ disconnect(this, &QQmlProfilerServiceImpl::startFlushTimer, &m_flushTimer, timerStart);
+ disconnect(this, &QQmlProfilerServiceImpl::stopFlushTimer,
+ &m_flushTimer, &QTimer::stop);
}
}
+ if (!stream.atEnd())
+ stream >> m_useMessageTypes;
// If engineId == -1 objectForId() and then the cast will return 0.
if (enabled)
@@ -448,7 +453,7 @@ void QQmlProfilerServiceImpl::flush()
}
foreach (QQmlAbstractProfilerAdapter *profiler, reporting)
- profiler->reportData();
+ profiler->reportData(m_useMessageTypes);
}
QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.h b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.h
index 6490e77f44..bbfc32b681 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.h
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.h
@@ -99,9 +99,6 @@ signals:
void startFlushTimer();
void stopFlushTimer();
-private slots:
- void flush();
-
protected:
virtual void stateAboutToBeChanged(State state) Q_DECL_OVERRIDE;
virtual void messageReceived(const QByteArray &) Q_DECL_OVERRIDE;
@@ -112,10 +109,12 @@ private:
void sendMessages();
void addEngineProfiler(QQmlAbstractProfilerAdapter *profiler, QJSEngine *engine);
void removeProfilerFromStartTimes(const QQmlAbstractProfilerAdapter *profiler);
+ void flush();
QElapsedTimer m_timer;
QTimer m_flushTimer;
bool m_waitingForStop;
+ bool m_useMessageTypes;
QList<QQmlAbstractProfilerAdapter *> m_globalProfilers;
QMultiHash<QJSEngine *, QQmlAbstractProfilerAdapter *> m_engineProfilers;
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp b/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp
index 68a71a5524..eae5e0a795 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp
+++ b/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp
@@ -46,27 +46,26 @@ QV4ProfilerAdapter::QV4ProfilerAdapter(QQmlProfilerService *service, QV4::Execut
m_functionCallPos(0), m_memoryPos(0)
{
setService(service);
- engine->enableProfiler();
- connect(this, SIGNAL(profilingEnabled(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()),
+ engine->setProfiler(new QV4::Profiling::Profiler(engine));
+ connect(this, &QQmlAbstractProfilerAdapter::profilingEnabled,
+ this, &QV4ProfilerAdapter::forwardEnabled);
+ connect(this, &QQmlAbstractProfilerAdapter::profilingEnabledWhileWaiting,
+ this, &QV4ProfilerAdapter::forwardEnabledWhileWaiting, Qt::DirectConnection);
+ connect(this, &QV4ProfilerAdapter::v4ProfilingEnabled,
+ engine->profiler(), &QV4::Profiling::Profiler::startProfiling);
+ connect(this, &QV4ProfilerAdapter::v4ProfilingEnabledWhileWaiting,
+ engine->profiler(), &QV4::Profiling::Profiler::startProfiling, Qt::DirectConnection);
+ connect(this, &QQmlAbstractProfilerAdapter::profilingDisabled,
+ engine->profiler(), &QV4::Profiling::Profiler::stopProfiling);
+ connect(this, &QQmlAbstractProfilerAdapter::profilingDisabledWhileWaiting,
+ engine->profiler(), &QV4::Profiling::Profiler::stopProfiling,
Qt::DirectConnection);
- connect(this, SIGNAL(dataRequested()), engine->profiler, SLOT(reportData()));
- connect(this, SIGNAL(referenceTimeKnown(QElapsedTimer)),
- engine->profiler, SLOT(setTimer(QElapsedTimer)));
- connect(engine->profiler, SIGNAL(dataReady(QV4::Profiling::FunctionLocationHash,
- QVector<QV4::Profiling::FunctionCallProperties>,
- QVector<QV4::Profiling::MemoryAllocationProperties>)),
- this, SLOT(receiveData(QV4::Profiling::FunctionLocationHash,
- QVector<QV4::Profiling::FunctionCallProperties>,
- QVector<QV4::Profiling::MemoryAllocationProperties>)));
+ connect(this, &QQmlAbstractProfilerAdapter::dataRequested,
+ engine->profiler(), &QV4::Profiling::Profiler::reportData);
+ connect(this, &QQmlAbstractProfilerAdapter::referenceTimeKnown,
+ engine->profiler(), &QV4::Profiling::Profiler::setTimer);
+ connect(engine->profiler(), &QV4::Profiling::Profiler::dataReady,
+ this, &QV4ProfilerAdapter::receiveData);
}
qint64 QV4ProfilerAdapter::appendMemoryEvents(qint64 until, QList<QByteArray> &messages,
@@ -77,7 +76,7 @@ qint64 QV4ProfilerAdapter::appendMemoryEvents(qint64 until, QList<QByteArray> &m
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;
+ d << props.timestamp << int(MemoryAllocation) << int(props.type) << props.size;
++m_memoryPos;
messages.append(d.squeezedData());
d.clear();
@@ -105,13 +104,13 @@ qint64 QV4ProfilerAdapter::finalizeMessages(qint64 until, QList<QByteArray> &mes
return callNext == -1 ? memoryNext : qMin(callNext, memoryNext);
}
-qint64 QV4ProfilerAdapter::sendMessages(qint64 until, QList<QByteArray> &messages)
+qint64 QV4ProfilerAdapter::sendMessages(qint64 until, QList<QByteArray> &messages,
+ bool trackLocations)
{
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 (!m_stack.isEmpty() &&
@@ -121,7 +120,7 @@ qint64 QV4ProfilerAdapter::sendMessages(qint64 until, QList<QByteArray> &message
return finalizeMessages(until, messages, m_stack.top(), d);
appendMemoryEvents(m_stack.top(), messages, d);
- d << m_stack.pop() << RangeEnd << Javascript;
+ d << m_stack.pop() << int(RangeEnd) << int(Javascript);
messages.append(d.squeezedData());
d.clear();
}
@@ -133,17 +132,27 @@ qint64 QV4ProfilerAdapter::sendMessages(qint64 until, QList<QByteArray> &message
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;
+ auto location = m_functionLocations.find(props.id);
+
+ d << props.start << int(RangeStart) << int(Javascript);
+ if (trackLocations)
+ d << static_cast<qint64>(props.id);
+ if (location != m_functionLocations.end()) {
+ messages.push_back(d.squeezedData());
+ d.clear();
+ d << props.start << int(RangeLocation) << int(Javascript) << location->file << location->line
+ << location->column;
+ if (trackLocations)
+ d << static_cast<qint64>(props.id);
+ messages.push_back(d.squeezedData());
+ d.clear();
+ d << props.start << int(RangeData) << int(Javascript) << location->name;
+
+ if (trackLocations) {
+ d << static_cast<qint64>(props.id);
+ m_functionLocations.erase(location);
+ }
+ }
messages.push_back(d.squeezedData());
d.clear();
m_stack.push(props.end);
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.h b/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.h
index 968825c346..5d5b83f7ca 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.h
+++ b/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.h
@@ -67,20 +67,16 @@ class QV4ProfilerAdapter : public QQmlAbstractProfilerAdapter {
public:
QV4ProfilerAdapter(QQmlProfilerService *service, QV4::ExecutionEngine *engine);
- virtual qint64 sendMessages(qint64 until, QList<QByteArray> &messages);
+ virtual qint64 sendMessages(qint64 until, QList<QByteArray> &messages,
+ bool trackLocations) override;
-signals:
- void v4ProfilingEnabled(quint64 v4Features);
- void v4ProfilingEnabledWhileWaiting(quint64 v4Features);
-
-public slots:
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);
+signals:
+ void v4ProfilingEnabled(quint64 v4Features);
+ void v4ProfilingEnabledWhileWaiting(quint64 v4Features);
private:
QV4::Profiling::FunctionLocationHash m_functionLocations;
@@ -92,6 +88,8 @@ private:
qint64 appendMemoryEvents(qint64 until, QList<QByteArray> &messages, QQmlDebugPacket &d);
qint64 finalizeMessages(qint64 until, QList<QByteArray> &messages, qint64 callNext,
QQmlDebugPacket &d);
+ void forwardEnabled(quint64 features);
+ void forwardEnabledWhileWaiting(quint64 features);
static quint64 translateFeatures(quint64 qmlFeatures);
};