diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/debugger/qqmlprofilerservice.cpp | 163 | ||||
-rw-r--r-- | src/qml/debugger/qqmlprofilerservice_p.h | 309 | ||||
-rw-r--r-- | src/qml/qml/qqmlvme.cpp | 18 |
3 files changed, 249 insertions, 241 deletions
diff --git a/src/qml/debugger/qqmlprofilerservice.cpp b/src/qml/debugger/qqmlprofilerservice.cpp index b294e2e140..2d958fb1ce 100644 --- a/src/qml/debugger/qqmlprofilerservice.cpp +++ b/src/qml/debugger/qqmlprofilerservice.cpp @@ -54,61 +54,74 @@ QQmlProfilerService *QQmlProfilerService::instance = 0; Q_GLOBAL_STATIC(QQmlProfilerService, profilerInstance) bool QQmlProfilerService::enabled = false; -// convert to a QByteArray that can be sent to the debug client +// convert to QByteArrays that can be sent to the debug client // use of QDataStream can skew results // (see tst_qqmldebugtrace::trace() benchmark) -QByteArray QQmlProfilerData::toByteArray() const +void QQmlProfilerData::toByteArrays(QList<QByteArray> &messages) const { QByteArray data; //### using QDataStream is relatively expensive - QQmlDebugStream ds(&data, QIODevice::WriteOnly); - ds << time << messageType << detailType; - if (messageType == (int)QQmlProfilerService::RangeStart && - detailType == (int)QQmlProfilerService::Binding) - ds << bindingType; - if (messageType == (int)QQmlProfilerService::RangeData) - ds << detailData; - if (messageType == (int)QQmlProfilerService::RangeLocation) - ds << detailData << line << column; - if (messageType == (int)QQmlProfilerService::Event && - detailType == (int)QQmlProfilerService::AnimationFrame) - ds << framerate << animationcount; - if (messageType == (int)QQmlProfilerService::PixmapCacheEvent) { - ds << detailData; - switch (detailType) { - case QQmlProfilerService::PixmapSizeKnown: ds << line << column; break; - case QQmlProfilerService::PixmapReferenceCountChanged: ds << animationcount; break; - case QQmlProfilerService::PixmapCacheCountChanged: ds << animationcount; break; - default: break; - } - } - if (messageType == (int)QQmlProfilerService::SceneGraphFrame) { - switch (detailType) { - // RendererFrame: preprocessTime, updateTime, bindingTime, renderTime - case QQmlProfilerService::SceneGraphRendererFrame: ds << subtime_1 << subtime_2 << subtime_3 << subtime_4; break; - // AdaptationLayerFrame: glyphCount (which is an integer), glyphRenderTime, glyphStoreTime - case QQmlProfilerService::SceneGraphAdaptationLayerFrame: ds << (int)subtime_1 << subtime_2 << subtime_3; break; - // ContextFrame: compiling material time - case QQmlProfilerService::SceneGraphContextFrame: ds << subtime_1; break; - // RenderLoop: syncTime, renderTime, swapTime - case QQmlProfilerService::SceneGraphRenderLoopFrame: ds << subtime_1 << subtime_2 << subtime_3; break; - // TexturePrepare: bind, convert, swizzle, upload, mipmap - case QQmlProfilerService::SceneGraphTexturePrepare: ds << subtime_1 << subtime_2 << subtime_3 << subtime_4 << subtime_5; break; - // TextureDeletion: deletionTime - case QQmlProfilerService::SceneGraphTextureDeletion: ds << subtime_1; break; - // PolishAndSync: polishTime, waitTime, syncTime, animationsTime, - case QQmlProfilerService::SceneGraphPolishAndSync: ds << subtime_1 << subtime_2 << subtime_3 << subtime_4; break; - // WindowsRenderLoop: GL time, make current time, SceneGraph time - case QQmlProfilerService::SceneGraphWindowsRenderShow: ds << subtime_1 << subtime_2 << subtime_3; break; - // WindowsAnimations: update time - case QQmlProfilerService::SceneGraphWindowsAnimations: ds << subtime_1; break; - // WindowsRenderWindow: polish time - case QQmlProfilerService::SceneGraphWindowsPolishFrame: ds << subtime_1; break; - default:break; + for (int i = 0; i < QQmlProfilerService::MaximumMessage; ++i) { + if ((messageType & (1 << i)) == 0) + continue; + + QQmlDebugStream ds(&data, QIODevice::WriteOnly); + ds << time << i << detailType; + switch (i) { + case QQmlProfilerService::Event: + if (detailType == (int)QQmlProfilerService::AnimationFrame) + ds << framerate << count; + break; + case QQmlProfilerService::RangeStart: + if (detailType == (int)QQmlProfilerService::Binding) + ds << bindingType; + break; + case QQmlProfilerService::RangeData: + ds << detailString; + break; + case QQmlProfilerService::RangeLocation: + ds << (detailUrl.isEmpty() ? detailString : detailUrl.toString()) << x << y; + break; + case QQmlProfilerService::RangeEnd: break; + case QQmlProfilerService::PixmapCacheEvent: + ds << detailUrl.toString(); + switch (detailType) { + case QQmlProfilerService::PixmapSizeKnown: ds << x << y; break; + case QQmlProfilerService::PixmapReferenceCountChanged: ds << count; break; + case QQmlProfilerService::PixmapCacheCountChanged: ds << count; break; + default: break; + } + break; + case QQmlProfilerService::SceneGraphFrame: + switch (detailType) { + // RendererFrame: preprocessTime, updateTime, bindingTime, renderTime + case QQmlProfilerService::SceneGraphRendererFrame: ds << subtime_1 << subtime_2 << subtime_3 << subtime_4; break; + // AdaptationLayerFrame: glyphCount (which is an integer), glyphRenderTime, glyphStoreTime + case QQmlProfilerService::SceneGraphAdaptationLayerFrame: ds << (int)subtime_1 << subtime_2 << subtime_3; break; + // ContextFrame: compiling material time + case QQmlProfilerService::SceneGraphContextFrame: ds << subtime_1; break; + // RenderLoop: syncTime, renderTime, swapTime + case QQmlProfilerService::SceneGraphRenderLoopFrame: ds << subtime_1 << subtime_2 << subtime_3; break; + // TexturePrepare: bind, convert, swizzle, upload, mipmap + case QQmlProfilerService::SceneGraphTexturePrepare: ds << subtime_1 << subtime_2 << subtime_3 << subtime_4 << subtime_5; break; + // TextureDeletion: deletionTime + case QQmlProfilerService::SceneGraphTextureDeletion: ds << subtime_1; break; + // PolishAndSync: polishTime, waitTime, syncTime, animationsTime, + case QQmlProfilerService::SceneGraphPolishAndSync: ds << subtime_1 << subtime_2 << subtime_3 << subtime_4; break; + // WindowsRenderLoop: GL time, make current time, SceneGraph time + case QQmlProfilerService::SceneGraphWindowsRenderShow: ds << subtime_1 << subtime_2 << subtime_3; break; + // WindowsAnimations: update time + case QQmlProfilerService::SceneGraphWindowsAnimations: ds << subtime_1; break; + // WindowsRenderWindow: polish time + case QQmlProfilerService::SceneGraphWindowsPolishFrame: ds << subtime_1; break; + default:break; + } + break; + case QQmlProfilerService::Complete: break; } + messages << data; + data.clear(); } - - return data; } void QQmlProfilerService::animationTimerCallback(qint64 delta) @@ -162,10 +175,9 @@ bool QQmlProfilerService::startProfilingImpl() { if (QQmlDebugService::isDebuggingEnabled() && !enabled) { enabled = true; - QQmlProfilerData ed = {m_timer.nsecsElapsed(), (int)Event, (int)StartTrace, - QString(), -1, -1, 0, 0, 0, - 0, 0, 0, 0, 0}; - QQmlDebugService::sendMessage(ed.toByteArray()); + QList<QByteArray> messages; + QQmlProfilerData(m_timer.nsecsElapsed(), 1 << Event, StartTrace).toByteArrays(messages); + QQmlDebugService::sendMessages(messages); return true; } else { return false; @@ -178,10 +190,7 @@ bool QQmlProfilerService::stopProfilingImpl() enabled = false; // We cannot use instance here as this is called from the debugger thread. // It may be called before the QML engine (and the profiler) is ready. - QQmlProfilerData ed = {m_timer.nsecsElapsed(), (int)Event, (int)EndTrace, - QString(), -1, -1, 0, 0, 0, - 0, 0, 0, 0, 0}; - processMessage(ed); + processMessage(QQmlProfilerData(m_timer.nsecsElapsed(), 1 << Event, EndTrace)); return true; } else { return false; @@ -197,7 +206,7 @@ void QQmlProfilerService::sendMessages() QList<QByteArray> messages; for (int i = 0; i < m_data.count(); ++i) - messages << m_data.at(i).toByteArray(); + m_data.at(i).toByteArrays(messages); m_data.clear(); //indicate completion @@ -256,30 +265,26 @@ void QQmlProfilerService::messageReceived(const QByteArray &message) */ /*! - * \fn bool QQmlVmeProfiler::start() - * Clears the current range data, then stops the profiler previously running in the - * foreground if any, then starts a new one if profiling is enabled. - * Returns whether the new profiler was actually started. + * \fn bool QQmlVmeProfiler::startBackground(const QString &typeName) + * If profiling is enabled clears the current range data, then stops the + * profiler previously running in the foreground if any, then starts a new one + * in the background, setting the given typeName. \a typeName is the type of + * object being created. */ /*! - * \fn void QQmlVmeProfiler::updateLocation(const QUrl &url, int line, int column) - * Updates the current profiler's location information. \a url is the URL of + * \fn bool QQmlVmeProfiler::start(const QString &typeName, const QUrl &url, int line, int column) + * If profiling is enabled clears the current range data, then stops the + * profiler previously running in the foreground if any, then starts a new one + * in the foreground, setting the given location. \a url is the URL of * file being executed, \line line is the current line in in that file, and * \a column is the current column in that file. */ /*! - * \fn void QQmlVmeProfiler::updateTypeName(const QString &typename) - * Updates the current profiler's type information. \a typeName is the type of - * object being created. - */ - -/*! * \fn bool QQmlVmeProfiler::pop() * Stops the currently running profiler, if any, then retrieves an old one from the stack * of paused profilers and starts that if possible. - * Returns whether there actually is a running profiler after that. */ /*! @@ -300,19 +305,13 @@ void QQmlProfilerService::messageReceived(const QByteArray &message) * Stop profiler running in the foreground, if any. */ - /*! - * \fn void QQmlVmeProfiler::background() - * Pushes the profiler currently running in the foreground to the background so that it - * won't be stopped by stop() or start(). There can be multiple profilers in the background. - * You can retrieve them in reverse order by calling foreground(). - */ - -/*! - * \fn bool QQmlVmeProfiler::foreground() - * Stops the profiler currently running in the foreground, if any and puts the next profiler - * from the background in its place if there are any profiles in the background. - * Returns Whethere there actually is a valid running profiler afterwards. + * \fn bool QQmlVmeProfiler::foreground(const QUrl &url, int line, int column) + * Stops the profiler currently running in the foreground, if any and puts the + * next profiler from the background in its place if there are any profilers in + * the background. Additionally the rangeLocation is set. \a url is the URL of + * file being executed, \line line is the current line in in that file, and + * \a column is the current column in that file. */ QT_END_NAMESPACE diff --git a/src/qml/debugger/qqmlprofilerservice_p.h b/src/qml/debugger/qqmlprofilerservice_p.h index 6de24c188c..85d515c7dd 100644 --- a/src/qml/debugger/qqmlprofilerservice_p.h +++ b/src/qml/debugger/qqmlprofilerservice_p.h @@ -73,27 +73,79 @@ QT_BEGIN_NAMESPACE +// This struct is somewhat dangerous to use: +// You can save values either with 32 or 64 bit precision. toByteArrays will +// guess the precision from messageType. If you state the wrong messageType +// you will get undefined results. +// The messageType is itself a bit field. You can pack multiple messages into +// one object, e.g. RangeStart and RangeLocation. Each one will be read +// independently by toByteArrays. Thus you can only pack messages if their data +// doesn't overlap. Again, it's up to you to figure that out. struct Q_AUTOTEST_EXPORT QQmlProfilerData { + QQmlProfilerData() {} + + QQmlProfilerData(qint64 time, int messageType, int detailType, const QUrl &url, + int x = 0, int y = 0, int framerate = 0, int count = 0, int bindingType = 0) : + time(time), messageType(messageType), detailType(detailType), detailUrl(url), + x(x), y(y), framerate(framerate), count(count), bindingType(bindingType) {} + + QQmlProfilerData(qint64 time, int messageType, int detailType, const QString &str, + int x = 0, int y = 0, int framerate = 0, int count = 0, int bindingType = 0) : + time(time), messageType(messageType), detailType(detailType),detailString(str), + x(x), y(y), framerate(framerate), count(count), bindingType(bindingType) {} + + QQmlProfilerData(qint64 time, int messageType, int detailType, const QString &str, + const QUrl &url, int x = 0, int y = 0, int framerate = 0, int count = 0, + int bindingType = 0) : + time(time), messageType(messageType), detailType(detailType), detailString(str), + detailUrl(url), x(x), y(y), framerate(framerate), count(count), bindingType(bindingType) {} + + + QQmlProfilerData(qint64 time, int messageType, int detailType) : + time(time), messageType(messageType), detailType(detailType) {} + + // Special ctor for scenegraph frames. Note that it's missing the QString/QUrl params. + // This is slightly ugly, but makes it easier to disambiguate between int and qint64 params. + QQmlProfilerData(qint64 time, int messageType, int detailType, + qint64 d1, qint64 d2, qint64 d3, qint64 d4, qint64 d5) : + time(time), messageType(messageType), detailType(detailType), + subtime_1(d1), subtime_2(d2), subtime_3(d3), subtime_4(d4), subtime_5(d5) {} + + qint64 time; - int messageType; + int messageType; //bit field of QQmlProfilerService::Message int detailType; - //### - QString detailData; //used by RangeData and RangeLocation - int line; //used by RangeLocation, also as "width" for pixmaps - int column; //used by RangeLocation, also as "height" for pixmaps - int framerate; //used by animation events - int animationcount; //used by animation events, also as "cache/reference count" for pixmaps - int bindingType; - - qint64 subtime_1; - qint64 subtime_2; - qint64 subtime_3; - qint64 subtime_4; - qint64 subtime_5; - - QByteArray toByteArray() const; + QString detailString; //used by RangeData and possibly by RangeLocation + QUrl detailUrl; //used by RangeLocation, overrides detailString + + union { + qint64 subtime_1; + int x; //used by RangeLocation and for pixmaps + }; + + union { + qint64 subtime_2; + int y; //used by RangeLocation and for pixmaps + }; + + union { + qint64 subtime_3; + int framerate; //used by animation events + }; + + union { + qint64 subtime_4; + int count; //used by animation events and for pixmaps + }; + + union { + qint64 subtime_5; + int bindingType; + }; + + void toByteArrays(QList<QByteArray> &messages) const; }; Q_DECLARE_TYPEINFO(QQmlProfilerData, Q_MOVABLE_TYPE); @@ -180,10 +232,7 @@ public: static void addEvent(EventType event) { - QQmlProfilerData ed = {instance->m_timer.nsecsElapsed(), (int)Event, (int)event, - QString(), -1, -1, 0, 0, 0, - 0, 0, 0, 0, 0}; - instance->processMessage(ed); + instance->processMessage(QQmlProfilerData(instance->timestamp(), 1 << Event, event)); } static void animationFrame(qint64 delta) @@ -191,52 +240,43 @@ public: int animCount = QUnifiedTimer::instance()->runningAnimationCount(); if (animCount > 0 && delta > 0) { - QQmlProfilerData ed = {instance->m_timer.nsecsElapsed(), (int)Event, - (int)AnimationFrame, QString(), -1, -1, - 1000 / (int)delta /* trim fps to integer */, animCount, 0, 0, 0, - 0, 0, 0}; - instance->processMessage(ed); + instance->processMessage(QQmlProfilerData(instance->timestamp(), 1 << Event, + AnimationFrame, QString(), 0, 0, + 1000 / (int)delta /* trim fps to integer */, + animCount)); } } static void sceneGraphFrame(SceneGraphFrameType frameType, qint64 value1, qint64 value2 = -1, qint64 value3 = -1, qint64 value4 = -1, qint64 value5 = -1) { - // because I already have some space to store ints in the struct, I'll use it to store the - // frame data even though the field names do not match - QQmlProfilerData ed = {instance->m_timer.nsecsElapsed(), (int)SceneGraphFrame, - (int)frameType, QString(), -1, -1, -1, -1, -1, - value1, value2, value3, value4, value5}; - instance->processMessage(ed); + instance->processMessage(QQmlProfilerData(instance->timestamp(), 1 << SceneGraphFrame, + frameType, value1, value2, value3, value4, + value5)); } static void pixmapEvent(PixmapEventType eventType, const QUrl &url) { - QQmlProfilerData ed = {instance->m_timer.nsecsElapsed(), (int)PixmapCacheEvent, - (int)eventType, url.toString(), -1, -1, -1, -1, -1, - 0, 0, 0, 0, 0}; - instance->processMessage(ed); + instance->processMessage(QQmlProfilerData(instance->timestamp(), 1 << PixmapCacheEvent, + eventType, url)); } static void pixmapEvent(PixmapEventType eventType, const QUrl &url, int count) { - QQmlProfilerData ed = {instance->m_timer.nsecsElapsed(), (int)PixmapCacheEvent, - (int)eventType, url.toString(), -1, -1, -1, count, -1, - 0, 0, 0, 0, 0}; - instance->processMessage(ed); + instance->processMessage(QQmlProfilerData(instance->timestamp(), 1 << PixmapCacheEvent, + eventType, url, 0, 0, 0, count)); } static void pixmapEvent(PixmapEventType eventType, const QUrl &url, const QSize &size) { if (size.width() > 0 && size.height() > 0) { - QQmlProfilerData ed = {instance->m_timer.nsecsElapsed(), (int)PixmapCacheEvent, - (int)eventType, url.toString(), - size.width(), size.height(), -1, -1, -1, - 0, 0, 0, 0, 0}; - instance->processMessage(ed); + instance->processMessage(QQmlProfilerData(instance->timestamp(), 1 << PixmapCacheEvent, + eventType, url, size.width(), size.height())); } } + qint64 timestamp() {return m_timer.nsecsElapsed();} + static void sendProfilingData(); QQmlProfilerService(); @@ -250,52 +290,57 @@ private: bool startProfilingImpl(); bool stopProfilingImpl(); - static void startRange(RangeType range, BindingType bindingType = QmlBinding) + static void startRange(RangeType range, const QString &fileName, int line, int column, + BindingType bindingType = QmlBinding) + { + instance->processMessage(QQmlProfilerData(instance->timestamp(), + (1 << RangeStart | 1 << RangeLocation), range, + fileName, line, column, 0, 0, bindingType)); + } + + // Have toByteArrays() construct another RangeData event from the same QString later. + // This is somewhat pointless but important for backwards compatibility. + static void startRangeWithData(RangeType range, const QString &name, int line, int column, + BindingType bindingType = QmlBinding) { - QQmlProfilerData rd = {instance->m_timer.nsecsElapsed(), (int)RangeStart, (int)range, - QString(), -1, -1, 0, 0, (int)bindingType, - 0, 0, 0, 0, 0}; - instance->processMessage(rd); + instance->processMessage(QQmlProfilerData(instance->timestamp(), (1 << RangeStart | 1 << RangeLocation | 1 << RangeData), + range, name, line, column, 0, 0, bindingType)); } - static void rangeData(RangeType range, const QString &rData) + static void startRange(RangeType range, const QUrl &fileName, int line, int column, + BindingType bindingType = QmlBinding) { - QQmlProfilerData rd = {instance->m_timer.nsecsElapsed(), (int)RangeData, (int)range, - rData, -1, -1, 0, 0, 0, - 0, 0, 0, 0, 0}; - instance->processMessage(rd); + instance->processMessage(QQmlProfilerData(instance->timestamp(), + (1 << RangeStart | 1 << RangeLocation), + range, fileName, line, column, 0, 0, + bindingType)); } - static void rangeData(RangeType range, const QUrl &rData) + static void startRange(RangeType range, const QString &rData, const QUrl &fileName, int line, + int column, BindingType bindingType = QmlBinding) { - QQmlProfilerData rd = {instance->m_timer.nsecsElapsed(), (int)RangeData, (int)range, - rData.toString(), -1, -1, 0, 0, 0, - 0, 0, 0, 0, 0}; - instance->processMessage(rd); + instance->processMessage(QQmlProfilerData(instance->timestamp(), (1 << RangeStart | 1 << RangeLocation | 1 << RangeData), + range, rData, fileName, line, column, 0, 0, + bindingType)); } - static void rangeLocation(RangeType range, const QString &fileName, int line, int column) + static void startRange(RangeType range, const QString &rData, + BindingType bindingType = QmlBinding) { - QQmlProfilerData rd = {instance->m_timer.nsecsElapsed(), (int)RangeLocation, (int)range, - fileName, line, column, 0, 0, 0, - 0, 0, 0, 0, 0}; - instance->processMessage(rd); + instance->processMessage(QQmlProfilerData(instance->timestamp(), + (1 << RangeStart | 1 << RangeData), range, + rData, 0, 0, 0, 0, bindingType)); } static void rangeLocation(RangeType range, const QUrl &fileName, int line, int column) { - QQmlProfilerData rd = {instance->m_timer.nsecsElapsed(), (int)RangeLocation, (int)range, - fileName.toString(), line, column, 0, 0, 0, - 0, 0, 0, 0, 0}; - instance->processMessage(rd); + instance->processMessage(QQmlProfilerData(instance->timestamp(), 1 << RangeLocation, range, + fileName, line, column)); } static void endRange(RangeType range) { - QQmlProfilerData rd = {instance->m_timer.nsecsElapsed(), (int)RangeEnd, (int)range, - QString(), -1, -1, 0, 0, 0, - 0, 0, 0, 0, 0}; - instance->processMessage(rd); + instance->processMessage(QQmlProfilerData(instance->timestamp(), 1 << RangeEnd, range)); } void sendMessages(); @@ -332,8 +377,7 @@ private: struct QQmlBindingProfiler { QQmlBindingProfiler(const QString &url, int line, int column, QQmlProfilerService::BindingType bindingType) { - Q_QML_PROFILE(startRange(QQmlProfilerService::Binding, bindingType)); - Q_QML_PROFILE(rangeLocation(QQmlProfilerService::Binding, url, line, column)); + Q_QML_PROFILE(startRange(QQmlProfilerService::Binding, url, line, column, bindingType)); } ~QQmlBindingProfiler() @@ -345,10 +389,8 @@ struct QQmlBindingProfiler { struct QQmlHandlingSignalProfiler { QQmlHandlingSignalProfiler(QQmlBoundSignalExpression *expression) { - Q_QML_PROFILE(startRange(QQmlProfilerService::HandlingSignal)); - Q_QML_PROFILE(rangeLocation(QQmlProfilerService::HandlingSignal, - expression->sourceFile(), expression->lineNumber(), - expression->columnNumber())); + Q_QML_PROFILE(startRange(QQmlProfilerService::HandlingSignal, + expression->sourceFile(), expression->lineNumber(), expression->columnNumber())); } ~QQmlHandlingSignalProfiler() @@ -360,9 +402,7 @@ struct QQmlHandlingSignalProfiler { struct QQmlCompilingProfiler { QQmlCompilingProfiler(const QString &name) { - Q_QML_PROFILE(startRange(QQmlProfilerService::Compiling)); - Q_QML_PROFILE(rangeLocation(QQmlProfilerService::Compiling, name, 1, 1)); - Q_QML_PROFILE(rangeData(QQmlProfilerService::Compiling, name)); + Q_QML_PROFILE(startRangeWithData(QQmlProfilerService::Compiling, name, 1, 1)); } ~QQmlCompilingProfiler() @@ -380,30 +420,16 @@ public: int line; int column; QString typeName; - void clear() - { - url.clear(); - line = 0; - column = 0; - typeName.clear(); - } }; - QQmlVmeProfiler() : - running(false) - {} - - ~QQmlVmeProfiler() - { - if (QQmlProfilerService::enabled) - clear(); - } + QQmlVmeProfiler() : running(false) {} void clear() { - stop(); ranges.clear(); if (QQmlProfilerService::enabled) { + if (running) + QQmlProfilerService::instance->endRange(QQmlProfilerService::Creating); for (int i = 0; i < backgroundRanges.count(); ++i) { QQmlProfilerService::instance->endRange(QQmlProfilerService::Creating); } @@ -412,59 +438,45 @@ public: running = false; } - bool start() + void startBackground(const QString &typeName) { if (QQmlProfilerService::enabled) { - currentRange.clear(); - if (running) + if (running) { QQmlProfilerService::instance->endRange(QQmlProfilerService::Creating); - else - running = true; - QQmlProfilerService::instance->startRange(QQmlProfilerService::Creating); - return true; - } - return false; - } - - void stop() - { - if (QQmlProfilerService::enabled && running) { - QQmlProfilerService::instance->endRange(QQmlProfilerService::Creating); - currentRange.clear(); - running = false; + running = false; + } + QQmlProfilerService::instance->startRange(QQmlProfilerService::Creating, typeName); + backgroundRanges.push(typeName); } } - void updateLocation(const QUrl &url, int line, int column) + void start(const QString &typeName, const QUrl &url, int line, int column) { - if (QQmlProfilerService::enabled && running) { - currentRange.url = url; - currentRange.line = line; - currentRange.column = column; - QQmlProfilerService::instance->rangeLocation( - QQmlProfilerService::Creating, url, line, column); + if (QQmlProfilerService::enabled) { + switchRange(); + setCurrentRange(typeName, url, line, column); + QQmlProfilerService::instance->startRange(QQmlProfilerService::Creating, typeName, url, + line, column); } } - void updateTypeName(const QString &typeName) + void stop() { if (QQmlProfilerService::enabled && running) { - currentRange.typeName = typeName; - QQmlProfilerService::instance->rangeData(QQmlProfilerService::Creating, typeName); + QQmlProfilerService::instance->endRange(QQmlProfilerService::Creating); + running = false; } } - bool pop() + void pop() { if (QQmlProfilerService::enabled && ranges.count() > 0) { - start(); + switchRange(); currentRange = ranges.pop(); - QQmlProfilerService::instance->rangeLocation( - QQmlProfilerService::Creating, currentRange.url, currentRange.line, currentRange.column); - QQmlProfilerService::instance->rangeData(QQmlProfilerService::Creating, currentRange.typeName); - return true; + QQmlProfilerService::instance->startRange(QQmlProfilerService::Creating, + currentRange.typeName, currentRange.url, + currentRange.line, currentRange.column); } - return false; } void push() @@ -473,30 +485,37 @@ public: ranges.push(currentRange); } - void background() + void foreground(const QUrl &url, int line, int column) { - if (QQmlProfilerService::enabled && running) { - backgroundRanges.push(currentRange); - running = false; + if (QQmlProfilerService::enabled && backgroundRanges.count() > 0) { + switchRange(); + setCurrentRange(backgroundRanges.pop(), url, line, column); + QQmlProfilerService::instance->rangeLocation( + QQmlProfilerService::Creating, url, line, column); } } - bool foreground() +private: + + void switchRange() { - if (QQmlProfilerService::enabled && backgroundRanges.count() > 0) { - stop(); - currentRange = backgroundRanges.pop(); + if (running) + QQmlProfilerService::instance->endRange(QQmlProfilerService::Creating); + else running = true; - return true; - } - return false; } -private: + void setCurrentRange(const QString &typeName, const QUrl &url, int line, int column) + { + currentRange.typeName = typeName; + currentRange.url = url; + currentRange.line = line; + currentRange.column = column; + } Data currentRange; QStack<Data> ranges; - QStack<Data> backgroundRanges; + QStack<QString> backgroundRanges; bool running; }; diff --git a/src/qml/qml/qqmlvme.cpp b/src/qml/qml/qqmlvme.cpp index 1881b554ed..f5229be7ef 100644 --- a/src/qml/qml/qqmlvme.cpp +++ b/src/qml/qml/qqmlvme.cpp @@ -503,10 +503,7 @@ QObject *QQmlVME::run(QList<QQmlError> *errors, const QQmlCompiledData::TypeReference &type = TYPES.at(instr.type); Q_ASSERT(type.component); - if (profiler.start()) { - profiler.updateTypeName(type.component->name); - profiler.background(); - } + profiler.startBackground(type.component->name); states.push(State()); @@ -529,8 +526,7 @@ QObject *QQmlVME::run(QList<QQmlError> *errors, QML_END_INSTR(CreateQMLObject) QML_BEGIN_INSTR(CompleteQMLObject) - if (profiler.foreground()) - profiler.updateLocation(CTXT->url, instr.line, instr.column); + profiler.foreground(CTXT->url, instr.line, instr.column); QObject *o = objects.top(); Q_ASSERT(o); @@ -574,10 +570,7 @@ QObject *QQmlVME::run(QList<QQmlError> *errors, QML_BEGIN_INSTR(CreateCppObject) const QQmlCompiledData::TypeReference &type = TYPES.at(instr.type); Q_ASSERT(type.type); - if (profiler.start()) { - profiler.updateLocation(CTXT->url, instr.line, instr.column); - profiler.updateTypeName(type.type->qmlTypeName()); - } + profiler.start(type.type->qmlTypeName(), CTXT->url, instr.line, instr.column); QObject *o = 0; void *memory = 0; @@ -650,10 +643,7 @@ QObject *QQmlVME::run(QList<QQmlError> *errors, QML_BEGIN_INSTR(CreateSimpleObject) const QQmlCompiledData::TypeReference &ref = TYPES.at(instr.type); - if (profiler.start()) { - profiler.updateLocation(CTXT->url, instr.line, instr.column); - profiler.updateTypeName(ref.type->qmlTypeName()); - } + profiler.start(ref.type->qmlTypeName(), CTXT->url, instr.line, instr.column); QObject *o = (QObject *)operator new(instr.typeSize + sizeof(QQmlData)); ::memset(static_cast<void *>(o), 0, instr.typeSize + sizeof(QQmlData)); instr.create(o); |