aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/debugger/qv4profileradapter.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@digia.com>2014-06-02 18:33:19 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-06-06 18:18:35 +0200
commitac56e7cda724aa7463ef6ffe5f0e93bd3208cb51 (patch)
treec96c9a5e611937b658f13ab21e9d71787c12b512 /src/qml/debugger/qv4profileradapter.cpp
parent4a127e3b2e98c1d690d9baf346e4d3ee8aa4edf1 (diff)
Javascript heap profiler
This profiler tracks every memory allocation and deallocation, by the MemoryManager as well as the V4 VM, and exposes them as a stream of events to the profiler service. Change-Id: I85297d498f0a7eb55df5d7829c4b7307de980519 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml/debugger/qv4profileradapter.cpp')
-rw-r--r--src/qml/debugger/qv4profileradapter.cpp39
1 files changed, 31 insertions, 8 deletions
diff --git a/src/qml/debugger/qv4profileradapter.cpp b/src/qml/debugger/qv4profileradapter.cpp
index e7b82566d6..cdceb0e533 100644
--- a/src/qml/debugger/qv4profileradapter.cpp
+++ b/src/qml/debugger/qv4profileradapter.cpp
@@ -58,26 +58,47 @@ 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(QList<QV4::Profiling::FunctionCallProperties>)),
- this, SLOT(receiveData(QList<QV4::Profiling::FunctionCallProperties>)));
+ connect(engine->profiler, SIGNAL(dataReady(QList<QV4::Profiling::FunctionCallProperties>,
+ QList<QV4::Profiling::MemoryAllocationProperties>)),
+ this, SLOT(receiveData(QList<QV4::Profiling::FunctionCallProperties>,
+ QList<QV4::Profiling::MemoryAllocationProperties>)));
}
+qint64 QV4ProfilerAdapter::appendMemoryEvents(qint64 until, QList<QByteArray> &messages)
+{
+ QByteArray message;
+ while (!memory_data.empty() && memory_data.front().timestamp <= until) {
+ QQmlDebugStream d(&message, QIODevice::WriteOnly);
+ QV4::Profiling::MemoryAllocationProperties &props = memory_data.front();
+ d << props.timestamp << MemoryAllocation << props.type << props.size;
+ memory_data.pop_front();
+ messages.append(message);
+ }
+ return memory_data.empty() ? -1 : memory_data.front().timestamp;
+}
qint64 QV4ProfilerAdapter::sendMessages(qint64 until, QList<QByteArray> &messages)
{
QByteArray message;
while (true) {
while (!stack.empty() && (data.empty() || stack.top() <= data.front().start)) {
- if (stack.top() > until)
- return stack.top();
+ if (stack.top() > until) {
+ qint64 memory_next = appendMemoryEvents(until, messages);
+ return memory_next == -1 ? stack.top() : qMin(stack.top(), memory_next);
+ }
+ appendMemoryEvents(stack.top(), messages);
QQmlDebugStream d(&message, QIODevice::WriteOnly);
d << stack.pop() << RangeEnd << Javascript;
messages.append(message);
}
while (!data.empty() && (stack.empty() || data.front().start < stack.top())) {
- if (data.front().start > until)
- return data.front().start;
const QV4::Profiling::FunctionCallProperties &props = data.front();
+ if (props.start > until) {
+ qint64 memory_next = appendMemoryEvents(until, messages);
+ return memory_next == -1 ? props.start : qMin(props.start, memory_next);
+ }
+ appendMemoryEvents(props.start, messages);
+
QQmlDebugStream d_start(&message, QIODevice::WriteOnly);
d_start << props.start << RangeStart << Javascript;
messages.push_back(message);
@@ -95,13 +116,15 @@ qint64 QV4ProfilerAdapter::sendMessages(qint64 until, QList<QByteArray> &message
data.pop_front();
}
if (stack.empty() && data.empty())
- return -1;
+ return appendMemoryEvents(until, messages);
}
}
-void QV4ProfilerAdapter::receiveData(const QList<QV4::Profiling::FunctionCallProperties> &new_data)
+void QV4ProfilerAdapter::receiveData(const QList<QV4::Profiling::FunctionCallProperties> &new_data,
+ const QList<QV4::Profiling::MemoryAllocationProperties> &new_memory_data)
{
data = new_data;
+ memory_data = new_memory_data;
stack.clear();
service->dataReady(this);
}