forked from qt-creator/qt-creator
Perf: Partially aspectify settings
Change-Id: I605bfcd94e95cce753f42528586829072aea5663 Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -5,7 +5,6 @@ add_qtc_plugin(PerfProfiler
|
||||
SOURCES
|
||||
perfconfigeventsmodel.cpp perfconfigeventsmodel.h
|
||||
perfconfigwidget.cpp perfconfigwidget.h
|
||||
perfconfigwidget.ui
|
||||
perfdatareader.cpp perfdatareader.h
|
||||
perfevent.h
|
||||
perfeventtype.h
|
||||
|
||||
@@ -40,7 +40,7 @@ PerfConfigEventsModel::PerfConfigEventsModel(PerfSettings *settings, QObject *pa
|
||||
|
||||
int PerfConfigEventsModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
return parent.isValid() ? 0 : m_settings->events().length();
|
||||
return parent.isValid() ? 0 : m_settings->events.value().length();
|
||||
}
|
||||
|
||||
int PerfConfigEventsModel::columnCount(const QModelIndex &parent) const
|
||||
@@ -58,7 +58,7 @@ QVariant PerfConfigEventsModel::data(const QModelIndex &index, int role) const
|
||||
return QVariant(); // ignore
|
||||
}
|
||||
|
||||
QString event = m_settings->events().value(index.row());
|
||||
QString event = m_settings->events.value().value(index.row());
|
||||
const EventDescription description = parseEvent(event);
|
||||
switch (index.column()) {
|
||||
case ColumnEventType: {
|
||||
@@ -142,7 +142,7 @@ bool PerfConfigEventsModel::setData(const QModelIndex &dataIndex, const QVariant
|
||||
const int row = dataIndex.row();
|
||||
const int column = dataIndex.column();
|
||||
|
||||
QStringList events = m_settings->events();
|
||||
QStringList events = m_settings->events.value();
|
||||
EventDescription description = parseEvent(events[row]);
|
||||
switch (column) {
|
||||
case ColumnEventType:
|
||||
@@ -176,7 +176,7 @@ bool PerfConfigEventsModel::setData(const QModelIndex &dataIndex, const QVariant
|
||||
break;
|
||||
}
|
||||
events[row] = generateEvent(description);
|
||||
m_settings->setEvents(events);
|
||||
m_settings->events.setValue(events);
|
||||
emit dataChanged(index(row, ColumnEventType), index(row, ColumnResult));
|
||||
return true;
|
||||
}
|
||||
@@ -201,11 +201,11 @@ bool PerfConfigEventsModel::insertRows(int row, int count, const QModelIndex &pa
|
||||
if (parent.isValid())
|
||||
return false;
|
||||
|
||||
QStringList events = m_settings->events();
|
||||
QStringList events = m_settings->events.value();
|
||||
for (int i = 0; i < count; ++i)
|
||||
events.insert(row, "dummy");
|
||||
beginInsertRows(parent, row, row + count - 1);
|
||||
m_settings->setEvents(events);
|
||||
m_settings->events.setValue(events);
|
||||
endInsertRows();
|
||||
return true;
|
||||
}
|
||||
@@ -215,17 +215,17 @@ bool PerfConfigEventsModel::removeRows(int row, int count, const QModelIndex &pa
|
||||
if (parent.isValid())
|
||||
return false;
|
||||
|
||||
QStringList events = m_settings->events();
|
||||
QStringList events = m_settings->events.value();
|
||||
for (int i = 0; i < count; ++i)
|
||||
events.removeAt(row);
|
||||
beginRemoveRows(parent, row, row + count - 1);
|
||||
m_settings->setEvents(events);
|
||||
m_settings->events.setValue(events);
|
||||
endRemoveRows();
|
||||
|
||||
if (events.isEmpty()) {
|
||||
beginInsertRows(parent, 0, 0);
|
||||
events.append("dummy");
|
||||
m_settings->setEvents(events);
|
||||
m_settings->events.setValue(events);
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
|
||||
@@ -36,11 +36,17 @@
|
||||
#include <projectexplorer/runcontrol.h>
|
||||
#include <projectexplorer/target.h>
|
||||
|
||||
#include <utils/aspects.h>
|
||||
#include <utils/layoutbuilder.h>
|
||||
#include <utils/qtcprocess.h>
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QHeaderView>
|
||||
#include <QMessageBox>
|
||||
#include <QMetaEnum>
|
||||
#include <QStyledItemDelegate>
|
||||
#include <QMessageBox>
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
namespace PerfProfiler {
|
||||
namespace Internal {
|
||||
@@ -63,85 +69,61 @@ public:
|
||||
};
|
||||
|
||||
PerfConfigWidget::PerfConfigWidget(PerfSettings *settings, QWidget *parent)
|
||||
: m_settings(settings), m_ui(new Ui::PerfConfigWidget)
|
||||
: m_settings(settings)
|
||||
{
|
||||
setParent(parent);
|
||||
|
||||
m_ui->setupUi(this);
|
||||
m_ui->useTracePointsButton->setVisible(false);
|
||||
eventsView = new QTableView(this);
|
||||
eventsView->setMinimumSize(QSize(0, 300));
|
||||
eventsView->setEditTriggers(QAbstractItemView::AllEditTriggers);
|
||||
eventsView->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
eventsView->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
eventsView->setModel(new PerfConfigEventsModel(m_settings, this));
|
||||
eventsView->setItemDelegate(new SettingsDelegate(this));
|
||||
eventsView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
|
||||
|
||||
m_ui->callgraphMode->addItem(tr("dwarf"), QLatin1String(Constants::PerfCallgraphDwarf));
|
||||
m_ui->callgraphMode->addItem(tr("frame pointer"), QLatin1String(Constants::PerfCallgraphFP));
|
||||
m_ui->callgraphMode->addItem(tr("last branch record"),
|
||||
QLatin1String(Constants::PerfCallgraphLBR));
|
||||
useTracePointsButton = new QPushButton(this);
|
||||
useTracePointsButton->setText(tr("Use Trace Points"));
|
||||
useTracePointsButton->setVisible(false);
|
||||
connect(useTracePointsButton, &QPushButton::pressed,
|
||||
this, &PerfConfigWidget::readTracePoints);
|
||||
|
||||
m_ui->sampleMode->addItem(tr("frequency (Hz)"), QLatin1String(Constants::PerfSampleFrequency));
|
||||
m_ui->sampleMode->addItem(tr("event count"), QLatin1String(Constants::PerfSampleCount));
|
||||
|
||||
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 = 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) {
|
||||
QString sampleMode = m_ui->sampleMode->itemData(index).toString();
|
||||
m_settings->setSampleMode(sampleMode);
|
||||
});
|
||||
connect(m_ui->extraArguments, &QLineEdit::textEdited, this, [this](const QString &text) {
|
||||
m_settings->setExtraArguments(Utils::QtcProcess::splitArgs(text));
|
||||
});
|
||||
|
||||
m_ui->eventsView->setModel(new PerfConfigEventsModel(m_settings, this));
|
||||
m_ui->eventsView->setItemDelegate(new SettingsDelegate(this));
|
||||
m_ui->eventsView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
|
||||
connect(m_ui->addEventButton, &QPushButton::pressed, this, [this]() {
|
||||
auto model = m_ui->eventsView->model();
|
||||
addEventButton = new QPushButton(this);
|
||||
addEventButton->setText(tr("Add Event"));
|
||||
connect(addEventButton, &QPushButton::pressed, this, [this]() {
|
||||
auto model = eventsView->model();
|
||||
model->insertRow(model->rowCount());
|
||||
});
|
||||
connect(m_ui->removeEventButton, &QPushButton::pressed, this, [this]() {
|
||||
QModelIndex index = m_ui->eventsView->currentIndex();
|
||||
|
||||
removeEventButton = new QPushButton(this);
|
||||
removeEventButton->setText(tr("Remove Event"));
|
||||
connect(removeEventButton, &QPushButton::pressed, this, [this]() {
|
||||
QModelIndex index = eventsView->currentIndex();
|
||||
if (index.isValid())
|
||||
m_ui->eventsView->model()->removeRow(index.row());
|
||||
eventsView->model()->removeRow(index.row());
|
||||
});
|
||||
|
||||
connect(m_settings, &PerfSettings::changed, this, &PerfConfigWidget::updateUi);
|
||||
connect(m_ui->useTracePointsButton, &QPushButton::pressed,
|
||||
this, &PerfConfigWidget::readTracePoints);
|
||||
connect(m_ui->resetButton, &QPushButton::pressed, m_settings, &PerfSettings::resetToDefault);
|
||||
updateUi();
|
||||
}
|
||||
resetButton = new QPushButton(this);
|
||||
resetButton->setText(tr("Reset"));
|
||||
connect(resetButton, &QPushButton::pressed, m_settings, &PerfSettings::resetToDefault);
|
||||
|
||||
PerfConfigWidget::~PerfConfigWidget()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
using namespace Layouting;
|
||||
const Break nl;
|
||||
|
||||
void PerfConfigWidget::updateUi()
|
||||
{
|
||||
for (int index = 0, end = m_ui->callgraphMode->count(); index != end; ++index) {
|
||||
if (m_ui->callgraphMode->itemData(index) == m_settings->callgraphMode()) {
|
||||
m_ui->callgraphMode->setCurrentIndex(index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Column {
|
||||
Row { Stretch(), useTracePointsButton, addEventButton, removeEventButton, resetButton },
|
||||
|
||||
for (int index = 0, end = m_ui->sampleMode->count(); index != end; ++index) {
|
||||
if (m_ui->sampleMode->itemData(index) == m_settings->sampleMode()) {
|
||||
m_ui->sampleMode->setCurrentIndex(index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
eventsView,
|
||||
|
||||
m_ui->stackSize->setEnabled(m_settings->callgraphMode()
|
||||
== QLatin1String(Constants::PerfCallgraphDwarf));
|
||||
m_ui->stackSize->setValue(m_settings->stackSize());
|
||||
m_ui->period->setValue(m_settings->period());
|
||||
m_ui->extraArguments->setText(m_settings->extraArguments().join(QLatin1Char(' ')));
|
||||
Grid {
|
||||
m_settings->callgraphMode, m_settings->stackSize, nl,
|
||||
m_settings->sampleMode, m_settings->period, nl,
|
||||
},
|
||||
|
||||
Row { m_settings->extraArguments }, // FIXME: Align with above.
|
||||
|
||||
Stretch()
|
||||
}.attachTo(this);
|
||||
}
|
||||
|
||||
void PerfConfigWidget::setTarget(ProjectExplorer::Target *target)
|
||||
@@ -153,7 +135,7 @@ void PerfConfigWidget::setTarget(ProjectExplorer::Target *target)
|
||||
}
|
||||
|
||||
if (device.isNull()) {
|
||||
m_ui->useTracePointsButton->setEnabled(false);
|
||||
useTracePointsButton->setEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -162,7 +144,7 @@ void PerfConfigWidget::setTarget(ProjectExplorer::Target *target)
|
||||
|
||||
m_process.reset(device->createProcess(nullptr));
|
||||
if (!m_process) {
|
||||
m_ui->useTracePointsButton->setEnabled(false);
|
||||
useTracePointsButton->setEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -172,12 +154,12 @@ void PerfConfigWidget::setTarget(ProjectExplorer::Target *target)
|
||||
connect(m_process.get(), &ProjectExplorer::DeviceProcess::error,
|
||||
this, &PerfConfigWidget::handleProcessError);
|
||||
|
||||
m_ui->useTracePointsButton->setEnabled(true);
|
||||
useTracePointsButton->setEnabled(true);
|
||||
}
|
||||
|
||||
void PerfConfigWidget::setTracePointsButtonVisible(bool visible)
|
||||
{
|
||||
m_ui->useTracePointsButton->setVisible(visible);
|
||||
useTracePointsButton->setVisible(visible);
|
||||
}
|
||||
|
||||
void PerfConfigWidget::apply()
|
||||
@@ -198,7 +180,7 @@ void PerfConfigWidget::readTracePoints()
|
||||
runnable.commandLineArguments = QLatin1String("probe -l");
|
||||
|
||||
m_process->start(runnable);
|
||||
m_ui->useTracePointsButton->setEnabled(false);
|
||||
useTracePointsButton->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,7 +189,7 @@ void PerfConfigWidget::handleProcessFinished()
|
||||
const QList<QByteArray> lines =
|
||||
m_process->readAllStandardOutput().append(m_process->readAllStandardError())
|
||||
.split('\n');
|
||||
auto model = m_ui->eventsView->model();
|
||||
auto model = eventsView->model();
|
||||
const int previousRows = model->rowCount();
|
||||
QHash<QByteArray, QByteArray> tracePoints;
|
||||
for (const QByteArray &line : lines) {
|
||||
@@ -234,10 +216,10 @@ void PerfConfigWidget::handleProcessFinished()
|
||||
QString::fromUtf8(event));
|
||||
}
|
||||
model->removeRows(0, previousRows);
|
||||
m_ui->sampleMode->setCurrentText(tr("event count"));
|
||||
m_ui->period->setValue(1);
|
||||
m_settings->sampleMode.setVolatileValue(1);
|
||||
m_settings->period.setVolatileValue(1);
|
||||
}
|
||||
m_ui->useTracePointsButton->setEnabled(true);
|
||||
useTracePointsButton->setEnabled(true);
|
||||
}
|
||||
|
||||
void PerfConfigWidget::handleProcessError(QProcess::ProcessError error)
|
||||
@@ -246,7 +228,7 @@ void PerfConfigWidget::handleProcessError(QProcess::ProcessError error)
|
||||
Core::AsynchronousMessageBox::warning(
|
||||
tr("Cannot List Trace Points"),
|
||||
tr("\"perf probe -l\" failed to start. Is perf installed?"));
|
||||
m_ui->useTracePointsButton->setEnabled(true);
|
||||
useTracePointsButton->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,17 +29,19 @@
|
||||
|
||||
#include <coreplugin/dialogs/ioptionspage.h>
|
||||
|
||||
#include <projectexplorer/devicesupport/deviceprocess.h>
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QTableView>
|
||||
|
||||
namespace PerfProfiler {
|
||||
namespace Internal {
|
||||
|
||||
namespace Ui { class PerfConfigWidget; }
|
||||
|
||||
class PerfConfigWidget : public Core::IOptionsPageWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PerfConfigWidget(PerfSettings *settings, QWidget *parent = nullptr);
|
||||
~PerfConfigWidget();
|
||||
|
||||
void updateUi();
|
||||
void setTarget(ProjectExplorer::Target *target);
|
||||
@@ -53,8 +55,13 @@ private:
|
||||
void handleProcessError(QProcess::ProcessError error);
|
||||
|
||||
PerfSettings *m_settings;
|
||||
Ui::PerfConfigWidget *m_ui;
|
||||
std::unique_ptr<ProjectExplorer::DeviceProcess> m_process;
|
||||
|
||||
QTableView *eventsView;
|
||||
QPushButton *useTracePointsButton;
|
||||
QPushButton *addEventButton;
|
||||
QPushButton *removeEventButton;
|
||||
QPushButton *resetButton;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
@@ -1,135 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>PerfProfiler::Internal::PerfConfigWidget</class>
|
||||
<widget class="QWidget" name="PerfProfiler::Internal::PerfConfigWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>560</width>
|
||||
<height>500</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="4" column="1">
|
||||
<widget class="QComboBox" name="sampleMode"/>
|
||||
</item>
|
||||
<item row="3" column="3">
|
||||
<widget class="QSpinBox" name="stackSize">
|
||||
<property name="maximum">
|
||||
<number>65536</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>4096</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QLabel" name="stackSizeLabel">
|
||||
<property name="text">
|
||||
<string>Stack snapshot size (kB):</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="sampleModeLabel">
|
||||
<property name="text">
|
||||
<string>Sample mode:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QLabel" name="periodLabel">
|
||||
<property name="text">
|
||||
<string>Sample period:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="callgraphLabel">
|
||||
<property name="text">
|
||||
<string>Call graph mode:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1" colspan="3">
|
||||
<widget class="QLineEdit" name="extraArguments"/>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="callgraphMode">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="extraArgumentsLabel">
|
||||
<property name="text">
|
||||
<string>Additional arguments:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="3">
|
||||
<widget class="QSpinBox" name="period">
|
||||
<property name="maximum">
|
||||
<number>2147483647</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>250</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="4">
|
||||
<widget class="QTableView" name="eventsView">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<height>300</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::AllEditTriggers</set>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::SingleSelection</enum>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="useTracePointsButton">
|
||||
<property name="text">
|
||||
<string>Use Trace Points</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="addEventButton">
|
||||
<property name="text">
|
||||
<string>Add Event</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QPushButton" name="removeEventButton">
|
||||
<property name="text">
|
||||
<string>Remove Event</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QPushButton" name="resetButton">
|
||||
<property name="text">
|
||||
<string>Reset</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -69,7 +69,6 @@ OTHER_FILES += \
|
||||
PerfProfiler.json.in
|
||||
|
||||
FORMS += \
|
||||
perfconfigwidget.ui \
|
||||
perfloaddialog.ui \
|
||||
perftracepointdialog.ui
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ QtcPlugin {
|
||||
"perfconfigeventsmodel.h",
|
||||
"perfconfigwidget.cpp",
|
||||
"perfconfigwidget.h",
|
||||
"perfconfigwidget.ui",
|
||||
"perfdatareader.cpp",
|
||||
"perfdatareader.h",
|
||||
"perfevent.h",
|
||||
|
||||
@@ -49,22 +49,9 @@ const char TraceFileExtension[] = ".data";
|
||||
const char PerfProfilerPerspectiveId[] = "PerfProfiler.Perspective";
|
||||
const char PerfProfilerLocalActionId[] = "PerfProfiler.Local";
|
||||
const char AnalyzerSettingsGroupId[] = "Analyzer";
|
||||
const char PerfSampleModeId[] = "Analyzer.Perf.SampleMode";
|
||||
const char PerfFrequencyId[] = "Analyzer.Perf.Frequency";
|
||||
const char PerfStackSizeId[] = "Analyzer.Perf.StackSize";
|
||||
const char PerfCallgraphModeId[] = "Analyzer.Perf.CallgraphMode";
|
||||
const char PerfEventsId[] = "Analyzer.Perf.Events";
|
||||
const char PerfExtraArgumentsId[] = "Analyzer.Perf.ExtraArguments";
|
||||
const char PerfSettingsId[] = "Analyzer.Perf.Settings";
|
||||
const char PerfRecordArgumentsId[] = "Analyzer.Perf.RecordArguments";
|
||||
|
||||
const unsigned int PerfDefaultPeriod = 250;
|
||||
const unsigned int PerfDefaultStackSize = 4096;
|
||||
const char PerfSettingsId[] = "Analyzer.Perf.Settings";
|
||||
const char PerfCallgraphDwarf[] = "dwarf";
|
||||
const char PerfCallgraphFP[] = "fp";
|
||||
const char PerfCallgraphLBR[] = "lbr";
|
||||
const char PerfSampleFrequency[] = "-F";
|
||||
const char PerfSampleCount[] = "-c";
|
||||
|
||||
const char PerfStreamMagic[] = "QPERFSTREAM";
|
||||
const char PerfZqfileMagic[] = "PTQFILE4.10";
|
||||
|
||||
@@ -31,6 +31,10 @@
|
||||
|
||||
#include <QSettings>
|
||||
|
||||
#include <utils/qtcprocess.h>
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
namespace PerfProfiler {
|
||||
|
||||
PerfSettings::PerfSettings(ProjectExplorer::Target *target)
|
||||
@@ -42,6 +46,48 @@ PerfSettings::PerfSettings(ProjectExplorer::Target *target)
|
||||
return widget;
|
||||
});
|
||||
|
||||
group.registerAspect(&period);
|
||||
period.setSettingsKey("Analyzer.Perf.Frequency");
|
||||
period.setRange(250, 2147483647);
|
||||
period.setDefaultValue(250);
|
||||
period.setLabelText(tr("Sample period:"));
|
||||
|
||||
group.registerAspect(&stackSize);
|
||||
stackSize.setSettingsKey("Analyzer.Perf.StackSize");
|
||||
stackSize.setRange(4096, 65536);
|
||||
stackSize.setDefaultValue(4096);
|
||||
stackSize.setLabelText(tr("Stack snapshot size (kB):"));
|
||||
|
||||
group.registerAspect(&sampleMode);
|
||||
sampleMode.setSettingsKey("Analyzer.Perf.SampleMode");
|
||||
sampleMode.setDisplayStyle(SelectionAspect::DisplayStyle::ComboBox);
|
||||
sampleMode.setLabelText(tr("Sample mode:"));
|
||||
sampleMode.addOption({tr("frequency (Hz)"), {}, QString("-F")});
|
||||
sampleMode.addOption({tr("event count"), {}, QString("-c")});
|
||||
sampleMode.setDefaultValue(0);
|
||||
|
||||
group.registerAspect(&callgraphMode);
|
||||
callgraphMode.setSettingsKey("Analyzer.Perf.CallgraphMode");
|
||||
callgraphMode.setDisplayStyle(SelectionAspect::DisplayStyle::ComboBox);
|
||||
callgraphMode.setLabelText(tr("Call graph mode:"));
|
||||
callgraphMode.addOption({tr("dwarf"), {}, QString(Constants::PerfCallgraphDwarf)});
|
||||
callgraphMode.addOption({tr("frame pointer"), {}, QString("fp")});
|
||||
callgraphMode.addOption({tr("last branch record"), {}, QString("lbr")});
|
||||
callgraphMode.setDefaultValue(0);
|
||||
|
||||
group.registerAspect(&events);
|
||||
events.setSettingsKey("Analyzer.Perf.Events");
|
||||
events.setDefaultValue({"cpu-cycles"});
|
||||
|
||||
group.registerAspect(&extraArguments);
|
||||
extraArguments.setSettingsKey("Analyzer.Perf.ExtraArguments");
|
||||
extraArguments.setDisplayStyle(StringAspect::DisplayStyle::LineEditDisplay);
|
||||
extraArguments.setLabelText(tr("Additional arguments:"));
|
||||
|
||||
connect(&callgraphMode, &SelectionAspect::volatileValueChanged, this, [this](int index) {
|
||||
stackSize.setEnabled(index == 0);
|
||||
});
|
||||
|
||||
readGlobalSettings();
|
||||
}
|
||||
|
||||
@@ -52,13 +98,6 @@ PerfSettings::~PerfSettings()
|
||||
void PerfSettings::readGlobalSettings()
|
||||
{
|
||||
QVariantMap defaults;
|
||||
defaults.insert(QLatin1String(Constants::PerfEventsId), QStringList({"cpu-cycles"}));
|
||||
defaults.insert(QLatin1String(Constants::PerfSampleModeId), Constants::PerfSampleFrequency);
|
||||
defaults.insert(QLatin1String(Constants::PerfFrequencyId), Constants::PerfDefaultPeriod);
|
||||
defaults.insert(QLatin1String(Constants::PerfStackSizeId), Constants::PerfDefaultStackSize);
|
||||
defaults.insert(QLatin1String(Constants::PerfCallgraphModeId),
|
||||
QLatin1String(Constants::PerfCallgraphDwarf));
|
||||
defaults.insert(QLatin1String(Constants::PerfExtraArgumentsId), QStringList());
|
||||
|
||||
// Read stored values
|
||||
QSettings *settings = Core::ICore::settings();
|
||||
@@ -84,51 +123,23 @@ void PerfSettings::writeGlobalSettings() const
|
||||
|
||||
void PerfSettings::toMap(QVariantMap &map) const
|
||||
{
|
||||
map[QLatin1String(Constants::PerfSampleModeId)] = m_sampleMode;
|
||||
map[QLatin1String(Constants::PerfFrequencyId)] = m_period;
|
||||
map[QLatin1String(Constants::PerfStackSizeId)] = m_stackSize;
|
||||
map[QLatin1String(Constants::PerfCallgraphModeId)] = m_callgraphMode;
|
||||
map[QLatin1String(Constants::PerfEventsId)] = m_events;
|
||||
map[QLatin1String(Constants::PerfExtraArgumentsId)] = m_extraArguments;
|
||||
map[QLatin1String(Constants::PerfRecordArgumentsId)] = perfRecordArguments();
|
||||
group.toMap(map);
|
||||
}
|
||||
|
||||
void PerfSettings::fromMap(const QVariantMap &map)
|
||||
{
|
||||
m_sampleMode = map.value(QLatin1String(Constants::PerfSampleModeId), m_sampleMode).toString();
|
||||
m_period = map.value(QLatin1String(Constants::PerfFrequencyId), m_period).toInt();
|
||||
m_stackSize = map.value(QLatin1String(Constants::PerfStackSizeId), m_stackSize).toInt();
|
||||
m_callgraphMode = map.value(QLatin1String(Constants::PerfCallgraphModeId),
|
||||
m_callgraphMode).toString();
|
||||
m_events = map.value(QLatin1String(Constants::PerfEventsId), m_events).toStringList();
|
||||
m_extraArguments = map.value(QLatin1String(Constants::PerfExtraArgumentsId),
|
||||
m_extraArguments).toStringList();
|
||||
group.fromMap(map);
|
||||
emit changed();
|
||||
}
|
||||
|
||||
QString PerfSettings::callgraphMode() const
|
||||
{
|
||||
return m_callgraphMode;
|
||||
}
|
||||
|
||||
QStringList PerfSettings::events() const
|
||||
{
|
||||
return m_events;
|
||||
}
|
||||
|
||||
QStringList PerfSettings::extraArguments() const
|
||||
{
|
||||
return m_extraArguments;
|
||||
}
|
||||
|
||||
QStringList PerfSettings::perfRecordArguments() const
|
||||
{
|
||||
QString callgraphArg = m_callgraphMode;
|
||||
if (m_callgraphMode == QLatin1String(Constants::PerfCallgraphDwarf))
|
||||
callgraphArg += "," + QString::number(m_stackSize);
|
||||
QString callgraphArg = callgraphMode.itemValue().toString();
|
||||
if (callgraphArg == Constants::PerfCallgraphDwarf)
|
||||
callgraphArg += "," + QString::number(stackSize.value());
|
||||
|
||||
QString events;
|
||||
for (const QString &event : m_events) {
|
||||
for (const QString &event : this->events.value()) {
|
||||
if (!event.isEmpty()) {
|
||||
if (!events.isEmpty())
|
||||
events.append(',');
|
||||
@@ -136,23 +147,11 @@ QStringList PerfSettings::perfRecordArguments() const
|
||||
}
|
||||
}
|
||||
|
||||
return QStringList({"-e", events, "--call-graph", callgraphArg, m_sampleMode,
|
||||
QString::number(m_period)}) + m_extraArguments;
|
||||
}
|
||||
|
||||
void PerfSettings::setCallgraphMode(const QString &callgraphMode)
|
||||
{
|
||||
m_callgraphMode = callgraphMode;
|
||||
}
|
||||
|
||||
void PerfSettings::setEvents(const QStringList &events)
|
||||
{
|
||||
m_events = events;
|
||||
}
|
||||
|
||||
void PerfSettings::setExtraArguments(const QStringList &args)
|
||||
{
|
||||
m_extraArguments = args;
|
||||
return QStringList({"-e", events,
|
||||
"--call-graph", callgraphArg,
|
||||
sampleMode.itemValue().toString(),
|
||||
QString::number(period.value())})
|
||||
+ QtcProcess::splitArgs(extraArguments.value());
|
||||
}
|
||||
|
||||
void PerfSettings::resetToDefault()
|
||||
@@ -163,34 +162,4 @@ void PerfSettings::resetToDefault()
|
||||
fromMap(map);
|
||||
}
|
||||
|
||||
int PerfSettings::stackSize() const
|
||||
{
|
||||
return m_stackSize;
|
||||
}
|
||||
|
||||
QString PerfSettings::sampleMode() const
|
||||
{
|
||||
return m_sampleMode;
|
||||
}
|
||||
|
||||
void PerfSettings::setStackSize(int stackSize)
|
||||
{
|
||||
m_stackSize = stackSize;
|
||||
}
|
||||
|
||||
void PerfSettings::setSampleMode(const QString &sampleMode)
|
||||
{
|
||||
m_sampleMode = sampleMode;
|
||||
}
|
||||
|
||||
int PerfSettings::period() const
|
||||
{
|
||||
return m_period;
|
||||
}
|
||||
|
||||
void PerfSettings::setPeriod(int period)
|
||||
{
|
||||
m_period = period;
|
||||
}
|
||||
|
||||
} // namespace PerfProfiler
|
||||
|
||||
@@ -45,36 +45,25 @@ public:
|
||||
void readGlobalSettings();
|
||||
void writeGlobalSettings() const;
|
||||
|
||||
int period() const;
|
||||
int stackSize() const;
|
||||
QString sampleMode() const;
|
||||
QString callgraphMode() const;
|
||||
QStringList events() const;
|
||||
QStringList extraArguments() const;
|
||||
|
||||
QStringList perfRecordArguments() const;
|
||||
|
||||
void setPeriod(int period);
|
||||
void setStackSize(int stackSize);
|
||||
void setSampleMode(const QString &sampleMode);
|
||||
void setCallgraphMode(const QString &callgraphMode);
|
||||
void setEvents(const QStringList &events);
|
||||
void setExtraArguments(const QStringList &args);
|
||||
void resetToDefault();
|
||||
|
||||
Utils::IntegerAspect period;
|
||||
Utils::IntegerAspect stackSize;
|
||||
Utils::SelectionAspect sampleMode;
|
||||
Utils::SelectionAspect callgraphMode;
|
||||
Utils::StringListAspect events;
|
||||
Utils::StringAspect extraArguments;
|
||||
|
||||
Utils::AspectContainer group;
|
||||
|
||||
signals:
|
||||
void changed();
|
||||
|
||||
protected:
|
||||
void toMap(QVariantMap &map) const final;
|
||||
void fromMap(const QVariantMap &map) final;
|
||||
|
||||
int m_period;
|
||||
int m_stackSize;
|
||||
QString m_sampleMode;
|
||||
QString m_callgraphMode;
|
||||
QStringList m_events;
|
||||
QStringList m_extraArguments;
|
||||
};
|
||||
|
||||
} // namespace PerfProfiler
|
||||
|
||||
Reference in New Issue
Block a user