aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@digia.com>2014-01-06 13:48:23 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-01-22 14:34:23 +0100
commitf781d97e141632c646da09888c9612931f7c928b (patch)
tree30039814cdb41bbb49fc2d840babf4cb18417eff /src
parenta32bed7047469273cc8513cad7b2923d60f8d590 (diff)
Put multiple QML profiling messages into one object where possible
As most of the QML profiling messages only use a small subset of the available fields in QQmlProfilerData we can a, reduce the size of QQmlProfilerData by using unions b, put multiple messages into one object where their data doesn't overlap Furthermore we can add another field for saving QUrl members in QQmlProfilerData so that we can combine more different messages and don't have to convert from QUrl to QString while profiling. This should reduce the impact of the profiling code on the performance of the application being profiled. Task-number: QTBUG-35315 Change-Id: Iecd61e90cc8490d2efbbb381391d98dfee61d3cd Reviewed-by: Michael Brasser <michael.brasser@live.com> Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/qml/debugger/qqmlprofilerservice.cpp163
-rw-r--r--src/qml/debugger/qqmlprofilerservice_p.h309
-rw-r--r--src/qml/qml/qqmlvme.cpp18
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);