4#ifndef QQMLPROFILER_P_H
5#define QQMLPROFILER_P_H
18#include <private/qqmlbinding_p.h>
19#include <private/qqmlboundsignal_p.h>
20#include <private/qqmlglobal_p.h>
21#include <private/qv4function_p.h>
23#if QT_CONFIG(qml_debug)
24#include "qqmlprofilerdefinitions_p.h"
27#include <QtCore/qurl.h>
28#include <QtCore/qstring.h>
32#if !QT_CONFIG(qml_debug)
34#define Q_QML_PROFILE_IF_ENABLED(feature, profiler, Code)
35#define Q_QML_PROFILE(feature, profiler, Method)
36#define Q_QML_OC_PROFILE(member, Code)
80#define Q_QML_PROFILE_IF_ENABLED(feature, profiler, Code)
81 if (profiler && (profiler->featuresEnabled & (1
<< feature))) {
86#define Q_QML_PROFILE(feature, profiler, Method)
89#define Q_QML_OC_PROFILE(member, Code)
100 QQmlProfilerData(qint64 time = -1,
int messageType = -1,
101 RangeType detailType = MaximumRangeType, quintptr locationId = 0) :
102 time(time), locationId(locationId), messageType(messageType), detailType(detailType)
109 RangeType detailType;
114class Q_QML_EXPORT QQmlProfiler :
public QObject,
public QQmlProfilerDefinitions {
119 Location(
const QQmlSourceLocation &location = QQmlSourceLocation(),
120 const QUrl &url = QUrl()) :
121 location(location), url(url) {}
122 QQmlSourceLocation location;
128 struct RefLocation :
public Location {
130 : Location(), locationType(MaximumRangeType), something(
nullptr), sent(
false)
134 RefLocation(QV4::Function *ref)
135 : Location(ref->sourceLocation()), locationType(Binding), sent(
false)
138 function->executableCompilationUnit()->addref();
141 RefLocation(QV4::ExecutableCompilationUnit *ref,
const QUrl &url,
142 const QV4::CompiledData::Object *obj,
const QString &type)
143 : Location(QQmlSourceLocation(type, obj->location.line(), obj->location.column()), url),
144 locationType(Creating), sent(
false)
150 RefLocation(QQmlBoundSignalExpression *ref)
151 : Location(ref->sourceLocation()), locationType(HandlingSignal), sent(
false)
154 boundSignal->addref();
157 RefLocation(QQmlDataBlob *ref)
158 : Location(QQmlSourceLocation(), ref->url()), locationType(Compiling), sent(
false)
164 RefLocation(
const RefLocation &other)
166 locationType(other.locationType),
167 function(other.function),
173 RefLocation &operator=(
const RefLocation &other)
175 if (
this != &other) {
177 Location::operator=(other);
178 locationType = other.locationType;
179 function = other.function;
196 switch (locationType) {
198 function->executableCompilationUnit()->addref();
204 boundSignal->addref();
210 Q_ASSERT(locationType == MaximumRangeType);
220 switch (locationType) {
222 function->executableCompilationUnit()->release();
228 boundSignal->release();
234 Q_ASSERT(locationType == MaximumRangeType);
241 return locationType != MaximumRangeType;
249 RangeType locationType;
251 QV4::Function *function;
252 QV4::ExecutableCompilationUnit *unit;
253 QQmlBoundSignalExpression *boundSignal;
260 typedef QHash<quintptr, Location> LocationHash;
262 void startBinding(QV4::Function *function)
271 quintptr locationId = function ? id(function) + 1 : id(
this);
272 m_data.append(QQmlProfilerData(m_timer.nsecsElapsed(),
273 (1 << RangeStart | 1 << RangeLocation), Binding,
276 RefLocation &location = m_locations[locationId];
277 if (!location.isValid()) {
279 location = RefLocation(function);
281 location.locationType = Binding;
287 void startCompiling(QQmlDataBlob *blob)
289 quintptr locationId(id(blob));
290 m_data.append(QQmlProfilerData(m_timer.nsecsElapsed(),
291 (1 << RangeStart | 1 << RangeLocation | 1 << RangeData),
292 Compiling, locationId));
294 RefLocation &location = m_locations[locationId];
295 if (!location.isValid())
296 location = RefLocation(blob);
299 void startHandlingSignal(QQmlBoundSignalExpression *expression)
306 quintptr locationId(id(expression->function()) + 2);
307 m_data.append(QQmlProfilerData(m_timer.nsecsElapsed(),
308 (1 << RangeStart | 1 << RangeLocation), HandlingSignal,
311 RefLocation &location = m_locations[locationId];
312 if (!location.isValid())
313 location = RefLocation(expression);
316 void startCreating(
const QV4::CompiledData::Object *obj)
318 m_data.append(QQmlProfilerData(m_timer.nsecsElapsed(),
319 (1 << RangeStart | 1 << RangeLocation | 1 << RangeData),
323 void updateCreating(
const QV4::CompiledData::Object *obj,
324 QV4::ExecutableCompilationUnit *ref,
325 const QUrl &url,
const QString &type)
327 quintptr locationId(id(obj));
328 RefLocation &location = m_locations[locationId];
329 if (!location.isValid())
330 location = RefLocation(ref, url, obj, type);
333 template<RangeType Range>
336 m_data.append(QQmlProfilerData(m_timer.nsecsElapsed(), 1 << RangeEnd, Range));
341 quint64 featuresEnabled;
343 template<
typename Object>
344 static quintptr id(
const Object *pointer)
346 return reinterpret_cast<quintptr>(pointer);
349 void startProfiling(quint64 features);
350 void stopProfiling();
352 void setTimer(
const QElapsedTimer &timer) { m_timer = timer; }
355 void dataReady(
const QVector<QQmlProfilerData> &,
const QQmlProfiler::LocationHash &);
358 QElapsedTimer m_timer;
359 QHash<quintptr, RefLocation> m_locations;
360 QVector<QQmlProfilerData> m_data;
367struct QQmlProfilerHelper :
public QQmlProfilerDefinitions {
368 QQmlProfiler *profiler;
369 QQmlProfilerHelper(QQmlProfiler *profiler) : profiler(profiler) {}
372struct QQmlBindingProfiler :
public QQmlProfilerHelper {
373 QQmlBindingProfiler(QQmlProfiler *profiler, QV4::Function *function) :
374 QQmlProfilerHelper(profiler)
376 Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileBinding, profiler,
377 startBinding(function));
380 ~QQmlBindingProfiler()
382 Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileBinding, profiler,
383 endRange<Binding>());
387struct QQmlHandlingSignalProfiler :
public QQmlProfilerHelper {
388 QQmlHandlingSignalProfiler(QQmlProfiler *profiler, QQmlBoundSignalExpression *expression) :
389 QQmlProfilerHelper(profiler)
391 Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileHandlingSignal, profiler,
392 startHandlingSignal(expression));
395 ~QQmlHandlingSignalProfiler()
397 Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileHandlingSignal, profiler,
398 endRange<QQmlProfiler::HandlingSignal>());
402struct QQmlCompilingProfiler :
public QQmlProfilerHelper {
403 QQmlCompilingProfiler(QQmlProfiler *profiler, QQmlDataBlob *blob) :
404 QQmlProfilerHelper(profiler)
406 Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCompiling, profiler, startCompiling(blob));
409 ~QQmlCompilingProfiler()
411 Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCompiling, profiler, endRange<Compiling>());
415struct QQmlVmeProfiler :
public QQmlProfilerDefinitions {
418 QQmlVmeProfiler() : profiler(
nullptr) {}
420 void init(QQmlProfiler *p)
425 const QV4::CompiledData::Object *pop()
427 if (ranges.size() > 0) {
428 const auto *result = ranges.back();
435 void push(
const QV4::CompiledData::Object *object)
437 ranges.push_back(object);
440 QQmlProfiler *profiler;
443 std::vector<
const QV4::CompiledData::Object *> ranges;
446class QQmlObjectCreationProfiler {
449 QQmlObjectCreationProfiler(QQmlProfiler *profiler,
const QV4::CompiledData::Object *obj)
452 Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCreating, profiler, startCreating(obj));
455 ~QQmlObjectCreationProfiler()
457 Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCreating, profiler, endRange<QQmlProfilerDefinitions::Creating>());
460 void update(QV4::ExecutableCompilationUnit *ref,
const QV4::CompiledData::Object *obj,
461 const QString &typeName,
const QUrl &url)
463 profiler->updateCreating(obj, ref, url, typeName);
467 QQmlProfiler *profiler;
470class QQmlObjectCompletionProfiler {
472 QQmlObjectCompletionProfiler(QQmlVmeProfiler *parent) :
473 profiler(parent->profiler)
476 profiler->startCreating(parent->pop());
480 ~QQmlObjectCompletionProfiler()
482 Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCreating, profiler,
483 endRange<QQmlProfilerDefinitions::Creating>());
486 QQmlProfiler *profiler;
493#if QT_CONFIG(qml_debug)
495Q_DECLARE_METATYPE(QVector<QQmlProfilerData>)
496Q_DECLARE_METATYPE(QQmlProfiler::LocationHash)
Q_DECLARE_TYPEINFO(QByteArrayView, Q_PRIMITIVE_TYPE)
#define Q_QML_PROFILE(feature, profiler, Method)
#define Q_QML_PROFILE_IF_ENABLED(feature, profiler, Code)