Skip to content

Commit

Permalink
add search function to disassembler
Browse files Browse the repository at this point in the history
  • Loading branch information
lievenhey committed May 16, 2023
1 parent 6deef4c commit 06991bd
Show file tree
Hide file tree
Showing 7 changed files with 492 additions and 176 deletions.
17 changes: 17 additions & 0 deletions src/models/disassemblymodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "hotspot-config.h"

#include "highlighter.hpp"
#include "search.h"
#include "sourcecodemodel.h"

DisassemblyModel::DisassemblyModel(KSyntaxHighlighting::Repository* repository, QObject* parent)
Expand Down Expand Up @@ -222,3 +223,19 @@ QModelIndex DisassemblyModel::indexForFileLine(const Data::FileLine& fileLine) c
return {};
return index(bestMatch, 0);
}

void DisassemblyModel::find(const QString& search, Direction direction, int offset)
{
auto searchFunc = [&search](const DisassemblyOutput::DisassemblyLine& line) {
return line.disassembly.indexOf(search, 0, Qt::CaseInsensitive) != -1;
};

int resultIndex = ::search(
m_data.disassemblyLines, searchFunc, [this] { emit resultFound({}); }, direction, offset);

if (resultIndex >= 0) {
emit resultFound(createIndex(resultIndex, DisassemblyColumn));
} else {
emit resultFound({});
}
}
7 changes: 7 additions & 0 deletions src/models/disassemblymodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ class Definition;
class Repository;
}

enum class Direction;

class DisassemblyModel : public QAbstractTableModel
{
Q_OBJECT
Expand Down Expand Up @@ -67,8 +69,13 @@ class DisassemblyModel : public QAbstractTableModel
SyntaxHighlightRole,
};

signals:
void resultFound(QModelIndex index);
void searchEndReached();

public slots:
void updateHighlighting(int line);
void find(const QString& search, Direction direction, int offset);

private:
QTextDocument* m_document;
Expand Down
50 changes: 50 additions & 0 deletions src/models/search.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
SPDX-FileCopyrightText: Lieven Hey <[email protected]>
SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company, [email protected]
SPDX-License-Identifier: GPL-2.0-or-later
*/

#pragma once

#include <QVector>

enum class Direction
{
Forward,
Backward
};

template<typename entry, typename SearchFunc, typename EndReached>
int search(QVector<entry> source, SearchFunc&& searchFunc, EndReached&& endReached, Direction direction, int offset)
{
if (offset > source.size() || offset < 0) {
offset = 0;
}

auto start = direction == Direction::Forward
? (source.begin() + offset)
: (source.end() - (source.size() - offset - 1)); // 1 one due to offset of the reverse iterator

auto it = direction == Direction::Forward
? std::find_if(start, source.end(), searchFunc)
: (std::find_if(std::make_reverse_iterator(start), source.rend(), searchFunc) + 1).base();

// it is less than source.begin() if the backward search ends at source.rend()
if (it >= source.begin() && it < source.end()) {
auto distance = std::distance(source.begin(), it);
return distance;
}

it = direction == Direction::Forward
? std::find_if(source.begin(), start, searchFunc)
: (std::find_if(source.rbegin(), std::make_reverse_iterator(start), searchFunc) + 1).base();

if (it != source.end()) {
auto distance = std::distance(source.begin(), it);
endReached();
return distance;
}

return -1;
}
19 changes: 19 additions & 0 deletions src/models/sourcecodemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@
#include <QTextBlock>
#include <QTextDocument>

#include <algorithm>

#include "highlighter.hpp"
#include "search.h"

SourceCodeModel::SourceCodeModel(KSyntaxHighlighting::Repository* repository, QObject* parent)
: QAbstractTableModel(parent)
Expand Down Expand Up @@ -244,3 +247,19 @@ void SourceCodeModel::setSysroot(const QString& sysroot)
{
m_sysroot = sysroot;
}

void SourceCodeModel::find(const QString& search, Direction direction, int offset)
{
auto searchFunc = [&search](const SourceCodeLine& line) {
return line.text.indexOf(search, 0, Qt::CaseInsensitive) != -1;
};

int resultIndex = ::search(
m_sourceCodeLines, searchFunc, [this] { emit resultFound({}); }, direction, offset);

if (resultIndex >= 0) {
emit resultFound(createIndex(resultIndex + 1, SourceCodeColumn));
} else {
emit resultFound({});
}
}
8 changes: 8 additions & 0 deletions src/models/sourcecodemodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ struct SourceCodeLine
QTextLine line;
};

enum class Direction;

Q_DECLARE_METATYPE(QTextLine)

class SourceCodeModel : public QAbstractTableModel
Expand Down Expand Up @@ -72,10 +74,16 @@ class SourceCodeModel : public QAbstractTableModel
FileLineRole,
};

signals:
void resultFound(QModelIndex index);
void searchEndReached();

public slots:
void updateHighlighting(int line);
void setSysroot(const QString& sysroot);

void find(const QString& search, Direction direction, int offset);

private:
QString m_sysroot;
QSet<int> m_validLineNumbers;
Expand Down
91 changes: 87 additions & 4 deletions src/resultsdisassemblypage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
#include <QTemporaryFile>
#include <QTextStream>

#include <KColorScheme>
#include <KRecursiveFilterProxyModel>
#include <KStandardAction>

#include "parsers/perf/perfparser.h"
#include "resultsutil.h"
Expand All @@ -42,11 +44,21 @@
#include "models/costdelegate.h"
#include "models/disassemblymodel.h"
#include "models/hashmodel.h"
#include "models/search.h"
#include "models/sourcecodemodel.h"
#include "models/topproxy.h"
#include "models/treemodel.h"
#include "settings.h"

