diff options
Diffstat (limited to 'src/plugins/perfprofiler')
27 files changed, 377 insertions, 253 deletions
diff --git a/src/plugins/perfprofiler/CMakeLists.txt b/src/plugins/perfprofiler/CMakeLists.txt new file mode 100644 index 0000000000..20345cb038 --- /dev/null +++ b/src/plugins/perfprofiler/CMakeLists.txt @@ -0,0 +1,41 @@ +add_qtc_plugin(PerfProfiler + DEPENDS Tracing Qt5::QuickWidgets + PLUGIN_DEPENDS Core Debugger ProjectExplorer QtSupport + SOURCES + perfconfigeventsmodel.cpp perfconfigeventsmodel.h + perfconfigwidget.cpp perfconfigwidget.h + perfconfigwidget.ui + perfdatareader.cpp perfdatareader.h + perfevent.h + perfeventtype.h + perfloaddialog.cpp perfloaddialog.h perfloaddialog.ui + perfoptionspage.cpp perfoptionspage.h + perfprofiler.qrc + perfprofilerconstants.h + perfprofilerflamegraphmodel.cpp perfprofilerflamegraphmodel.h + perfprofilerflamegraphview.cpp perfprofilerflamegraphview.h + perfprofilerplugin.cpp perfprofilerplugin.h + perfprofilerruncontrol.cpp perfprofilerruncontrol.h + perfprofilerstatisticsmodel.cpp perfprofilerstatisticsmodel.h + perfprofilerstatisticsview.cpp perfprofilerstatisticsview.h + perfprofilertool.cpp perfprofilertool.h + perfprofilertracefile.cpp perfprofilertracefile.h + perfprofilertracemanager.cpp perfprofilertracemanager.h + perfprofilertraceview.cpp perfprofilertraceview.h + perfprofiler_global.h + perfresourcecounter.cpp perfresourcecounter.h + perfrunconfigurationaspect.cpp perfrunconfigurationaspect.h + perfsettings.cpp perfsettings.h + perftimelinemodel.cpp perftimelinemodel.h + perftimelinemodelmanager.cpp perftimelinemodelmanager.h + perftimelineresourcesrenderpass.cpp perftimelineresourcesrenderpass.h + perftracepointdialog.cpp perftracepointdialog.h perftracepointdialog.ui +) + +extend_qtc_plugin(PerfProfiler + CONDITION WITH_TESTS + SOURCES + tests/perfprofilertracefile_test.cpp tests/perfprofilertracefile_test.h + tests/perfresourcecounter_test.cpp tests/perfresourcecounter_test.h + tests/tests.qrc +) diff --git a/src/plugins/perfprofiler/perfconfigwidget.cpp b/src/plugins/perfprofiler/perfconfigwidget.cpp index 356948bb86..1fe3acf58d 100644 --- a/src/plugins/perfprofiler/perfconfigwidget.cpp +++ b/src/plugins/perfprofiler/perfconfigwidget.cpp @@ -33,6 +33,7 @@ #include <projectexplorer/devicesupport/deviceprocess.h> #include <projectexplorer/kit.h> #include <projectexplorer/kitinformation.h> +#include <projectexplorer/runcontrol.h> #include <projectexplorer/target.h> #include <utils/qtcprocess.h> @@ -75,15 +76,14 @@ PerfConfigWidget::PerfConfigWidget(PerfSettings *settings, QWidget *parent) : m_ui->sampleMode->addItem(tr("frequency (Hz)"), QLatin1String(Constants::PerfSampleFrequency)); m_ui->sampleMode->addItem(tr("event count"), QLatin1String(Constants::PerfSampleCount)); - auto comboboxChangedSignal - = static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged); + auto comboboxChangedSignal = QOverload<int>::of(&QComboBox::currentIndexChanged); connect(m_ui->callgraphMode, comboboxChangedSignal, this, [this](int index) { QString mode = m_ui->callgraphMode->itemData(index).toString(); m_settings->setCallgraphMode(mode); m_ui->stackSize->setEnabled(mode == QLatin1String(Constants::PerfCallgraphDwarf)); }); - auto spinBoxChangedSignal = static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged); + auto spinBoxChangedSignal = QOverload<int>::of(&QSpinBox::valueChanged); connect(m_ui->stackSize, spinBoxChangedSignal, m_settings, &PerfSettings::setStackSize); connect(m_ui->period, spinBoxChangedSignal, m_settings, &PerfSettings::setPeriod); connect(m_ui->sampleMode, comboboxChangedSignal, this, [this](int index) { @@ -147,7 +147,7 @@ void PerfConfigWidget::setTarget(ProjectExplorer::Target *target) ProjectExplorer::IDevice::ConstPtr device; if (target) { if (ProjectExplorer::Kit *kit = target->kit()) - device = ProjectExplorer::DeviceKitInformation::device(kit); + device = ProjectExplorer::DeviceKitAspect::device(kit); } if (device.isNull()) { diff --git a/src/plugins/perfprofiler/perfdatareader.cpp b/src/plugins/perfprofiler/perfdatareader.cpp index 52afd696b8..86c80f382c 100644 --- a/src/plugins/perfprofiler/perfdatareader.cpp +++ b/src/plugins/perfprofiler/perfdatareader.cpp @@ -34,12 +34,15 @@ #include <coreplugin/messagemanager.h> #include <coreplugin/progressmanager/futureprogress.h> #include <coreplugin/progressmanager/progressmanager.h> + #include <projectexplorer/buildconfiguration.h> #include <projectexplorer/kitinformation.h> #include <projectexplorer/project.h> -#include <projectexplorer/runconfiguration.h> +#include <projectexplorer/runcontrol.h> #include <projectexplorer/session.h> +#include <projectexplorer/target.h> #include <projectexplorer/toolchain.h> + #include <qtsupport/qtkitinformation.h> #include <utils/qtcassert.h> @@ -64,7 +67,7 @@ PerfDataReader::PerfDataReader(QObject *parent) : m_remoteProcessStart(std::numeric_limits<qint64>::max()), m_lastRemoteTimestamp(0) { - connect(&m_input, static_cast<void (QProcess::*)(int)>(&QProcess::finished), + connect(&m_input, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, [this](int exitCode) { emit processFinished(); // process any remaining input before signaling finished() @@ -293,7 +296,7 @@ QStringList PerfDataReader::collectArguments(const QString &executableDirPath, if (!executableDirPath.isEmpty()) arguments << QLatin1String("--app") << executableDirPath; - if (QtSupport::BaseQtVersion *qt = QtSupport::QtKitInformation::qtVersion(kit)) { + if (QtSupport::BaseQtVersion *qt = QtSupport::QtKitAspect::qtVersion(kit)) { arguments << QLatin1String("--extra") << QString::fromLatin1("%1%5%2%5%3%5%4") .arg(QDir::toNativeSeparators(qt->libraryPath().toString())) .arg(QDir::toNativeSeparators(qt->pluginPath().toString())) @@ -302,7 +305,7 @@ QStringList PerfDataReader::collectArguments(const QString &executableDirPath, .arg(QDir::listSeparator()); } - if (auto toolChain = ProjectExplorer::ToolChainKitInformation::toolChain( + if (auto toolChain = ProjectExplorer::ToolChainKitAspect::toolChain( kit, ProjectExplorer::Constants::CXX_LANGUAGE_ID)) { ProjectExplorer::Abi::Architecture architecture = toolChain->targetAbi().architecture(); if (architecture == ProjectExplorer::Abi::ArmArchitecture && @@ -313,7 +316,7 @@ QStringList PerfDataReader::collectArguments(const QString &executableDirPath, } } - QString sysroot = ProjectExplorer::SysRootKitInformation::sysRoot(kit).toString(); + QString sysroot = ProjectExplorer::SysRootKitAspect::sysRoot(kit).toString(); if (!sysroot.isEmpty()) arguments << QLatin1String("--sysroot") << sysroot; @@ -392,11 +395,11 @@ bool PerfDataReader::feedParser(const QByteArray &input) return true; } -QStringList PerfDataReader::findTargetArguments(const ProjectExplorer::RunConfiguration *rc) const +QStringList PerfDataReader::findTargetArguments(const ProjectExplorer::RunControl *runControl) const { - ProjectExplorer::Kit *kit = rc->target()->kit(); + ProjectExplorer::Kit *kit = runControl->kit(); QTC_ASSERT(kit, return QStringList()); - ProjectExplorer::BuildConfiguration *buildConfig = rc->target()->activeBuildConfiguration(); + ProjectExplorer::BuildConfiguration *buildConfig = runControl->target()->activeBuildConfiguration(); QString buildDir = buildConfig ? buildConfig->buildDirectory().toString() : QString(); return collectArguments(buildDir, kit); } diff --git a/src/plugins/perfprofiler/perfdatareader.h b/src/plugins/perfprofiler/perfdatareader.h index 41cc96bdf4..2908c97914 100644 --- a/src/plugins/perfprofiler/perfdatareader.h +++ b/src/plugins/perfprofiler/perfdatareader.h @@ -28,13 +28,16 @@ #include "perfprofilertracefile.h" #include "perftimelinemodelmanager.h" -#include <projectexplorer/target.h> - #include <utils/temporaryfile.h> #include <QProcess> #include <QQueue> +namespace ProjectExplorer { +class Kit; +class RunControl; +} // ProjectExplorer + namespace PerfProfiler { namespace Internal { @@ -52,7 +55,7 @@ public: void startParser(); void stopParser(); - QStringList findTargetArguments(const ProjectExplorer::RunConfiguration *rc) const; + QStringList findTargetArguments(const ProjectExplorer::RunControl *runControl) const; void clear(); bool feedParser(const QByteArray &input); diff --git a/src/plugins/perfprofiler/perfevent.h b/src/plugins/perfprofiler/perfevent.h index 7fc7942645..dcee855e38 100644 --- a/src/plugins/perfprofiler/perfevent.h +++ b/src/plugins/perfprofiler/perfevent.h @@ -50,9 +50,14 @@ public: ThreadStartTypeId = -2, ThreadEndTypeId = -3, LostTypeId = -4, - LastSpecialTypeId = -5 + ContextSwitchTypeId = -5, + LastSpecialTypeId = -6 }; + int numAttributes() const { return m_values.length() + 1; } + qint32 attributeId(int i) const { return i == 0 ? typeIndex() : m_values[i - 1].first; } + quint64 attributeValue(int i) const { return i == 0 ? m_value : m_values[i - 1].second; } + const QVector<qint32> &origFrames() const { return m_origFrames; } quint8 origNumGuessedFrames() const { return m_origNumGuessedFrames; } @@ -67,25 +72,27 @@ public: quint8 numGuessedFrames() const { return m_numGuessedFrames; } void setNumGuessedFrames(quint8 numGuessedFrames) { m_numGuessedFrames = numGuessedFrames; } - quint64 period() const { return m_period; } - quint64 weight() const { return m_weight; } - quint8 feature() const { return m_feature; } + quint8 extra() const { return m_extra; } + void setExtra(quint8 extra) { m_extra = extra; } + private: friend QDataStream &operator>>(QDataStream &stream, PerfEvent &event); friend QDataStream &operator<<(QDataStream &stream, const PerfEvent &event); + QVector<QPair<qint32, quint64>> m_values; QVector<qint32> m_origFrames; QVector<qint32> m_frames; QHash<qint32, QVariant> m_traceData; quint32 m_pid = 0; quint32 m_tid = 0; - quint64 m_period = 0; - quint64 m_weight = 0; + quint64 m_value = 0; + quint32 m_cpu = 0; quint8 m_origNumGuessedFrames = 0; quint8 m_numGuessedFrames = 0; quint8 m_feature = PerfEventType::InvalidFeature; + quint8 m_extra = 0; }; inline QDataStream &operator>>(QDataStream &stream, PerfEvent &event) @@ -105,16 +112,16 @@ inline QDataStream &operator>>(QDataStream &stream, PerfEvent &event) case PerfEventType::ThreadStart: case PerfEventType::ThreadEnd: case PerfEventType::LostDefinition: - case PerfEventType::Sample43: case PerfEventType::Sample: case PerfEventType::TracePointSample: + case PerfEventType::ContextSwitchDefinition: break; case PerfEventType::InvalidFeature: QTC_ASSERT(false, return stream); } quint64 timestamp; - stream >> event.m_pid >> event.m_tid >> timestamp; + stream >> event.m_pid >> event.m_tid >> timestamp >> event.m_cpu; static const quint64 qint64Max = static_cast<quint64>(std::numeric_limits<qint64>::max()); event.setTimestamp(static_cast<qint64>(qMin(timestamp, qint64Max))); @@ -129,15 +136,30 @@ inline QDataStream &operator>>(QDataStream &stream, PerfEvent &event) case PerfEventType::LostDefinition: event.setTypeIndex(PerfEvent::LostTypeId); break; + case PerfEventType::ContextSwitchDefinition: + event.setTypeIndex(PerfEvent::ContextSwitchTypeId); + bool isSwitchOut; + stream >> isSwitchOut; + event.setExtra(isSwitchOut); + break; default: { - qint32 typeIndex; - stream >> event.m_origFrames >> event.m_origNumGuessedFrames >> typeIndex; - if (event.m_feature != PerfEventType::Sample43) { - stream >> event.m_period >> event.m_weight; - if (event.m_feature == PerfEventType::TracePointSample) - stream >> event.m_traceData; + qint32 firstAttributeId; + stream >> event.m_origFrames >> event.m_origNumGuessedFrames; + QVector<QPair<qint32, quint64>> values; + stream >> values; + if (values.isEmpty()) { + firstAttributeId = PerfEvent::LastSpecialTypeId; + } else { + firstAttributeId = PerfEvent::LastSpecialTypeId - values.first().first; + event.m_value = values.first().second; + for (auto it = values.constBegin() + 1, end = values.constEnd(); it != end; ++it) { + event.m_values.push_back({ PerfEvent::LastSpecialTypeId - it->first, + it->second }); + } } - event.setTypeIndex(PerfEvent::LastSpecialTypeId - typeIndex); + if (event.m_feature == PerfEventType::TracePointSample) + stream >> event.m_traceData; + event.setTypeIndex(firstAttributeId); } } @@ -148,23 +170,31 @@ inline QDataStream &operator<<(QDataStream &stream, const PerfEvent &event) { quint8 feature = event.feature(); stream << feature << event.m_pid << event.m_tid - << (event.timestamp() < 0ll ? 0ull : static_cast<quint64>(event.timestamp())); + << (event.timestamp() < 0ll ? 0ull : static_cast<quint64>(event.timestamp())) + << event.m_cpu; switch (feature) { case PerfEventType::ThreadStart: case PerfEventType::ThreadEnd: case PerfEventType::LostDefinition: break; - case PerfEventType::Sample43: + case PerfEventType::ContextSwitchDefinition: + stream << bool(event.extra()); + break; case PerfEventType::Sample: - case PerfEventType::TracePointSample: - stream << event.m_origFrames << event.m_origNumGuessedFrames - << static_cast<qint32>(PerfEvent::LastSpecialTypeId - event.typeIndex()); - if (feature != PerfEventType::Sample43) { - stream << event.m_period << event.m_weight; - if (feature == PerfEventType::TracePointSample) - stream << event.m_traceData; + case PerfEventType::TracePointSample: { + stream << event.m_origFrames << event.m_origNumGuessedFrames; + + QVector<QPair<qint32, quint64>> values; + for (int i = 0, end = event.numAttributes(); i < end; ++i) { + values.push_back({ PerfEvent::LastSpecialTypeId - event.attributeId(i), + event.attributeValue(i) }); } + stream << values; + + if (feature == PerfEventType::TracePointSample) + stream << event.m_traceData; break; + } default: QTC_CHECK(false); } diff --git a/src/plugins/perfprofiler/perfeventtype.h b/src/plugins/perfprofiler/perfeventtype.h index 2d8533edde..457b6afeb2 100644 --- a/src/plugins/perfprofiler/perfeventtype.h +++ b/src/plugins/perfprofiler/perfeventtype.h @@ -39,33 +39,33 @@ public: static const qint32 staticClassId = 0x70726674; // 'prft' enum Feature { - Sample43, // Only used until QtC/perfparser 4.3 ThreadStart, ThreadEnd, Command, LocationDefinition, SymbolDefinition, - AttributesDefinition, StringDefinition, LostDefinition, FeaturesDefinition, Error, - Sample, Progress, TracePointFormat, + AttributesDefinition, + ContextSwitchDefinition, + Sample, TracePointSample, InvalidFeature }; static quint64 attributeFeatures() { - return (1ull << Sample43) | (1ull << Sample) | (1ull << TracePointSample) - | (1ull << AttributesDefinition); + return (1ull << Sample) | (1ull << TracePointSample) | (1ull << AttributesDefinition); } static quint64 metaFeatures() { - return (1ull << ThreadStart) | (1ull << ThreadEnd) | (1ull << LostDefinition); + return (1ull << ThreadStart) | (1ull << ThreadEnd) | (1ull << LostDefinition) + | (1ull << ContextSwitchDefinition); } static quint64 locationFeatures() @@ -90,8 +90,10 @@ public: struct Attribute { quint64 config = std::numeric_limits<quint64>::max(); + quint64 frequencyOrPeriod = std::numeric_limits<quint64>::max(); quint32 type = std::numeric_limits<quint32>::max(); qint32 name = -1; + bool usesFrequency = false; }; struct Location { @@ -126,7 +128,6 @@ public: bool isAttribute() const { switch (feature()) { - case Sample43: case Sample: case AttributesDefinition: case TracePointSample: @@ -141,6 +142,8 @@ public: case ThreadStart: case ThreadEnd: case LostDefinition: + case ContextSwitchDefinition: + case InvalidFeature: return true; default: return false; @@ -178,12 +181,14 @@ private: inline QDataStream &operator>>(QDataStream &stream, PerfEventType::Attribute &attribute) { - return stream >> attribute.type >> attribute.config >> attribute.name; + return stream >> attribute.type >> attribute.config >> attribute.name + >> attribute.usesFrequency >> attribute.frequencyOrPeriod; } inline QDataStream &operator<<(QDataStream &stream, const PerfEventType::Attribute &attribute) { - return stream << attribute.type << attribute.config << attribute.name; + return stream << attribute.type << attribute.config << attribute.name + << attribute.usesFrequency << attribute.frequencyOrPeriod; } inline QDataStream &operator>>(QDataStream &stream, PerfEventType::Location &location) diff --git a/src/plugins/perfprofiler/perfoptionspage.cpp b/src/plugins/perfprofiler/perfoptionspage.cpp index 8b66475f77..356b073dd6 100644 --- a/src/plugins/perfprofiler/perfoptionspage.cpp +++ b/src/plugins/perfprofiler/perfoptionspage.cpp @@ -33,7 +33,7 @@ namespace PerfProfiler { namespace Internal { -PerfOptionsPage::PerfOptionsPage(QObject *parent) : Core::IOptionsPage(parent) +PerfOptionsPage::PerfOptionsPage() { setId(Constants::PerfSettingsId); setDisplayName(QCoreApplication::translate("PerfProfiler::PerfOptionsPage", "CPU Usage")); diff --git a/src/plugins/perfprofiler/perfoptionspage.h b/src/plugins/perfprofiler/perfoptionspage.h index 7f5da499e8..febde556e0 100644 --- a/src/plugins/perfprofiler/perfoptionspage.h +++ b/src/plugins/perfprofiler/perfoptionspage.h @@ -36,7 +36,7 @@ class PerfOptionsPage : public Core::IOptionsPage { Q_OBJECT public: - PerfOptionsPage(QObject *parent = nullptr); + PerfOptionsPage(); QWidget *widget(); void apply(); diff --git a/src/plugins/perfprofiler/perfprofilerconstants.h b/src/plugins/perfprofiler/perfprofilerconstants.h index b35ba28ec8..32e174cf5d 100644 --- a/src/plugins/perfprofiler/perfprofilerconstants.h +++ b/src/plugins/perfprofiler/perfprofilerconstants.h @@ -66,8 +66,7 @@ const char PerfSampleFrequency[] = "-F"; const char PerfSampleCount[] = "-c"; const char PerfStreamMagic[] = "QPERFSTREAM"; -const char PerfQzfileMagic[] = "QPERFQZFILE"; -const char PerfZqfileMagic[] = "QPERFZQFILE"; +const char PerfZqfileMagic[] = "PTQFILE4.10"; } // namespace Constants } // namespace PerfProfiler diff --git a/src/plugins/perfprofiler/perfprofilerflamegraphmodel.cpp b/src/plugins/perfprofiler/perfprofilerflamegraphmodel.cpp index 3a10ad67ae..79ebb32ba1 100644 --- a/src/plugins/perfprofiler/perfprofilerflamegraphmodel.cpp +++ b/src/plugins/perfprofiler/perfprofilerflamegraphmodel.cpp @@ -227,8 +227,12 @@ void PerfProfilerFlameGraphData::updateTraceData(const PerfEvent &event, const P PerfProfilerFlameGraphModel::Data *data, int numSamples) { - const PerfEventType::Attribute &attribute = type.attribute(); - if (attribute.type == PerfEventType::TypeTracepoint) { + Q_UNUSED(type); + for (int i = 0, end = event.numAttributes(); i < end; ++i) { + const PerfEventType::Attribute &attribute = manager->attribute(event.attributeId(i)); + if (attribute.type != PerfEventType::TypeTracepoint) + continue; + const PerfProfilerTraceManager::TracePoint &tracePoint = manager->tracePoint(static_cast<int>(attribute.config)); diff --git a/src/plugins/perfprofiler/perfprofilerplugin.cpp b/src/plugins/perfprofiler/perfprofilerplugin.cpp index a6fc393cab..26f2272204 100644 --- a/src/plugins/perfprofiler/perfprofilerplugin.cpp +++ b/src/plugins/perfprofiler/perfprofilerplugin.cpp @@ -52,32 +52,44 @@ #include <QAction> #include <QDebug> #include <QMenu> -#include <QtPlugin> using namespace ProjectExplorer; namespace PerfProfiler { +namespace Internal { Q_GLOBAL_STATIC(PerfSettings, perfGlobalSettings) -bool PerfProfilerPlugin::initialize(const QStringList &arguments, QString *errorString) +class PerfProfilerPluginPrivate { - Q_UNUSED(arguments) - Q_UNUSED(errorString) +public: + PerfProfilerPluginPrivate() + { + RunConfiguration::registerAspect<PerfRunConfigurationAspect>(); - (void) new Internal::PerfOptionsPage(this); + RunControl::registerWorkerCreator(ProjectExplorer::Constants::PERFPROFILER_RUN_MODE, + [](RunControl *runControl){ return new PerfProfilerRunner(runControl); }); - RunConfiguration::registerAspect<PerfRunConfigurationAspect>(); + auto constraint = [](RunConfiguration *) { return true; }; + RunControl::registerWorker<PerfProfilerRunner> + (ProjectExplorer::Constants::PERFPROFILER_RUN_MODE, constraint); + } - (void) new Internal::PerfProfilerTool(this); + PerfOptionsPage optionsPage; + PerfProfilerTool profilerTool; +}; - RunControl::registerWorkerCreator(ProjectExplorer::Constants::PERFPROFILER_RUN_MODE, - [](RunControl *runControl){ return new Internal::PerfProfilerRunner(runControl); }); +PerfProfilerPlugin::~PerfProfilerPlugin() +{ + delete d; +} - auto constraint = [](RunConfiguration *) { return true; }; - RunControl::registerWorker<Internal::PerfProfilerRunner> - (ProjectExplorer::Constants::PERFPROFILER_RUN_MODE, constraint); +bool PerfProfilerPlugin::initialize(const QStringList &arguments, QString *errorString) +{ + Q_UNUSED(arguments) + Q_UNUSED(errorString) + d = new PerfProfilerPluginPrivate; return true; } @@ -85,19 +97,20 @@ void PerfProfilerPlugin::extensionsInitialized() { } -PerfProfiler::PerfSettings *PerfProfilerPlugin::globalSettings() +PerfSettings *PerfProfilerPlugin::globalSettings() { return perfGlobalSettings(); } -QList<QObject *> PerfProfiler::PerfProfilerPlugin::createTestObjects() const +QVector<QObject *> PerfProfilerPlugin::createTestObjects() const { - QList<QObject *> tests; + QVector<QObject *> tests; #if WITH_TESTS - tests << new Internal::PerfProfilerTraceFileTest; - tests << new Internal::PerfResourceCounterTest; + tests << new PerfProfilerTraceFileTest; + tests << new PerfResourceCounterTest; #endif // WITH_TESTS return tests; } +} // namespace Internal } // namespace PerfProfiler diff --git a/src/plugins/perfprofiler/perfprofilerplugin.h b/src/plugins/perfprofiler/perfprofilerplugin.h index 35d79b099f..9f60f5fa32 100644 --- a/src/plugins/perfprofiler/perfprofilerplugin.h +++ b/src/plugins/perfprofiler/perfprofilerplugin.h @@ -30,6 +30,7 @@ #include <extensionsystem/iplugin.h> namespace PerfProfiler { +namespace Internal { class PerfProfilerPlugin : public ExtensionSystem::IPlugin { @@ -37,11 +38,16 @@ class PerfProfilerPlugin : public ExtensionSystem::IPlugin Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "PerfProfiler.json") public: + ~PerfProfilerPlugin(); + bool initialize(const QStringList &arguments, QString *errorString) final; void extensionsInitialized() final; - QList<QObject *> createTestObjects() const final; + QVector<QObject *> createTestObjects() const final; static PerfSettings *globalSettings(); + + class PerfProfilerPluginPrivate *d = nullptr; }; +} // namespace Internal } // namespace PerfProfiler diff --git a/src/plugins/perfprofiler/perfprofilerruncontrol.cpp b/src/plugins/perfprofiler/perfprofilerruncontrol.cpp index 50aa9696a1..6f521c306a 100644 --- a/src/plugins/perfprofiler/perfprofilerruncontrol.cpp +++ b/src/plugins/perfprofiler/perfprofilerruncontrol.cpp @@ -84,7 +84,7 @@ public: void start() override { - QStringList args = m_reader.findTargetArguments(runControl()->runConfiguration()); + QStringList args = m_reader.findTargetArguments(runControl()); QUrl url = runControl()->property("PerfConnection").toUrl(); if (url.isValid()) { args.append(QStringList{"--host", url.host(), "--port", QString::number(url.port())}); @@ -116,8 +116,7 @@ public: { setId("LocalPerfRecordWorker"); - auto runConfig = runControl->runConfiguration(); - auto perfAspect = static_cast<PerfRunConfigurationAspect *>(runConfig->aspect(Constants::PerfSettingsId)); + auto perfAspect = static_cast<PerfRunConfigurationAspect *>(runControl->aspect(Constants::PerfSettingsId)); QTC_ASSERT(perfAspect, return); PerfSettings *settings = static_cast<PerfSettings *>(perfAspect->currentSettings()); QTC_ASSERT(settings, return); diff --git a/src/plugins/perfprofiler/perfprofilerruncontrol.h b/src/plugins/perfprofiler/perfprofilerruncontrol.h index e9f434af9c..139fbac8ea 100644 --- a/src/plugins/perfprofiler/perfprofilerruncontrol.h +++ b/src/plugins/perfprofiler/perfprofilerruncontrol.h @@ -25,7 +25,7 @@ #pragma once -#include <projectexplorer/devicesupport/deviceprocess.h> +#include <projectexplorer/runcontrol.h> namespace PerfProfiler { namespace Internal { diff --git a/src/plugins/perfprofiler/perfprofilertool.cpp b/src/plugins/perfprofiler/perfprofilertool.cpp index 4feb8b0279..bb71f925da 100644 --- a/src/plugins/perfprofiler/perfprofilertool.cpp +++ b/src/plugins/perfprofiler/perfprofilertool.cpp @@ -69,8 +69,7 @@ namespace Internal { static PerfProfilerTool *s_instance; -PerfProfilerTool::PerfProfilerTool(QObject *parent) : - QObject(parent) +PerfProfilerTool::PerfProfilerTool() { s_instance = this; m_traceManager = new PerfProfilerTraceManager(this); @@ -158,6 +157,9 @@ PerfProfilerTool::PerfProfilerTool(QObject *parent) : tracePointsAction->setEnabled(m_startAction->isEnabled()); }); + connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::updateRunActions, + this, &PerfProfilerTool::updateRunActions); + m_recordButton = new QToolButton; m_clearButton = new QToolButton; m_filterButton = new QToolButton; @@ -342,9 +344,6 @@ void PerfProfilerTool::createViews() menu1->exec(m_flameGraphView->mapToGlobal(pos)); }); - connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::updateRunActions, - this, &PerfProfilerTool::updateRunActions); - m_perspective.addToolBarAction(m_startAction); m_perspective.addToolBarAction(m_stopAction); m_perspective.addToolBarWidget(m_recordButton); @@ -441,7 +440,7 @@ void PerfProfilerTool::onReaderStarted() void PerfProfilerTool::onWorkerCreation(RunControl *runControl) { - populateFileFinder(runControl->runConfiguration()); + populateFileFinder(runControl->project(), runControl->kit()); } void PerfProfilerTool::updateRunActions() @@ -541,7 +540,7 @@ void PerfProfilerTool::gotoSourceLocation(QString filePath, int lineNumber, int QFileInfo fi(filePath); if (!fi.isAbsolute() || !fi.exists() || !fi.isReadable()) { - fi.setFile(m_fileFinder.findFile(filePath)); + fi.setFile(m_fileFinder.findFile(filePath).first().toString()); if (!fi.exists() || !fi.isReadable()) return; } @@ -554,29 +553,29 @@ void PerfProfilerTool::gotoSourceLocation(QString filePath, int lineNumber, int } -static Utils::FileNameList collectQtIncludePaths(const ProjectExplorer::Kit *kit) +static Utils::FilePathList collectQtIncludePaths(const ProjectExplorer::Kit *kit) { - QtSupport::BaseQtVersion *qt = QtSupport::QtKitInformation::qtVersion(kit); + QtSupport::BaseQtVersion *qt = QtSupport::QtKitAspect::qtVersion(kit); if (qt == nullptr) - return Utils::FileNameList(); - Utils::FileNameList paths{qt->headerPath()}; + return Utils::FilePathList(); + Utils::FilePathList paths{qt->headerPath()}; QDirIterator dit(paths.first().toString(), QStringList(), QDir::Dirs | QDir::NoDotAndDotDot, QDirIterator::Subdirectories); while (dit.hasNext()) { dit.next(); - paths << Utils::FileName::fromString(dit.filePath()); + paths << Utils::FilePath::fromString(dit.filePath()); } return paths; } -static Utils::FileName sysroot(const Kit *kit) +static Utils::FilePath sysroot(const Kit *kit) { - return SysRootKitInformation::sysRoot(kit); + return SysRootKitAspect::sysRoot(kit); } -static Utils::FileNameList sourceFiles(const Project *currentProject = nullptr) +static Utils::FilePathList sourceFiles(const Project *currentProject = nullptr) { - Utils::FileNameList sourceFiles; + Utils::FilePathList sourceFiles; // Have the current project first. if (currentProject) @@ -614,12 +613,17 @@ void PerfProfilerTool::showLoadTraceDialog() QString filename = QFileDialog::getOpenFileName( ICore::mainWindow(), tr("Load Trace File"), - "", tr("Trace File (*.ptr)")); + "", tr("Trace File (*.ptq)")); if (filename.isEmpty()) return; startLoading(); - populateFileFinder(); + + const Project *currentProject = SessionManager::startupProject(); + const Target *target = currentProject ? currentProject->activeTarget() : nullptr; + const Kit *kit = target ? target->kit() : nullptr; + populateFileFinder(currentProject, kit); + m_traceManager->loadFromTraceFile(filename); } @@ -629,11 +633,11 @@ void PerfProfilerTool::showSaveTraceDialog() QString filename = QFileDialog::getSaveFileName( ICore::mainWindow(), tr("Save Trace File"), - "", tr("Trace File (*.ptr)")); + "", tr("Trace File (*.ptq)")); if (filename.isEmpty()) return; - if (!filename.endsWith(".ptr")) - filename += ".ptr"; + if (!filename.endsWith(".ptq")) + filename += ".ptq"; setToolActionsEnabled(false); m_traceManager->saveToTraceFile(filename); @@ -675,24 +679,12 @@ void PerfProfilerTool::updateTime(qint64 duration, qint64 delay) m_delayLabel->clear(); } -void PerfProfilerTool::populateFileFinder(const RunConfiguration *rc) +void PerfProfilerTool::populateFileFinder(const Project *project, const Kit *kit) { - const Project *currentProject = nullptr; - const Kit *kit = nullptr; - if (rc) { - if (const Target *target = rc->target()) { - kit = target->kit(); - currentProject = target->project(); - } - } else if ((currentProject = SessionManager::startupProject())) { - if (const Target *target = currentProject->activeTarget()) - kit = target->kit(); - } - - m_fileFinder.setProjectFiles(sourceFiles(currentProject)); + m_fileFinder.setProjectFiles(sourceFiles(project)); - if (currentProject) - m_fileFinder.setProjectDirectory(currentProject->projectDirectory()); + if (project) + m_fileFinder.setProjectDirectory(project->projectDirectory()); if (kit) { m_fileFinder.setAdditionalSearchDirectories(collectQtIncludePaths(kit)); diff --git a/src/plugins/perfprofiler/perfprofilertool.h b/src/plugins/perfprofiler/perfprofilertool.h index 7c0296b28d..8f36cfc7d0 100644 --- a/src/plugins/perfprofiler/perfprofilertool.h +++ b/src/plugins/perfprofiler/perfprofilertool.h @@ -48,7 +48,7 @@ class PerfProfilerTool : public QObject { Q_OBJECT public: - PerfProfilerTool(QObject *parent = nullptr); + PerfProfilerTool(); static PerfProfilerTool *instance(); PerfProfilerTraceManager *traceManager() const; @@ -88,7 +88,8 @@ private: void clear(); friend class PerfProfilerRunner; - void populateFileFinder(const ProjectExplorer::RunConfiguration *rc = nullptr); + void populateFileFinder(const ProjectExplorer::Project *project, + const ProjectExplorer::Kit *kit); void updateFilterMenu(); void updateRunActions(); void addLoadSaveActionsToMenu(QMenu *menu); diff --git a/src/plugins/perfprofiler/perfprofilertracefile.cpp b/src/plugins/perfprofiler/perfprofilertracefile.cpp index 7359e8f5d4..c6ea883c79 100644 --- a/src/plugins/perfprofiler/perfprofilertracefile.cpp +++ b/src/plugins/perfprofiler/perfprofilertracefile.cpp @@ -33,12 +33,11 @@ namespace PerfProfiler { namespace Internal { -Q_STATIC_ASSERT(sizeof(Constants::PerfStreamMagic) == sizeof(Constants::PerfQzfileMagic)); Q_STATIC_ASSERT(sizeof(Constants::PerfStreamMagic) == sizeof(Constants::PerfZqfileMagic)); PerfProfilerTraceFile::PerfProfilerTraceFile(QObject *parent) : Timeline::TimelineTraceFile(parent), m_messageSize(0), - m_dataStreamVersion(-1), m_compressed(false), m_mangledPackets(false) + m_dataStreamVersion(-1), m_compressed(false) { // This should result in either a direct or a queued connection, depending on where the signal // comes from. readMessages() should always run in the GUI thread. @@ -166,88 +165,91 @@ void PerfProfilerTraceFile::readMessages(const QByteArray &buffer) QDataStream dataStream(buffer); dataStream.setVersion(m_dataStreamVersion); - while (!dataStream.atEnd()) { - PerfEvent event; - dataStream >> event; - - const qint64 timestamp = event.timestamp(); - if (timestamp > 0) - event.setTimestamp(adjustTimestamp(timestamp)); - - qint32 id = -1; - switch (event.feature()) { - case PerfEventType::LocationDefinition: { - PerfEventType location(PerfEventType::LocationDefinition); - dataStream >> id >> location; - traceManager->setEventType(id, std::move(location)); - break; - } - case PerfEventType::SymbolDefinition: { - PerfProfilerTraceManager::Symbol symbol; - dataStream >> id >> symbol; - traceManager->setSymbol(id, symbol); - break; - } - case PerfEventType::AttributesDefinition: { - PerfEventType attributes(PerfEventType::AttributesDefinition); - dataStream >> id >> attributes; - traceManager->setEventType(PerfEvent::LastSpecialTypeId - id, std::move(attributes)); - break; - } - case PerfEventType::StringDefinition: { - QByteArray string; - dataStream >> id >> string; - traceManager->setString(id, string); - break; - } - case PerfEventType::FeaturesDefinition: { - PerfFeatures features; - dataStream >> features; - break; - } - case PerfEventType::Error: { - qint32 errorCode; - QString message; - dataStream >> errorCode >> message; - break; - } - case PerfEventType::Progress: { - float progress; - dataStream >> progress; - break; - } - case PerfEventType::TracePointFormat: { - PerfProfilerTraceManager::TracePoint tracePoint; - dataStream >> id >> tracePoint; - traceManager->setTracePoint(id, tracePoint); - break; - } - case PerfEventType::Command: { - PerfProfilerTraceManager::Thread thread; - dataStream >> thread; - traceManager->setThread(thread.tid, thread); - break; - } - case PerfEventType::ThreadStart: - case PerfEventType::ThreadEnd: - case PerfEventType::LostDefinition: - if (acceptsSamples()) - traceManager->appendEvent(std::move(event)); - break; - case PerfEventType::Sample43: - case PerfEventType::Sample: - case PerfEventType::TracePointSample: - if (acceptsSamples()) - traceManager->appendSampleEvent(std::move(event)); - break; - } - - if (!m_mangledPackets) { - if (!dataStream.atEnd()) - qWarning() << "Read only part of message"; - break; + PerfEvent event; + dataStream >> event; + + const qint64 timestamp = event.timestamp(); + if (timestamp > 0) + event.setTimestamp(adjustTimestamp(timestamp)); + + qint32 id = -1; + switch (event.feature()) { + case PerfEventType::LocationDefinition: { + PerfEventType location(PerfEventType::LocationDefinition); + dataStream >> id >> location; + for (int parent = location.location().parentLocationId; parent != -1; + parent = traceManager->location(parent).parentLocationId) { + if (parent == id) { + qWarning() << "A location cannot be its own parent location:" << id; + location = PerfEventType(PerfEventType::LocationDefinition); + break; + } } + traceManager->setEventType(id, std::move(location)); + break; + } + case PerfEventType::SymbolDefinition: { + PerfProfilerTraceManager::Symbol symbol; + dataStream >> id >> symbol; + traceManager->setSymbol(id, symbol); + break; + } + case PerfEventType::AttributesDefinition: { + PerfEventType attributes(PerfEventType::AttributesDefinition); + dataStream >> id >> attributes; + traceManager->setEventType(PerfEvent::LastSpecialTypeId - id, std::move(attributes)); + break; + } + case PerfEventType::StringDefinition: { + QByteArray string; + dataStream >> id >> string; + traceManager->setString(id, string); + break; + } + case PerfEventType::FeaturesDefinition: { + PerfFeatures features; + dataStream >> features; + break; + } + case PerfEventType::Error: { + qint32 errorCode; + QString message; + dataStream >> errorCode >> message; + break; } + case PerfEventType::Progress: { + float progress; + dataStream >> progress; + break; + } + case PerfEventType::TracePointFormat: { + PerfProfilerTraceManager::TracePoint tracePoint; + dataStream >> id >> tracePoint; + traceManager->setTracePoint(id, tracePoint); + break; + } + case PerfEventType::Command: { + PerfProfilerTraceManager::Thread thread; + dataStream >> thread; + traceManager->setThread(thread.tid, thread); + break; + } + case PerfEventType::ThreadStart: + case PerfEventType::ThreadEnd: + case PerfEventType::LostDefinition: + case PerfEventType::ContextSwitchDefinition: + if (acceptsSamples()) + traceManager->appendEvent(std::move(event)); + break; + case PerfEventType::Sample: + case PerfEventType::TracePointSample: + if (acceptsSamples()) + traceManager->appendSampleEvent(std::move(event)); + break; + } + + if (!dataStream.atEnd()) + qWarning() << "Read only part of message"; } void PerfProfilerTraceFile::readFromDevice() @@ -257,19 +259,18 @@ void PerfProfilerTraceFile::readFromDevice() if (m_device->bytesAvailable() < magicSize + static_cast<int>(sizeof(qint32))) return; - QVarLengthArray<char> magic(magicSize); + QByteArray magic(magicSize, 0); m_device->read(magic.data(), magicSize); if (strncmp(magic.data(), Constants::PerfStreamMagic, magicSize) == 0) { m_compressed = false; - m_mangledPackets = false; - } else if (strncmp(magic.data(), Constants::PerfQzfileMagic, magicSize) == 0) { - m_compressed = true; - m_mangledPackets = true; } else if (strncmp(magic.data(), Constants::PerfZqfileMagic, magicSize) == 0) { m_compressed = true; - m_mangledPackets = false; } else { - fail(tr("Invalid data format")); + fail(tr("Invalid data format. The trace file's identification string is \"%1\"." + "An acceptable trace file should have \"%2\". You cannot read trace files " + "generated with older versions of Qt Creator.") + .arg(QString::fromLatin1(magic)) + .arg(QString::fromLatin1(Constants::PerfZqfileMagic))); return; } @@ -278,7 +279,10 @@ void PerfProfilerTraceFile::readFromDevice() if (m_dataStreamVersion < 0 || m_dataStreamVersion > QDataStream::Qt_DefaultCompiledVersion) { - fail(tr("Invalid data format")); + fail(tr("Invalid data format. The trace file was written with data stream version %1. " + "We can read at most version %2. Please use a newer version of Qt.") + .arg(m_dataStreamVersion) + .arg(qint32(QDataStream::Qt_DefaultCompiledVersion))); return; } } @@ -296,8 +300,6 @@ void PerfProfilerTraceFile::readFromDevice() m_messageSize = 0; if (!m_compressed) emit messagesAvailable(buffer); - else if (m_mangledPackets) - emit messagesAvailable(qUncompress(buffer)); else emit blockAvailable(qUncompress(buffer)); diff --git a/src/plugins/perfprofiler/perfprofilertracefile.h b/src/plugins/perfprofiler/perfprofilertracefile.h index ac58cfe168..756ba2902d 100644 --- a/src/plugins/perfprofiler/perfprofilertracefile.h +++ b/src/plugins/perfprofiler/perfprofilertracefile.h @@ -71,7 +71,6 @@ protected: quint32 m_messageSize; qint32 m_dataStreamVersion; bool m_compressed; - bool m_mangledPackets; }; } // namespace Internal diff --git a/src/plugins/perfprofiler/perfprofilertracemanager.cpp b/src/plugins/perfprofiler/perfprofilertracemanager.cpp index 79bd1a05ad..75c31af32a 100644 --- a/src/plugins/perfprofiler/perfprofilertracemanager.cpp +++ b/src/plugins/perfprofiler/perfprofilertracemanager.cpp @@ -217,6 +217,10 @@ void PerfProfilerTraceManager::resetAttributes() tr("Thread ended"))); setEventType(PerfEvent::LostTypeId, PerfEventType(PerfEventType::LostDefinition, tr("Samples lost"))); + setEventType(PerfEvent::ContextSwitchTypeId, + PerfEventType(PerfEventType::ContextSwitchDefinition, tr("Context switch"))); + setEventType(PerfEvent::LastSpecialTypeId, + PerfEventType(PerfEventType::InvalidFeature, tr("Invalid"))); } void PerfProfilerTraceManager::finalize() @@ -279,7 +283,7 @@ void PerfProfilerTraceManager::replayPerfEvents(PerfEventLoader loader, Initiali QTC_ASSERT(traceEvent.is<PerfEvent>(), return false); PerfEvent &&event = traceEvent.asRvalueRef<PerfEvent>(); processSample(event); - loader(event, eventType(event.typeIndex())); + loader(event, eventType(event.attributeId(0))); return true; }); @@ -397,13 +401,13 @@ int PerfProfilerEventTypeStorage::append(Timeline::TraceEventType &&type) if (perfType.isLocation()) { const size_t index = m_locations.size(); m_locations.push_back(perfType); - QTC_ASSERT(index <= std::numeric_limits<int>::max(), + QTC_ASSERT(index <= size_t(std::numeric_limits<int>::max()), return std::numeric_limits<int>::max()); return static_cast<int>(index); } else if (perfType.isAttribute()) { const size_t index = m_attributes.size(); m_attributes.push_back(perfType); - QTC_ASSERT(index <= std::numeric_limits<int>::max(), + QTC_ASSERT(index <= size_t(std::numeric_limits<int>::max()), return -std::numeric_limits<int>::max()); return -static_cast<int>(index); } @@ -414,7 +418,8 @@ int PerfProfilerEventTypeStorage::append(Timeline::TraceEventType &&type) int PerfProfilerEventTypeStorage::size() const { const size_t result = m_attributes.size() + m_locations.size(); - QTC_ASSERT(result <= std::numeric_limits<int>::max(), return std::numeric_limits<int>::max()); + QTC_ASSERT(result <= size_t(std::numeric_limits<int>::max()), + return std::numeric_limits<int>::max()); return static_cast<int>(result); } diff --git a/src/plugins/perfprofiler/perfprofilertracemanager.h b/src/plugins/perfprofiler/perfprofilertracemanager.h index f663af3f3e..b35c6f1bd8 100644 --- a/src/plugins/perfprofiler/perfprofilertracemanager.h +++ b/src/plugins/perfprofiler/perfprofilertracemanager.h @@ -71,9 +71,9 @@ public: struct Thread { Thread(qint64 start = -1, qint64 firstEvent = -1, qint64 lastEvent = -1, quint32 pid = 0, - quint32 tid = 0, qint32 name = -1, bool enabled = false) : + quint32 tid = 0, quint32 cpu = 0, qint32 name = -1, bool enabled = false) : start(start), firstEvent(firstEvent), lastEvent(lastEvent), pid(pid), tid(tid), - name(name), enabled(enabled) + cpu(cpu), name(name), enabled(enabled) {} qint64 start; @@ -81,15 +81,17 @@ public: qint64 lastEvent; quint32 pid; quint32 tid; + quint32 cpu; qint32 name; bool enabled; }; struct Symbol { - Symbol() : name(-1), binary(-1), isKernel(false) {} + Symbol() : name(-1), binary(-1), path(-1), isKernel(false) {} qint32 name; qint32 binary; + qint32 path; bool isKernel; }; @@ -217,12 +219,12 @@ private: inline QDataStream &operator>>(QDataStream &stream, PerfProfilerTraceManager::Symbol &symbol) { - return stream >> symbol.name >> symbol.binary >> symbol.isKernel; + return stream >> symbol.name >> symbol.binary >> symbol.path >> symbol.isKernel; } inline QDataStream &operator<<(QDataStream &stream, const PerfProfilerTraceManager::Symbol &symbol) { - return stream << symbol.name << symbol.binary << symbol.isKernel; + return stream << symbol.name << symbol.binary << symbol.path << symbol.isKernel; } inline QDataStream &operator>>(QDataStream &stream, @@ -239,14 +241,14 @@ inline QDataStream &operator<<(QDataStream &stream, inline QDataStream &operator>>(QDataStream &stream, PerfProfilerTraceManager::Thread &thread) { - stream >> thread.pid >> thread.tid >> thread.start >> thread.name; + stream >> thread.pid >> thread.tid >> thread.start >> thread.cpu >> thread.name; thread.enabled = (thread.pid != 0); return stream; } inline QDataStream &operator<<(QDataStream &stream, const PerfProfilerTraceManager::Thread &thread) { - return stream << thread.pid << thread.tid << thread.start << thread.name; + return stream << thread.pid << thread.tid << thread.start << thread.cpu << thread.name; } diff --git a/src/plugins/perfprofiler/perfprofilertraceview.cpp b/src/plugins/perfprofiler/perfprofilertraceview.cpp index a55bdd4830..69ac873686 100644 --- a/src/plugins/perfprofiler/perfprofilertraceview.cpp +++ b/src/plugins/perfprofiler/perfprofilertraceview.cpp @@ -74,11 +74,7 @@ PerfProfilerTraceView::PerfProfilerTraceView(QWidget *parent, PerfProfilerTool * bool PerfProfilerTraceView::isUsable() const { -#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)) return quickWindow()->rendererInterface()->graphicsApi() == QSGRendererInterface::OpenGL; -#else - return true; -#endif } void PerfProfilerTraceView::selectByTypeId(int typeId) diff --git a/src/plugins/perfprofiler/perfresourcecounter.cpp b/src/plugins/perfprofiler/perfresourcecounter.cpp index e9935c334c..daae6be651 100644 --- a/src/plugins/perfprofiler/perfresourcecounter.cpp +++ b/src/plugins/perfprofiler/perfresourcecounter.cpp @@ -29,6 +29,5 @@ namespace PerfProfiler { namespace Internal { - } // namespace Internal } // namespace PerfProfiler diff --git a/src/plugins/perfprofiler/perfrunconfigurationaspect.cpp b/src/plugins/perfprofiler/perfrunconfigurationaspect.cpp index 498fd61b7b..03509751f1 100644 --- a/src/plugins/perfprofiler/perfrunconfigurationaspect.cpp +++ b/src/plugins/perfprofiler/perfrunconfigurationaspect.cpp @@ -35,7 +35,7 @@ namespace PerfProfiler { PerfRunConfigurationAspect::PerfRunConfigurationAspect(ProjectExplorer::Target *target) { setProjectSettings(new PerfSettings(target)); - setGlobalSettings(PerfProfilerPlugin::globalSettings()); + setGlobalSettings(Internal::PerfProfilerPlugin::globalSettings()); setId(Constants::PerfSettingsId); setDisplayName(QCoreApplication::translate("PerfProfiler::PerfRunConfigurationAspect", "Performance Analyzer Settings")); diff --git a/src/plugins/perfprofiler/perfsettings.h b/src/plugins/perfprofiler/perfsettings.h index 7ccfe5638d..85d506c9a5 100644 --- a/src/plugins/perfprofiler/perfsettings.h +++ b/src/plugins/perfprofiler/perfsettings.h @@ -40,7 +40,7 @@ class PERFPROFILER_EXPORT PerfSettings : public ProjectExplorer::ISettingsAspect public: explicit PerfSettings(ProjectExplorer::Target *target = nullptr); - ~PerfSettings(); + ~PerfSettings() final; void readGlobalSettings(); void writeGlobalSettings() const; @@ -66,8 +66,8 @@ signals: void changed(); protected: - void toMap(QVariantMap &map) const; - void fromMap(const QVariantMap &map); + void toMap(QVariantMap &map) const final; + void fromMap(const QVariantMap &map) final; int m_period; int m_stackSize; diff --git a/src/plugins/perfprofiler/perftimelinemodel.cpp b/src/plugins/perfprofiler/perftimelinemodel.cpp index c2a383161b..c16ff5d260 100644 --- a/src/plugins/perfprofiler/perftimelinemodel.cpp +++ b/src/plugins/perfprofiler/perftimelinemodel.cpp @@ -166,11 +166,12 @@ QVariantMap PerfTimelineModel::details(int index) const manager->traceDuration())); const int guessedFrames = -frame.numSamples; if (guessedFrames > 0) - result.insert(tr("Guessed"), tr("%1 frames").arg(guessedFrames)); - if (const int sampleWeight = weight(index)) - result.insert(tr("Weight"), sampleWeight); - if (const int samplePeriod = period(index)) - result.insert(tr("Period"), samplePeriod); + result.insert(tr("Guessed"), tr("%n frames", nullptr, guessedFrames)); + for (int i = 0, end = numAttributes(index); i < end; ++i) { + const auto &name = orUnknown(manager->string( + manager->attribute(attributeId(index, i)).name)); + result.insert(QString::fromUtf8(name), attributeValue(index, i)); + } if (attribute.type == PerfEventType::TypeTracepoint) { const PerfProfilerTraceManager::TracePoint &tracePoint = manager->tracePoint(static_cast<int>(attribute.config)); @@ -198,6 +199,10 @@ QVariantMap PerfTimelineModel::details(int index) const result.insert(tr("Details"), tr("lost sample")); result.insert(tr("Timestamp"), Timeline::formatTime(startTime(index), manager->traceDuration())); + } else if (typeId == PerfEvent::ContextSwitchTypeId) { + result.insert(tr("Details"), tr("context switch")); + result.insert(tr("Timestamp"), Timeline::formatTime(startTime(index), + manager->traceDuration())); } else { const PerfProfilerTraceManager::Symbol &symbol = manager->symbol(manager->aggregateAddresses() @@ -281,8 +286,11 @@ float PerfTimelineModel::relativeHeight(int index) const void PerfTimelineModel::updateTraceData(const PerfEvent &event) { const PerfProfilerTraceManager *manager = traceManager(); - const PerfEventType::Attribute &attribute = manager->attribute(event.typeIndex()); - if (attribute.type == PerfEventType::TypeTracepoint) { + for (int i = 0; i < event.numAttributes(); ++i) { + const PerfEventType::Attribute &attribute = manager->attribute(event.attributeId(i)); + if (attribute.type != PerfEventType::TypeTracepoint) + continue; + const PerfProfilerTraceManager::TracePoint &tracePoint = manager->tracePoint(static_cast<int>(attribute.config)); @@ -400,29 +408,30 @@ void PerfTimelineModel::updateFrames(const PerfEvent &event, int numConcurrentTh void PerfTimelineModel::addSample(const PerfEvent &event, qint64 resourceDelta, int resourceGuesses) { - static const int intMax = std::numeric_limits<int>::max(); - const int period = static_cast<int>(qMin(static_cast<quint64>(intMax), event.period())); - const int weight = static_cast<int>(qMin(static_cast<quint64>(intMax), event.weight())); - - const int id = TimelineModel::insert(event.timestamp(), 1, event.typeIndex()); + const int id = TimelineModel::insert(event.timestamp(), 1, event.attributeId(0)); StackFrame sample = StackFrame::sampleFrame(); + sample.attributeValue = event.attributeValue(0); sample.numSamples = event.numGuessedFrames() > 0 ? -event.numGuessedFrames() : 1; - sample.period = period; - sample.weight = weight; sample.resourcePeak = m_resourceBlocks.currentTotal(); sample.resourceDelta = resourceDelta; sample.resourceGuesses = resourceGuesses; + sample.numAttributes = event.numAttributes(); m_data.insert(id, std::move(sample)); const QHash<qint32, QVariant> &traceData = event.traceData(); if (!traceData.isEmpty()) m_extraData.insert(id, traceData); + for (int i = 1, end = sample.numAttributes; i < end; ++i) { + m_attributeValues[id].append(QPair<qint32, quint64>(event.attributeId(i), + event.attributeValue(i))); + } + m_lastTimestamp = event.timestamp(); } void PerfTimelineModel::loadEvent(const PerfEvent &event, int numConcurrentThreads) { - switch (event.typeIndex()) { + switch (event.attributeId(0)) { case PerfEvent::LostTypeId: { QVector<int> frames; for (int pos = m_currentStack.length() - 1; pos >= 0; --pos) @@ -438,6 +447,11 @@ void PerfTimelineModel::loadEvent(const PerfEvent &event, int numConcurrentThrea addSample(guessed, 0, 0); break; } + case PerfEvent::ContextSwitchTypeId: { + const int id = TimelineModel::insert(event.timestamp(), 1, PerfEvent::ContextSwitchTypeId); + m_data.insert(id, StackFrame::sampleFrame()); + break; + } case PerfEvent::ThreadStartTypeId: { if (m_threadStartTimestamp < 0 || event.timestamp() <= m_threadStartTimestamp) m_threadStartTimestamp = event.timestamp() - 1; @@ -459,7 +473,7 @@ void PerfTimelineModel::loadEvent(const PerfEvent &event, int numConcurrentThrea break; } default: { - QTC_ASSERT(event.typeIndex() <= PerfEvent::LastSpecialTypeId, break); + QTC_ASSERT(event.attributeId(0) <= PerfEvent::LastSpecialTypeId, break); if (event.timestamp() < 0) { updateTraceData(event); @@ -603,14 +617,19 @@ float PerfTimelineModel::resourceUsage(int index) const : 0.0f; } -int PerfTimelineModel::period(int index) const +qint32 PerfTimelineModel::attributeId(int index, int i) const +{ + return (i == 0) ? selectionId(index) : m_attributeValues[index][i].first; +} + +int PerfTimelineModel::numAttributes(int index) const { - return m_data[index].period; + return m_data[index].numAttributes; } -int PerfTimelineModel::weight(int index) const +quint64 PerfTimelineModel::attributeValue(int index, int i) const { - return m_data[index].weight; + return (i == 0) ? m_data[index].attributeValue : m_attributeValues[index][i].second; } bool PerfTimelineModel::handlesTypeId(int typeId) const diff --git a/src/plugins/perfprofiler/perftimelinemodel.h b/src/plugins/perfprofiler/perftimelinemodel.h index d6d5c88e99..a2ef90dc96 100644 --- a/src/plugins/perfprofiler/perftimelinemodel.h +++ b/src/plugins/perfprofiler/perftimelinemodel.h @@ -88,8 +88,9 @@ public: return selectionId(index) <= PerfEvent::LastSpecialTypeId; } - int period(int index) const; - int weight(int index) const; + int numAttributes(int index) const; + qint32 attributeId(int index, int i) const; + quint64 attributeValue(int index, int i) const; QHash<qint32, QVariant> extraData(int index) const { return m_extraData.value(index); } @@ -105,12 +106,12 @@ private: int numExpectedParallelSamples = 1; int displayRowCollapsed = MaximumSpecialRow; int displayRowExpanded = MaximumSpecialRow; - int period = 0; - int weight = 0; + quint64 attributeValue = 0; qint64 resourcePeak = 0; qint64 resourceDelta = 0; int resourceGuesses = 0; + int numAttributes = 0; static StackFrame sampleFrame() { @@ -150,6 +151,7 @@ private: QVector<StackFrame> m_data; QHash<int, QHash<qint32, QVariant>> m_extraData; + QHash<int, QVector<QPair<qint32, quint64>>> m_attributeValues; void computeExpandedLevels(); const PerfProfilerTraceManager *traceManager() const; diff --git a/src/plugins/perfprofiler/perftracepointdialog.cpp b/src/plugins/perfprofiler/perftracepointdialog.cpp index f4eef92c9b..5dc638bbbe 100644 --- a/src/plugins/perfprofiler/perftracepointdialog.cpp +++ b/src/plugins/perfprofiler/perftracepointdialog.cpp @@ -29,9 +29,13 @@ #include <projectexplorer/devicesupport/devicemanager.h> #include <projectexplorer/kitinformation.h> #include <projectexplorer/project.h> +#include <projectexplorer/projectexplorerconstants.h> +#include <projectexplorer/runcontrol.h> #include <projectexplorer/session.h> #include <projectexplorer/target.h> +#include <utils/qtcassert.h> + #include <QVBoxLayout> #include <QHBoxLayout> #include <QPushButton> @@ -52,7 +56,7 @@ PerfTracePointDialog::PerfTracePointDialog() : const Kit *kit = target->kit(); QTC_ASSERT(kit, return); - m_device = DeviceKitInformation::device(kit); + m_device = DeviceKitAspect::device(kit); if (!m_device) { m_ui->textEdit->setPlainText(tr("Error: No device available for active target.")); return; |