5#ifndef QQMLPROFILER_P_H
6#define QQMLPROFILER_P_H
19#include <private/qqmlbinding_p.h>
20#include <private/qqmlboundsignal_p.h>
21#include <private/qqmlglobal_p.h>
22#include <private/qv4function_p.h>
24#if QT_CONFIG(qml_debug)
25#include "qqmlprofilerdefinitions_p.h"
28#include <QtCore/qurl.h>
29#include <QtCore/qstring.h>
33#if !QT_CONFIG(qml_debug)
35#define Q_QML_PROFILE_IF_ENABLED(feature, profiler, Code)
36#define Q_QML_PROFILE(feature, profiler, Method)
37#define Q_QML_OC_PROFILE(member, Code)
81#define Q_QML_PROFILE_IF_ENABLED(feature, profiler, Code)
82 if (profiler && (profiler->featuresEnabled & (1
<< feature))) {
87#define Q_QML_PROFILE(feature, profiler, Method)
90#define Q_QML_OC_PROFILE(member, Code)
101 QQmlProfilerData(qint64 time = -1,
int messageType = -1,
102 RangeType detailType = MaximumRangeType, quintptr locationId = 0) :
103 time(time), locationId(locationId), messageType(messageType), detailType(detailType)
110 RangeType detailType;
115class Q_QML_EXPORT QQmlProfiler :
public QObject,
public QQmlProfilerDefinitions {
120 Location(
const QQmlSourceLocation &location = QQmlSourceLocation(),
121 const QUrl &url = QUrl()) :
122 location(location), url(url) {}
123 QQmlSourceLocation location;
129 struct RefLocation :
public Location {
131 : Location(), locationType(MaximumRangeType), something(
nullptr), sent(
false)
135 RefLocation(QV4::Function *ref)
136 : Location(ref->sourceLocation()), locationType(Binding), sent(
false)
139 function->executableCompilationUnit()->addref();
142 RefLocation(QV4::ExecutableCompilationUnit *ref,
const QUrl &url,
143 const QV4::CompiledData::Object *obj,
const QString &type)
144 : Location(QQmlSourceLocation(type, obj->location.line(), obj->location.column()), url),
145 locationType(Creating), sent(
false)
151 RefLocation(QQmlBoundSignalExpression *ref)
152 : Location(ref->sourceLocation()), locationType(HandlingSignal), sent(
false)
155 boundSignal->addref();
158 RefLocation(QQmlDataBlob *ref)
159 : Location(QQmlSourceLocation(), ref->url()), locationType(Compiling), sent(
false)
165 RefLocation(
const RefLocation &other)
167 locationType(other.locationType),
168 function(other.function),
174 RefLocation &operator=(
const RefLocation &other)
176 if (
this != &other) {
178 Location::operator=(other);
179 locationType = other.locationType;
180 function = other.function;
197 switch (locationType) {
199 function->executableCompilationUnit()->addref();
205 boundSignal->addref();
211 Q_ASSERT(locationType == MaximumRangeType);
221 switch (locationType) {
223 function->executableCompilationUnit()->release();
229 boundSignal->release();
235 Q_ASSERT(locationType == MaximumRangeType);
242 return locationType != MaximumRangeType;
250 RangeType locationType;
252 QV4::Function *function;
253 QV4::ExecutableCompilationUnit *unit;
254 QQmlBoundSignalExpression *boundSignal;
261 typedef QHash<quintptr, Location> LocationHash;
263 void startBinding(QV4::Function *function)
272 quintptr locationId = function ? id(function) + 1 : id(
this);
273 m_data.append(QQmlProfilerData(m_timer.nsecsElapsed(),
274 (1 << RangeStart | 1 << RangeLocation), Binding,
277 RefLocation &location = m_locations[locationId];
278 if (!location.isValid()) {
280 location = RefLocation(function);
282 location.locationType = Binding;
288 void startCompiling(QQmlDataBlob *blob)
290 quintptr locationId(id(blob));
291 m_data.append(QQmlProfilerData(m_timer.nsecsElapsed(),
292 (1 << RangeStart | 1 << RangeLocation | 1 << RangeData),
293 Compiling, locationId));
295 RefLocation &location = m_locations[locationId];
296 if (!location.isValid())
297 location = RefLocation(blob);
300 void startHandlingSignal(QQmlBoundSignalExpression *expression)
307 quintptr locationId(id(expression->function()) + 2);
308 m_data.append(QQmlProfilerData(m_timer.nsecsElapsed(),
309 (1 << RangeStart | 1 << RangeLocation), HandlingSignal,
312 RefLocation &location = m_locations[locationId];
313 if (!location.isValid())
314 location = RefLocation(expression);
317 void startCreating(
const QV4::CompiledData::Object *obj)
319 m_data.append(QQmlProfilerData(m_timer.nsecsElapsed(),
320 (1 << RangeStart | 1 << RangeLocation | 1 << RangeData),
324 void updateCreating(
const QV4::CompiledData::Object *obj,
325 QV4::ExecutableCompilationUnit *ref,
326 const QUrl &url,
const QString &type)
328 quintptr locationId(id(obj));
329 RefLocation &location = m_locations[locationId];
330 if (!location.isValid())
331 location = RefLocation(ref, url, obj, type);
334 template<RangeType Range>
337 m_data.append(QQmlProfilerData(m_timer.nsecsElapsed(), 1 << RangeEnd, Range));
342 quint64 featuresEnabled;
344 template<
typename Object>
345 static quintptr id(
const Object *pointer)
347 return reinterpret_cast<quintptr>(pointer);
350 void startProfiling(quint64 features);
351 void stopProfiling();
353 void setTimer(
const QElapsedTimer &timer) { m_timer = timer; }
356 void dataReady(
const QList<QQmlProfilerData> &,
const QQmlProfiler::LocationHash &);
359 QElapsedTimer m_timer;
360 QHash<quintptr, RefLocation> m_locations;
361 QList<QQmlProfilerData> m_data;
368struct QQmlProfilerHelper :
public QQmlProfilerDefinitions {
369 QQmlProfiler *profiler;
370 QQmlProfilerHelper(QQmlProfiler *profiler) : profiler(profiler) {}
373struct QQmlBindingProfiler :
public QQmlProfilerHelper {
374 QQmlBindingProfiler(QQmlProfiler *profiler, QV4::Function *function) :
375 QQmlProfilerHelper(profiler)
377 Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileBinding, profiler,
378 startBinding(function));
381 ~QQmlBindingProfiler()
383 Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileBinding, profiler,
384 endRange<Binding>());
388struct QQmlHandlingSignalProfiler :
public QQmlProfilerHelper {
389 QQmlHandlingSignalProfiler(QQmlProfiler *profiler, QQmlBoundSignalExpression *expression) :
390 QQmlProfilerHelper(profiler)
392 Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileHandlingSignal, profiler,
393 startHandlingSignal(expression));
396 ~QQmlHandlingSignalProfiler()
398 Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileHandlingSignal, profiler,
399 endRange<QQmlProfiler::HandlingSignal>());
403struct QQmlCompilingProfiler :
public QQmlProfilerHelper {
404 QQmlCompilingProfiler(QQmlProfiler *profiler, QQmlDataBlob *blob) :
405 QQmlProfilerHelper(profiler)
407 Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCompiling, profiler, startCompiling(blob));
410 ~QQmlCompilingProfiler()
412 Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCompiling, profiler, endRange<Compiling>());
416struct QQmlVmeProfiler :
public QQmlProfilerDefinitions {
419 QQmlVmeProfiler() : profiler(
nullptr) {}
421 void init(QQmlProfiler *p)
426 const QV4::CompiledData::Object *pop()
428 if (ranges.size() > 0) {
429 const auto *result = ranges.back();
436 void push(
const QV4::CompiledData::Object *object)
438 ranges.push_back(object);
441 QQmlProfiler *profiler;
444 std::vector<
const QV4::CompiledData::Object *> ranges;
447class QQmlObjectCreationProfiler {
450 QQmlObjectCreationProfiler(QQmlProfiler *profiler,
const QV4::CompiledData::Object *obj)
453 Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCreating, profiler, startCreating(obj));
456 ~QQmlObjectCreationProfiler()
458 Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCreating, profiler, endRange<QQmlProfilerDefinitions::Creating>());
461 void update(QV4::ExecutableCompilationUnit *ref,
const QV4::CompiledData::Object *obj,
462 const QString &typeName,
const QUrl &url)
464 profiler->updateCreating(obj, ref, url, typeName);
468 QQmlProfiler *profiler;
471class QQmlObjectCompletionProfiler {
473 QQmlObjectCompletionProfiler(QQmlVmeProfiler *parent) :
474 profiler(parent->profiler)
477 profiler->startCreating(parent->pop());
481 ~QQmlObjectCompletionProfiler()
483 Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCreating, profiler,
484 endRange<QQmlProfilerDefinitions::Creating>());
487 QQmlProfiler *profiler;
494#if QT_CONFIG(qml_debug)
496Q_DECLARE_METATYPE(QList<QQmlProfilerData>)
497Q_DECLARE_METATYPE(QQmlProfiler::LocationHash)
Combined button and popup list for selecting options.
Q_DECLARE_TYPEINFO(QByteArrayView, Q_PRIMITIVE_TYPE)
#define Q_QML_PROFILE(feature, profiler, Method)
#define Q_QML_PROFILE_IF_ENABLED(feature, profiler, Code)