namespace {
template<typename ModelType, typename ResultFound, typename EndReached>
void connectModel(ModelType* model, ResultFound resultFound, EndReached endReached)
{
QObject::connect(model, &ModelType::resultFound, model, resultFound);
QObject::connect(model, &ModelType::searchEndReached, model, endReached);
}
}

ResultsDisassemblyPage::ResultsDisassemblyPage(CostContextMenu* costContextMenu, QWidget* parent)
: QWidget(parent)
, ui(new Ui::ResultsDisassemblyPage)
Expand Down Expand Up @@ -171,6 +183,76 @@ ResultsDisassemblyPage::ResultsDisassemblyPage(CostContextMenu* costContextMenu,
showDisassembly();
});

ui->searchEndWidget->hide();
ui->disasmEndReachedWidget->hide();

auto setupSearchShortcuts = [this](QPushButton* search, QPushButton* next, QPushButton* prev, QPushButton* close,
QWidget* searchWidget, QLineEdit* edit, QAbstractItemView* view,
KMessageWidget* endReached, auto* model, int additionalRows) {
searchWidget->hide();

auto actions = new QActionGroup(view);

auto findAction = KStandardAction::find(
this,
[searchWidget, edit] {
searchWidget->show();
edit->setFocus();
},
actions);
findAction->setShortcutContext(Qt::ShortcutContext::WidgetWithChildrenShortcut);
view->addAction(findAction);

auto searchNext = [this, model, edit, additionalRows] {
int offset = m_currentSearchIndex.isValid() ? m_currentSearchIndex.row() - additionalRows + 1 : 0;
model->find(edit->text(), Direction::Forward, offset);
};

auto searchPrev = [this, model, edit, additionalRows] {
int offset = m_currentSearchIndex.isValid() ? m_currentSearchIndex.row() - additionalRows - 1 : 0;

model->find(edit->text(), Direction::Backward, offset);
};

auto findNextAction = KStandardAction::findNext(this, searchNext, actions);
findNextAction->setShortcutContext(Qt::ShortcutContext::WidgetWithChildrenShortcut);
searchWidget->addAction(findNextAction);
auto findPrevAction = KStandardAction::findPrev(this, searchPrev, actions);
findPrevAction->setShortcutContext(Qt::ShortcutContext::WidgetWithChildrenShortcut);
searchWidget->addAction(findPrevAction);

connect(edit, &QLineEdit::returnPressed, findNextAction, &QAction::trigger);
connect(next, &QPushButton::clicked, findNextAction, &QAction::trigger);
connect(prev, &QPushButton::clicked, findPrevAction, &QAction::trigger);

connect(search, &QPushButton::clicked, findAction, &QAction::trigger);
connect(close, &QPushButton::clicked, this, [searchWidget] { searchWidget->hide(); });

KColorScheme colorScheme;

connectModel(
model,
[this, edit, view, colorScheme](const QModelIndex& index) {
auto palette = edit->palette();
m_currentSearchIndex = index;
palette.setBrush(QPalette::Text,
index.isValid() ? colorScheme.foreground()
: colorScheme.foreground(KColorScheme::NegativeText));
edit->setPalette(palette);
view->setCurrentIndex(index);

if (!index.isValid())
view->clearSelection();
},
[endReached] { endReached->show(); });
};

setupSearchShortcuts(ui->searchButton, ui->nextResult, ui->prevResult, ui->closeButton, ui->searchWidget,
ui->searchEdit, ui->sourceCodeView, ui->searchEndWidget, m_sourceCodeModel, 1);
setupSearchShortcuts(ui->disasmSearchButton, ui->disasmNextButton, ui->disasmPrevButton, ui->disasmCloseButton,
ui->disasmSearchWidget, ui->disasmSearchEdit, ui->assemblyView, ui->disasmEndReachedWidget,
m_disassemblyModel, 0);

#if KF5SyntaxHighlighting_FOUND
QStringList schemes;

Expand Down Expand Up @@ -310,17 +392,18 @@ void ResultsDisassemblyPage::showDisassembly(const DisassemblyOutput& disassembl

ResultsUtil::hideEmptyColumns(m_callerCalleeResults.selfCosts, ui->assemblyView, DisassemblyModel::COLUMN_COUNT);

ResultsUtil::hideEmptyColumns(m_callerCalleeResults.selfCosts, ui->sourceCodeView,
SourceCodeModel::COLUMN_COUNT);
ResultsUtil::hideEmptyColumns(m_callerCalleeResults.selfCosts, ui->sourceCodeView, SourceCodeModel::COLUMN_COUNT);

ResultsUtil::hideEmptyColumns(m_callerCalleeResults.inclusiveCosts, ui->sourceCodeView,
SourceCodeModel::COLUMN_COUNT + m_callerCalleeResults.selfCosts.numTypes());

// hide self cost for tracepoints in assembly view, this is basically always zero
ResultsUtil::hideTracepointColumns(m_callerCalleeResults.selfCosts, ui->assemblyView, DisassemblyModel::COLUMN_COUNT);
ResultsUtil::hideTracepointColumns(m_callerCalleeResults.selfCosts, ui->assemblyView,
DisassemblyModel::COLUMN_COUNT);

// hide self cost for tracepoints - only show inclusive times instead here
ResultsUtil::hideTracepointColumns(m_callerCalleeResults.selfCosts, ui->sourceCodeView, SourceCodeModel::COLUMN_COUNT);
ResultsUtil::hideTracepointColumns(m_callerCalleeResults.selfCosts, ui->sourceCodeView,
SourceCodeModel::COLUMN_COUNT);

setupAsmViewModel();
}
Expand Down
Loading

0 comments on commit 06991bd

Please sign in to comment.