diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2016-05-24 11:58:07 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2016-05-27 09:31:08 +0000 |
commit | 515efdb8a65dc8ba22a56a02ee6d7056f39619cb (patch) | |
tree | d984f8725ca2e9b0663b33378e5fe1d13b64fa8e /src/qml | |
parent | 777aac3005feb01aed21df9e135d5470182bc6ce (diff) |
QmlProfiler: Send RangeData and RangeLocation only once per type
This saves time when serializing the data to be sent.
Change-Id: Ic8c534d55445934a64dd253273099194b27d98af
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml')
-rw-r--r-- | src/qml/debugger/qqmlabstractprofileradapter_p.h | 6 | ||||
-rw-r--r-- | src/qml/debugger/qqmlprofiler.cpp | 18 | ||||
-rw-r--r-- | src/qml/debugger/qqmlprofiler_p.h | 28 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4profiling.cpp | 17 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4profiling_p.h | 49 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 5 |
6 files changed, 87 insertions, 36 deletions
diff --git a/src/qml/debugger/qqmlabstractprofileradapter_p.h b/src/qml/debugger/qqmlabstractprofileradapter_p.h index 1104608055..8820c4311a 100644 --- a/src/qml/debugger/qqmlabstractprofileradapter_p.h +++ b/src/qml/debugger/qqmlabstractprofileradapter_p.h @@ -71,13 +71,13 @@ public: virtual ~QQmlAbstractProfilerAdapter() {} void setService(QQmlProfilerService *new_service) { service = new_service; } - virtual qint64 sendMessages(qint64 until, QList<QByteArray> &messages) = 0; + virtual qint64 sendMessages(qint64 until, QList<QByteArray> &messages, bool trackLocations) = 0; void startProfiling(quint64 features); void stopProfiling(); - void reportData() { emit dataRequested(); } + void reportData(bool trackLocations) { emit dataRequested(trackLocations); } void stopWaiting() { waiting = false; } void startWaiting() { waiting = true; } @@ -94,7 +94,7 @@ signals: void profilingDisabled(); void profilingDisabledWhileWaiting(); - void dataRequested(); + void dataRequested(bool trackLocations); void referenceTimeKnown(const QElapsedTimer &timer); protected: diff --git a/src/qml/debugger/qqmlprofiler.cpp b/src/qml/debugger/qqmlprofiler.cpp index 629d5cb7b8..ffba731b13 100644 --- a/src/qml/debugger/qqmlprofiler.cpp +++ b/src/qml/debugger/qqmlprofiler.cpp @@ -59,19 +59,21 @@ void QQmlProfiler::startProfiling(quint64 features) void QQmlProfiler::stopProfiling() { featuresEnabled = false; - reportData(); + reportData(true); + m_locations.clear(); } -void QQmlProfiler::reportData() +void QQmlProfiler::reportData(bool trackLocations) { LocationHash resolved; resolved.reserve(m_locations.size()); - for (auto it = m_locations.constBegin(), end = m_locations.constEnd(); it != end; ++it) - resolved.insert(it.key(), it.value()); - - // This unrefs all the objects. We have to make sure we do this in the GUI thread. Also, it's - // a good idea to release the memory before creating the packets to be sent. - m_locations.clear(); + for (auto it = m_locations.begin(), end = m_locations.end(); it != end; ++it) { + if (!trackLocations || !it->sent) { + resolved.insert(it.key(), it.value()); + if (trackLocations) + it->sent = true; + } + } QVector<QQmlProfilerData> data; data.swap(m_data); diff --git a/src/qml/debugger/qqmlprofiler_p.h b/src/qml/debugger/qqmlprofiler_p.h index 1380599fb7..60851ac444 100644 --- a/src/qml/debugger/qqmlprofiler_p.h +++ b/src/qml/debugger/qqmlprofiler_p.h @@ -146,26 +146,27 @@ public: // Unfortunately we have to resolve the locations right away because the QML context might not // be available anymore when we send the data. struct RefLocation : public Location { - RefLocation() : Location(), locationType(MaximumRangeType), ref(nullptr) + RefLocation() : Location(), locationType(MaximumRangeType), ref(nullptr), sent(false) {} RefLocation(QQmlBinding *binding, QV4::FunctionObject *function) : Location(function->sourceLocation()), locationType(Binding), - ref(new BindingRefCount(binding), QQmlRefPointer<QQmlRefCount>::Adopt) + ref(new BindingRefCount(binding), QQmlRefPointer<QQmlRefCount>::Adopt), sent(false) {} RefLocation(QQmlCompiledData *ref, const QUrl &url, const QV4::CompiledData::Object *obj, const QString &type) : Location(QQmlSourceLocation(type, obj->location.line, obj->location.column), url), - locationType(Creating), ref(ref) + locationType(Creating), ref(ref), sent(false) {} RefLocation(QQmlBoundSignalExpression *ref) : - Location(ref->sourceLocation()), locationType(HandlingSignal), ref(ref) + Location(ref->sourceLocation()), locationType(HandlingSignal), ref(ref), sent(false) {} RefLocation(QQmlDataBlob *ref) : - Location(QQmlSourceLocation(), ref->url()), locationType(Compiling), ref(ref) + Location(QQmlSourceLocation(), ref->url()), locationType(Compiling), ref(ref), + sent(false) {} bool isValid() const @@ -175,6 +176,7 @@ public: RangeType locationType; QQmlRefPointer<QQmlRefCount> ref; + bool sent; }; typedef QHash<quintptr, Location> LocationHash; @@ -217,11 +219,6 @@ public: location = RefLocation(expression); } - void startCreating() - { - m_data.append(QQmlProfilerData(m_timer.nsecsElapsed(), 1 << RangeStart, Creating)); - } - void startCreating(const QV4::CompiledData::Object *obj) { m_data.append(QQmlProfilerData(m_timer.nsecsElapsed(), @@ -233,10 +230,6 @@ public: const QUrl &url, const QString &type) { quintptr locationId(id(obj)); - m_data.append(QQmlProfilerData(m_timer.nsecsElapsed(), - (1 << RangeLocation | 1 << RangeData), - Creating, locationId)); - RefLocation &location = m_locations[locationId]; if (!location.isValid()) location = RefLocation(ref, url, obj, type); @@ -261,7 +254,7 @@ public: public slots: void startProfiling(quint64 features); void stopProfiling(); - void reportData(); + void reportData(bool trackLocations); void setTimer(const QElapsedTimer &timer) { m_timer = timer; } signals: @@ -363,9 +356,10 @@ private: class QQmlObjectCreationProfiler { public: - QQmlObjectCreationProfiler(QQmlProfiler *profiler) : profiler(profiler) + QQmlObjectCreationProfiler(QQmlProfiler *profiler, const QV4::CompiledData::Object *obj) + : profiler(profiler) { - Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCreating, profiler, startCreating()); + Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCreating, profiler, startCreating(obj)); } ~QQmlObjectCreationProfiler() diff --git a/src/qml/jsruntime/qv4profiling.cpp b/src/qml/jsruntime/qv4profiling.cpp index 72475c5416..349ec48e06 100644 --- a/src/qml/jsruntime/qv4profiling.cpp +++ b/src/qml/jsruntime/qv4profiling.cpp @@ -78,7 +78,8 @@ Profiler::Profiler(QV4::ExecutionEngine *engine) : featuresEnabled(0), m_engine( void Profiler::stopProfiling() { featuresEnabled = 0; - reportData(); + reportData(true); + m_sentLocations.clear(); } bool operator<(const FunctionCall &call1, const FunctionCall &call2) @@ -88,7 +89,7 @@ bool operator<(const FunctionCall &call1, const FunctionCall &call2) (call1.m_end == call2.m_end && call1.m_function < call2.m_function))); } -void Profiler::reportData() +void Profiler::reportData(bool trackLocations) { std::sort(m_data.begin(), m_data.end()); QVector<FunctionCallProperties> properties; @@ -97,9 +98,15 @@ void Profiler::reportData() foreach (const FunctionCall &call, m_data) { properties.append(call.properties()); - FunctionLocation &location = locations[properties.constLast().id]; - if (!location.isValid()) - location = call.resolveLocation(); + Function *function = call.function(); + SentMarker &marker = m_sentLocations[reinterpret_cast<quintptr>(function)]; + if (!trackLocations || !marker.isValid()) { + FunctionLocation &location = locations[properties.constLast().id]; + if (!location.isValid()) + location = call.resolveLocation(); + if (trackLocations) + marker.setFunction(function); + } } emit dataReady(locations, properties, m_memory_data); diff --git a/src/qml/jsruntime/qv4profiling_p.h b/src/qml/jsruntime/qv4profiling_p.h index bb128b7cf3..01fdf2951e 100644 --- a/src/qml/jsruntime/qv4profiling_p.h +++ b/src/qml/jsruntime/qv4profiling_p.h @@ -134,6 +134,11 @@ public: return *this; } + Function *function() const + { + return m_function; + } + FunctionLocation resolveLocation() const; FunctionCallProperties properties() const; @@ -165,6 +170,46 @@ class Q_QML_EXPORT Profiler : public QObject { Q_OBJECT Q_DISABLE_COPY(Profiler) public: + struct SentMarker { + SentMarker() : m_function(nullptr) {} + + SentMarker(const SentMarker &other) : m_function(other.m_function) + { + if (m_function) + m_function->compilationUnit->addref(); + } + + ~SentMarker() + { + if (m_function) + m_function->compilationUnit->release(); + } + + SentMarker &operator=(const SentMarker &other) + { + if (&other != this) { + if (m_function) + m_function->compilationUnit->release(); + m_function = other.m_function; + m_function->compilationUnit->addref(); + } + return *this; + } + + void setFunction(Function *function) + { + Q_ASSERT(m_function == nullptr); + m_function = function; + m_function->compilationUnit->addref(); + } + + bool isValid() const + { return m_function != nullptr; } + + private: + Function *m_function; + }; + Profiler(QV4::ExecutionEngine *engine); size_t trackAlloc(size_t size, MemoryType type) @@ -186,7 +231,7 @@ public: public slots: void stopProfiling(); void startProfiling(quint64 features); - void reportData(); + void reportData(bool trackLocations); void setTimer(const QElapsedTimer &timer) { m_timer = timer; } signals: @@ -199,6 +244,7 @@ private: QElapsedTimer m_timer; QVector<FunctionCall> m_data; QVector<MemoryAllocationProperties> m_memory_data; + QHash<quintptr, SentMarker> m_sentLocations; friend class FunctionCallProfiler; }; @@ -237,6 +283,7 @@ Q_DECLARE_TYPEINFO(QV4::Profiling::MemoryAllocationProperties, Q_MOVABLE_TYPE); Q_DECLARE_TYPEINFO(QV4::Profiling::FunctionCallProperties, Q_MOVABLE_TYPE); Q_DECLARE_TYPEINFO(QV4::Profiling::FunctionCall, Q_MOVABLE_TYPE); Q_DECLARE_TYPEINFO(QV4::Profiling::FunctionLocation, Q_MOVABLE_TYPE); +Q_DECLARE_TYPEINFO(QV4::Profiling::Profiler::SentMarker, Q_MOVABLE_TYPE); QT_END_NAMESPACE Q_DECLARE_METATYPE(QV4::Profiling::FunctionLocationHash) diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index a6b24c4f16..9dba7f30d8 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -1017,7 +1017,9 @@ QV4::Heap::QmlContext *QQmlObjectCreator::currentQmlContext() QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isContextObject) { - QQmlObjectCreationProfiler profiler(sharedState->profiler.profiler); + const QV4::CompiledData::Object *obj = qmlUnit->objectAt(index); + QQmlObjectCreationProfiler profiler(sharedState->profiler.profiler, obj); + ActiveOCRestorer ocRestorer(this, QQmlEnginePrivate::get(engine)); bool isComponent = false; @@ -1027,7 +1029,6 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo QQmlParserStatus *parserStatus = 0; bool installPropertyCache = true; - const QV4::CompiledData::Object *obj = qmlUnit->objectAt(index); if (obj->flags & QV4::CompiledData::Object::IsComponent) { isComponent = true; QQmlComponent *component = new QQmlComponent(engine, compiledData, index, parent); |