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:
Eike Ziller
2017-03-28 09:56:16 +02:00
139 changed files with 1057 additions and 1111 deletions

View File

@@ -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()

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;