Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qv4profileradapter.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
6
8
10 m_functionCallPos(0), m_memoryPos(0)
11{
13 engine->setProfiler(new QV4::Profiling::Profiler(engine));
15 this, &QV4ProfilerAdapter::forwardEnabled);
17 this, &QV4ProfilerAdapter::forwardEnabledWhileWaiting, Qt::DirectConnection);
19 engine->profiler(), &QV4::Profiling::Profiler::startProfiling);
21 engine->profiler(), &QV4::Profiling::Profiler::startProfiling, Qt::DirectConnection);
23 engine->profiler(), &QV4::Profiling::Profiler::stopProfiling);
25 engine->profiler(), &QV4::Profiling::Profiler::stopProfiling,
28 engine->profiler(), &QV4::Profiling::Profiler::reportData);
30 engine->profiler(), &QV4::Profiling::Profiler::setTimer);
31 connect(engine->profiler(), &QV4::Profiling::Profiler::dataReady,
33}
34
35qint64 QV4ProfilerAdapter::appendMemoryEvents(qint64 until, QList<QByteArray> &messages,
37{
38 // Make it const, so that we cannot accidentally detach it.
39 const QVector<QV4::Profiling::MemoryAllocationProperties> &memoryData = m_memoryData;
40
41 while (memoryData.size() > m_memoryPos && memoryData[m_memoryPos].timestamp <= until) {
42 const QV4::Profiling::MemoryAllocationProperties &props = memoryData[m_memoryPos];
43 d << props.timestamp << int(MemoryAllocation) << int(props.type) << props.size;
44 ++m_memoryPos;
45 messages.append(d.squeezedData());
46 d.clear();
47 }
48 return memoryData.size() == m_memoryPos ? -1 : memoryData[m_memoryPos].timestamp;
49}
50
51qint64 QV4ProfilerAdapter::finalizeMessages(qint64 until, QList<QByteArray> &messages,
52 qint64 callNext, QQmlDebugPacket &d)
53{
54 qint64 memoryNext = -1;
55
56 if (callNext == -1) {
57 m_functionLocations.clear();
58 m_functionCallData.clear();
59 m_functionCallPos = 0;
60 memoryNext = appendMemoryEvents(until, messages, d);
61 } else {
62 memoryNext = appendMemoryEvents(qMin(callNext, until), messages, d);
63 }
64
65 if (memoryNext == -1) {
66 m_memoryData.clear();
67 m_memoryPos = 0;
68 return callNext;
69 }
70
71 return callNext == -1 ? memoryNext : qMin(callNext, memoryNext);
72}
73
74qint64 QV4ProfilerAdapter::sendMessages(qint64 until, QList<QByteArray> &messages)
75{
77
78 // Make it const, so that we cannot accidentally detach it.
79 const QVector<QV4::Profiling::FunctionCallProperties> &functionCallData = m_functionCallData;
80
81 while (true) {
82 while (!m_stack.isEmpty() &&
83 (m_functionCallPos == functionCallData.size() ||
84 m_stack.top() <= functionCallData[m_functionCallPos].start)) {
85 if (m_stack.top() > until || messages.size() > s_numMessagesPerBatch)
86 return finalizeMessages(until, messages, m_stack.top(), d);
87
88 appendMemoryEvents(m_stack.top(), messages, d);
89 d << m_stack.pop() << int(RangeEnd) << int(Javascript);
90 messages.append(d.squeezedData());
91 d.clear();
92 }
93 while (m_functionCallPos != functionCallData.size() &&
94 (m_stack.empty() || functionCallData[m_functionCallPos].start < m_stack.top())) {
95 const QV4::Profiling::FunctionCallProperties &props =
96 functionCallData[m_functionCallPos];
97 if (props.start > until || messages.size() > s_numMessagesPerBatch)
98 return finalizeMessages(until, messages, props.start, d);
99
100 appendMemoryEvents(props.start, messages, d);
101 auto location = m_functionLocations.constFind(props.id);
102
103 d << props.start << int(RangeStart) << int(Javascript) << static_cast<qint64>(props.id);
104 if (location != m_functionLocations.cend()) {
105 messages.push_back(d.squeezedData());
106 d.clear();
107 d << props.start << int(RangeLocation) << int(Javascript) << location->file << location->line
108 << location->column << static_cast<qint64>(props.id);
109 messages.push_back(d.squeezedData());
110 d.clear();
111 d << props.start << int(RangeData) << int(Javascript) << location->name
112 << static_cast<qint64>(props.id);
113 m_functionLocations.erase(location);
114 }
115 messages.push_back(d.squeezedData());
116 d.clear();
117 m_stack.push(props.end);
118 ++m_functionCallPos;
119 }
120 if (m_stack.empty() && m_functionCallPos == functionCallData.size())
121 return finalizeMessages(until, messages, -1, d);
122 }
123}
124
126 const QV4::Profiling::FunctionLocationHash &locations,
127 const QVector<QV4::Profiling::FunctionCallProperties> &functionCallData,
128 const QVector<QV4::Profiling::MemoryAllocationProperties> &memoryData)
129{
130 // In rare cases it could be that another flush or stop event is processed while data from
131 // the previous one is still pending. In that case we just append the data.
132 if (m_functionLocations.isEmpty())
133 m_functionLocations = locations;
134 else
135 m_functionLocations.insert(locations);
136
137 if (m_functionCallData.isEmpty())
138 m_functionCallData = functionCallData;
139 else
140 m_functionCallData.append(functionCallData);
141
142 if (m_memoryData.isEmpty())
143 m_memoryData = memoryData;
144 else
145 m_memoryData.append(memoryData);
146
147 service->dataReady(this);
148}
149
150quint64 QV4ProfilerAdapter::translateFeatures(quint64 qmlFeatures)
151{
152 quint64 v4Features = 0;
153 const quint64 one = 1;
154 if (qmlFeatures & (one << ProfileJavaScript))
155 v4Features |= (one << QV4::Profiling::FeatureFunctionCall);
156 if (qmlFeatures & (one << ProfileMemory))
157 v4Features |= (one << QV4::Profiling::FeatureMemoryAllocation);
158 return v4Features;
159}
160
161void QV4ProfilerAdapter::forwardEnabled(quint64 features)
162{
163 emit v4ProfilingEnabled(translateFeatures(features));
164}
165
166void QV4ProfilerAdapter::forwardEnabledWhileWaiting(quint64 features)
167{
168 emit v4ProfilingEnabledWhileWaiting(translateFeatures(features));
169}
170
172
173#include "moc_qv4profileradapter.cpp"
bool isEmpty() const noexcept
Definition qlist.h:401
bool empty() const noexcept
Definition qlist.h:685
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
void setService(QQmlProfilerService *new_service)
void profilingEnabled(quint64 features)
void profilingEnabledWhileWaiting(quint64 features)
void referenceTimeKnown(const QElapsedTimer &timer)
T & top()
Returns a reference to the stack's top item.
Definition qstack.h:19
T pop()
Removes the top item from the stack and returns it.
Definition qstack.h:18
void push(const T &t)
Adds element t to the top of the stack.
Definition qstack.h:17
void v4ProfilingEnabled(quint64 v4Features)
void v4ProfilingEnabledWhileWaiting(quint64 v4Features)
QV4ProfilerAdapter(QQmlProfilerService *service, QV4::ExecutionEngine *engine)
void receiveData(const QV4::Profiling::FunctionLocationHash &, const QVector< QV4::Profiling::FunctionCallProperties > &, const QVector< QV4::Profiling::MemoryAllocationProperties > &)
virtual qint64 sendMessages(qint64 until, QList< QByteArray > &messages) override
Combined button and popup list for selecting options.
@ DirectConnection
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
GLint location
GLenum GLuint GLsizei const GLenum * props
GLuint const GLint * locations
#define emit
unsigned long long quint64
Definition qtypes.h:61
long long qint64
Definition qtypes.h:60
QJSEngine engine
[0]