forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/4.3'
Conflicts: src/plugins/genericprojectmanager/genericproject.cpp src/plugins/genericprojectmanager/genericproject.h src/plugins/projectexplorer/projectmodels.cpp Change-Id: I290cba328212cadd3c12909d1f2f3642d326a1ca
This commit is contained in:
@@ -106,6 +106,7 @@ void FlameGraphModel::loadEvent(const QmlEvent &event, const QmlEventType &type)
|
||||
const bool isCompiling = (type.rangeType() == Compiling);
|
||||
QStack<QmlEvent> &stack = isCompiling ? m_compileStack : m_callStack;
|
||||
FlameGraphData *&stackTop = isCompiling ? m_compileStackTop : m_callStackTop;
|
||||
QTC_ASSERT(stackTop, return);
|
||||
|
||||
if (type.message() == MemoryAllocation) {
|
||||
if (type.detailType() == HeapPage)
|
||||
@@ -121,6 +122,8 @@ void FlameGraphModel::loadEvent(const QmlEvent &event, const QmlEventType &type)
|
||||
}
|
||||
|
||||
} else if (event.rangeStage() == RangeEnd) {
|
||||
QTC_ASSERT(stackTop != &m_stackBottom, return);
|
||||
QTC_ASSERT(stackTop->typeIndex == event.typeIndex(), return);
|
||||
stackTop->duration += event.timestamp() - stack.top().timestamp();
|
||||
stack.pop();
|
||||
stackTop = stackTop->parent;
|
||||
@@ -129,6 +132,7 @@ void FlameGraphModel::loadEvent(const QmlEvent &event, const QmlEventType &type)
|
||||
stack.push(event);
|
||||
stackTop = pushChild(stackTop, event);
|
||||
}
|
||||
QTC_CHECK(stackTop);
|
||||
}
|
||||
|
||||
void FlameGraphModel::finalize()
|
||||
|
||||
@@ -135,12 +135,14 @@ void MemoryUsageModel::loadEvent(const QmlEvent &event, const QmlEventType &type
|
||||
{
|
||||
if (type.message() != MemoryAllocation) {
|
||||
if (type.rangeType() != MaximumRangeType) {
|
||||
m_continuation = ContinueNothing;
|
||||
if (event.rangeStage() == RangeStart)
|
||||
m_rangeStack.push(RangeStackFrame(event.typeIndex(), event.timestamp()));
|
||||
else if (event.rangeStage() == RangeEnd)
|
||||
else if (event.rangeStage() == RangeEnd) {
|
||||
QTC_ASSERT(!m_rangeStack.isEmpty(), return);
|
||||
QTC_ASSERT(m_rangeStack.top().originTypeIndex == event.typeIndex(), return);
|
||||
m_rangeStack.pop();
|
||||
|
||||
m_continuation = ContinueNothing;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -225,7 +225,8 @@ void QmlProfilerStatisticsModel::loadEvent(const QmlEvent &event, const QmlEvent
|
||||
break;
|
||||
case RangeEnd: {
|
||||
// update stats
|
||||
|
||||
QTC_ASSERT(!stack.isEmpty(), return);
|
||||
QTC_ASSERT(stack.top().typeIndex() == event.typeIndex(), return);
|
||||
QmlEventStats *stats = &d->data[event.typeIndex()];
|
||||
qint64 duration = event.timestamp() - stack.top().timestamp();
|
||||
stats->duration += duration;
|
||||
|
||||
@@ -416,10 +416,77 @@ void QmlProfilerFileReader::loadEventTypes(QXmlStreamReader &stream)
|
||||
}
|
||||
}
|
||||
|
||||
class EventList
|
||||
{
|
||||
public:
|
||||
void addEvent(const QmlEvent &event);
|
||||
void addRange(const QmlEvent &start, const QmlEvent &end);
|
||||
|
||||
QVector<QmlEvent> finalize();
|
||||
|
||||
private:
|
||||
struct QmlRange {
|
||||
QmlEvent begin;
|
||||
QmlEvent end;
|
||||
};
|
||||
|
||||
QList<QmlRange> ranges; // We are going to do a lot of takeFirst() on this.
|
||||
};
|
||||
|
||||
void EventList::addEvent(const QmlEvent &event)
|
||||
{
|
||||
ranges.append({event, QmlEvent()});
|
||||
}
|
||||
|
||||
void EventList::addRange(const QmlEvent &start, const QmlEvent &end)
|
||||
{
|
||||
ranges.append({start, end});
|
||||
}
|
||||
|
||||
QVector<QmlEvent> EventList::finalize()
|
||||
{
|
||||
std::sort(ranges.begin(), ranges.end(), [](const QmlRange &a, const QmlRange &b) {
|
||||
if (a.begin.timestamp() < b.begin.timestamp())
|
||||
return true;
|
||||
if (a.begin.timestamp() > b.begin.timestamp())
|
||||
return false;
|
||||
|
||||
// If the start times are equal. Sort the one with the greater end time first, so that
|
||||
// the nesting is retained.
|
||||
return (a.end.timestamp() > b.end.timestamp());
|
||||
});
|
||||
|
||||
QList<QmlEvent> ends;
|
||||
QVector<QmlEvent> result;
|
||||
while (!ranges.isEmpty()) {
|
||||
// This is more expensive than just iterating, but we don't want to double the already
|
||||
// high memory footprint.
|
||||
QmlRange range = ranges.takeFirst();
|
||||
while (!ends.isEmpty() && ends.last().timestamp() <= range.begin.timestamp())
|
||||
result.append(ends.takeLast());
|
||||
|
||||
result.append(range.begin);
|
||||
if (range.end.isValid()) {
|
||||
auto it = ends.end();
|
||||
for (auto begin = ends.begin(); it != begin;) {
|
||||
if ((--it)->timestamp() >= range.end.timestamp()) {
|
||||
++it;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ends.insert(it, range.end);
|
||||
}
|
||||
}
|
||||
while (!ends.isEmpty())
|
||||
result.append(ends.takeLast());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void QmlProfilerFileReader::loadEvents(QXmlStreamReader &stream)
|
||||
{
|
||||
QTC_ASSERT(stream.name() == _("profilerDataModel"), return);
|
||||
QVector<QmlEvent> events;
|
||||
EventList events;
|
||||
|
||||
while (!stream.atEnd() && !stream.hasError() && !isCanceled()) {
|
||||
|
||||
@@ -444,12 +511,11 @@ void QmlProfilerFileReader::loadEvents(QXmlStreamReader &stream)
|
||||
|
||||
if (attributes.hasAttribute(_("duration"))) {
|
||||
event.setRangeStage(RangeStart);
|
||||
events.append(event);
|
||||
QmlEvent rangeEnd(event);
|
||||
rangeEnd.setRangeStage(RangeEnd);
|
||||
rangeEnd.setTimestamp(event.timestamp()
|
||||
+ attributes.value(_("duration")).toLongLong());
|
||||
events.append(rangeEnd);
|
||||
events.addRange(event, rangeEnd);
|
||||
} else {
|
||||
// attributes for special events
|
||||
if (attributes.hasAttribute(_("framerate")))
|
||||
@@ -485,7 +551,7 @@ void QmlProfilerFileReader::loadEvents(QXmlStreamReader &stream)
|
||||
if (attributes.hasAttribute(_("text")))
|
||||
event.setString(attributes.value(_("text")).toString());
|
||||
|
||||
events.append(event);
|
||||
events.addEvent(event);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -493,10 +559,7 @@ void QmlProfilerFileReader::loadEvents(QXmlStreamReader &stream)
|
||||
case QXmlStreamReader::EndElement: {
|
||||
if (elementName == _("profilerDataModel")) {
|
||||
// done reading profilerDataModel
|
||||
std::sort(events.begin(), events.end(), [](const QmlEvent &a, const QmlEvent &b) {
|
||||
return a.timestamp() < b.timestamp();
|
||||
});
|
||||
emit qmlEventsLoaded(events);
|
||||
emit qmlEventsLoaded(events.finalize());
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user