//### 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)
if (!QQmlDebugService::isDebuggingEnabled() || !m_enabled)
return;
- QQmlProfilerData ed = {m_timer.nsecsElapsed(), (int)Event, (int)StartTrace, QString(), -1, -1, 0, 0};
+ QQmlProfilerData ed = {m_timer.nsecsElapsed(), (int)Event, (int)StartTrace,
+ QString(), -1, -1, 0, 0, 0};
QQmlDebugService::sendMessage(ed.toByteArray());
}
if (!QQmlDebugService::isDebuggingEnabled() || !m_enabled)
return;
- QQmlProfilerData ed = {m_timer.nsecsElapsed(), (int)Event, (int)event, QString(), -1, -1, 0, 0};
+ QQmlProfilerData ed = {m_timer.nsecsElapsed(), (int)Event, (int)event,
+ QString(), -1, -1, 0, 0, 0};
processMessage(ed);
}
-void QQmlProfilerService::startRange(RangeType range)
+void QQmlProfilerService::startRange(RangeType range, BindingType bindingType)
{
if (!QQmlDebugService::isDebuggingEnabled() || !m_enabled)
return;
- QQmlProfilerData rd = {m_timer.nsecsElapsed(), (int)RangeStart, (int)range, QString(), -1, -1, 0, 0};
+ QQmlProfilerData rd = {m_timer.nsecsElapsed(), (int)RangeStart, (int)range,
+ QString(), -1, -1, 0, 0, (int)bindingType};
processMessage(rd);
}
if (!QQmlDebugService::isDebuggingEnabled() || !m_enabled)
return;
- QQmlProfilerData rd = {m_timer.nsecsElapsed(), (int)RangeData, (int)range, rData, -1, -1, 0, 0};
+ QQmlProfilerData rd = {m_timer.nsecsElapsed(), (int)RangeData, (int)range,
+ rData, -1, -1, 0, 0, 0};
processMessage(rd);
}
if (!QQmlDebugService::isDebuggingEnabled() || !m_enabled)
return;
- QQmlProfilerData rd = {m_timer.nsecsElapsed(), (int)RangeData, (int)range, rData.toString(), -1, -1, 0, 0};
+ QQmlProfilerData rd = {m_timer.nsecsElapsed(), (int)RangeData, (int)range,
+ rData.toString(), -1, -1, 0, 0, 0};
processMessage(rd);
}
if (!QQmlDebugService::isDebuggingEnabled() || !m_enabled)
return;
- QQmlProfilerData rd = {m_timer.nsecsElapsed(), (int)RangeLocation, (int)range, fileName, line, column, 0, 0};
+ QQmlProfilerData rd = {m_timer.nsecsElapsed(), (int)RangeLocation, (int)range,
+ fileName, line, column, 0, 0, 0};
processMessage(rd);
}
if (!QQmlDebugService::isDebuggingEnabled() || !m_enabled)
return;
- QQmlProfilerData rd = {m_timer.nsecsElapsed(), (int)RangeLocation, (int)range, fileName.toString(), line, column, 0, 0};
+ QQmlProfilerData rd = {m_timer.nsecsElapsed(), (int)RangeLocation, (int)range,
+ fileName.toString(), line, column, 0, 0, 0};
processMessage(rd);
}
if (!QQmlDebugService::isDebuggingEnabled() || !m_enabled)
return;
- QQmlProfilerData rd = {m_timer.nsecsElapsed(), (int)RangeEnd, (int)range, QString(), -1, -1, 0, 0};
+ QQmlProfilerData rd = {m_timer.nsecsElapsed(), (int)RangeEnd, (int)range,
+ QString(), -1, -1, 0, 0, 0};
processMessage(rd);
}
if (animCount > 0 && delta > 0) {
// trim fps to integer
int fps = 1000 / delta;
- QQmlProfilerData ed = {m_timer.nsecsElapsed(), (int)Event, (int)AnimationFrame, QString(), -1, -1, fps, animCount};
+ QQmlProfilerData ed = {m_timer.nsecsElapsed(), (int)Event, (int)AnimationFrame,
+ QString(), -1, -1, fps, animCount, 0};
processMessage(ed);
}
}
int column; //used by RangeLocation
int framerate; //used by animation events
int animationcount; //used by animation events
+ int bindingType;
QByteArray toByteArray() const;
};
MaximumRangeType
};
+ enum BindingType {
+ QmlBinding,
+ V8Binding,
+ V4Binding,
+
+ MaximumBindingType
+ };
+
static void initialize();
static bool startProfiling();
void addEventImpl(EventType);
void animationFrameImpl(qint64);
- void startRange(RangeType);
+ void startRange(RangeType, BindingType bindingType = QmlBinding);
void rangeData(RangeType, const QString &);
void rangeData(RangeType, const QUrl &);
void rangeLocation(RangeType, const QString &, int, int);
//
struct QQmlBindingProfiler {
- QQmlBindingProfiler(const QString &url, int line, int column)
+ QQmlBindingProfiler(const QString &url, int line, int column, QQmlProfilerService::BindingType bindingType)
{
QQmlProfilerService *instance = QQmlProfilerService::instance;
enabled = instance ? instance->profilingEnabled() : false;
if (enabled) {
- instance->startRange(QQmlProfilerService::Binding);
+ instance->startRange(QQmlProfilerService::Binding, bindingType);
instance->rangeLocation(QQmlProfilerService::Binding, url, line, column);
}
}
trace.addDetail("Column", m_columnNumber);
if (!updatingFlag()) {
- QQmlBindingProfiler prof(m_url, m_lineNumber, m_columnNumber);
+ QQmlBindingProfiler prof(m_url, m_lineNumber, m_columnNumber, QQmlProfilerService::QmlBinding);
setUpdatingFlag(true);
QQmlAbstractExpression::DeleteWatcher watcher(this);
trace.addDetail("Line", binding->line);
trace.addDetail("Column", binding->column);
- QQmlBindingProfiler prof(context->urlString, binding->line, binding->column);
+ QQmlBindingProfiler prof(context->urlString, binding->line, binding->column, QQmlProfilerService::V4Binding);
if (binding->updating) {
QString name;
trace.addDetail("Line", instruction->line);
trace.addDetail("Column", instruction->column);
- QQmlBindingProfiler prof(parent->urlString(), instruction->line, instruction->column);
+ QQmlBindingProfiler prof(parent->urlString(), instruction->line, instruction->column, QQmlProfilerService::V8Binding);
if (!updatingFlag()) {
setUpdatingFlag(true);
connect(&m_qmlProfilerClient, SIGNAL(enabledChanged()), this, SLOT(traceClientEnabled()));
connect(&m_qmlProfilerClient, SIGNAL(recordingChanged(bool)), this, SLOT(recordingChanged()));
- connect(&m_qmlProfilerClient, SIGNAL(range(QQmlProfilerService::RangeType,qint64,qint64,QStringList,QmlEventLocation)),
- &m_profilerData, SLOT(addQmlEvent(QQmlProfilerService::RangeType,qint64,qint64,QStringList,QmlEventLocation)));
+ connect(&m_qmlProfilerClient, SIGNAL(range(QQmlProfilerService::RangeType,QQmlProfilerService::BindingType,qint64,qint64,QStringList,QmlEventLocation)),
+ &m_profilerData, SLOT(addQmlEvent(QQmlProfilerService::RangeType,QQmlProfilerService::BindingType,qint64,qint64,QStringList,QmlEventLocation)));
connect(&m_qmlProfilerClient, SIGNAL(traceFinished(qint64)), &m_profilerData, SLOT(setTraceEndTime(qint64)));
connect(&m_qmlProfilerClient, SIGNAL(traceStarted(qint64)), &m_profilerData, SLOT(setTraceStartTime(qint64)));
connect(&m_qmlProfilerClient, SIGNAL(frame(qint64,int,int)), &m_profilerData, SLOT(addFrameEvent(qint64,int,int)));
QStack<qint64> rangeStartTimes[QQmlProfilerService::MaximumRangeType];
QStack<QStringList> rangeDatas[QQmlProfilerService::MaximumRangeType];
QStack<QmlEventLocation> rangeLocations[QQmlProfilerService::MaximumRangeType];
+ QStack<QQmlProfilerService::BindingType> bindingTypes;
int rangeCount[QQmlProfilerService::MaximumRangeType];
qint64 maximumTime;
};
{
::memset(d->rangeCount, 0,
QQmlProfilerService::MaximumRangeType * sizeof(int));
+ d->bindingTypes.clear();
ProfilerClient::clearData();
}
d->rangeStartTimes[range].push(time);
d->inProgressRanges |= (static_cast<qint64>(1) << range);
++d->rangeCount[range];
+
+ // read binding type
+ if (range == (int)QQmlProfilerService::Binding) {
+ int bindingType = (int)QQmlProfilerService::QmlBinding;
+ if (!stream.atEnd())
+ stream >> bindingType;
+ d->bindingTypes.push((QQmlProfilerService::BindingType)bindingType);
+ }
} else if (messageType == QQmlProfilerService::RangeData) {
QString data;
stream >> data;
d->rangeLocations[range].pop() : QmlEventLocation();
qint64 startTime = d->rangeStartTimes[range].pop();
+ QQmlProfilerService::BindingType bindingType = QQmlProfilerService::QmlBinding;
+ if (range == (int)QQmlProfilerService::Binding)
+ bindingType = d->bindingTypes.pop();
emit this->range((QQmlProfilerService::RangeType)range,
- startTime, time - startTime, data, location);
+ bindingType, startTime, time - startTime, data, location);
if (d->rangeCount[range] == 0) {
int count = d->rangeDatas[range].count() +
d->rangeStartTimes[range].count() +
signals:
void traceFinished( qint64 time );
void traceStarted( qint64 time );
- void range(QQmlProfilerService::RangeType type, qint64 startTime,
- qint64 length, const QStringList &data,
+ void range(QQmlProfilerService::RangeType type,
+ QQmlProfilerService::BindingType bindingType,
+ qint64 startTime, qint64 length,
+ const QStringList &data,
const QmlEventLocation &location);
void frame(qint64 time, int frameRate, int animationCount);
struct QmlRangeEventData {
QmlRangeEventData() {} // never called
QmlRangeEventData(const QString &_displayName,
+ const QQmlProfilerService::BindingType &_bindingType,
const QString &_eventHashStr,
const QmlEventLocation &_location,
const QString &_details,
const QQmlProfilerService::RangeType &_eventType)
: displayName(_displayName),eventHashStr(_eventHashStr),location(_location),
- details(_details),eventType(_eventType) {}
+ details(_details),eventType(_eventType),bindingType(_bindingType) {}
QString displayName;
QString eventHashStr;
QmlEventLocation location;
QString details;
QQmlProfilerService::RangeType eventType;
+ QQmlProfilerService::BindingType bindingType;
};
struct QmlRangeEventStartInstance {
}
void QmlProfilerData::addQmlEvent(QQmlProfilerService::RangeType type,
+ QQmlProfilerService::BindingType bindingType,
qint64 startTime,
qint64 duration,
const QStringList &data,
if (d->eventDescriptions.contains(eventHashStr)) {
newEvent = d->eventDescriptions[eventHashStr];
} else {
- newEvent = new QmlRangeEventData(displayName, eventHashStr, location, details, type);
+ newEvent = new QmlRangeEventData(displayName, bindingType, eventHashStr, location, details, type);
d->eventDescriptions.insert(eventHashStr, newEvent);
}
if (d->eventDescriptions.contains(eventHashStr)) {
newEvent = d->eventDescriptions[eventHashStr];
} else {
- newEvent = new QmlRangeEventData(displayName, eventHashStr, QmlEventLocation(), details, QQmlProfilerService::Painting);
+ newEvent = new QmlRangeEventData(displayName, QQmlProfilerService::QmlBinding, eventHashStr, QmlEventLocation(), details, QQmlProfilerService::Painting);
d->eventDescriptions.insert(eventHashStr, newEvent);
}
stream.writeTextElement(QStringLiteral("column"), QString::number(eventData->location.column));
}
stream.writeTextElement(QStringLiteral("details"), eventData->details);
+ if (eventData->eventType == QQmlProfilerService::Binding)
+ stream.writeTextElement(QStringLiteral("bindingType"), QString::number((int)eventData->bindingType));
stream.writeEndElement();
}
stream.writeEndElement(); // eventData
void clear();
void setTraceEndTime(qint64 time);
void setTraceStartTime(qint64 time);
- void addQmlEvent(QQmlProfilerService::RangeType type, qint64 startTime, qint64 duration,
- const QStringList &data, const QmlEventLocation &location);
+ void addQmlEvent(QQmlProfilerService::RangeType type,
+ QQmlProfilerService::BindingType bindingType,
+ qint64 startTime, qint64 duration, const QStringList &data,
+ const QmlEventLocation &location);
void addV8Event(int depth, const QString &function, const QString &filename,
int lineNumber, double totalTime, double selfTime);
void addFrameEvent(qint64 time, int framerate, int animationcount);