Profiler: Display source location information in the disassembly view

With this, we can now have some amount of source-level profiling
information :^)
This commit is contained in:
Ali Mohammad Pur 2021-08-06 00:37:20 +04:30 committed by Andreas Kling
parent c4437e19bd
commit 5d3b452897
Notes: sideshowbarker 2024-07-18 07:25:10 +09:00
2 changed files with 31 additions and 1 deletions

View file

@ -7,6 +7,7 @@
#include "DisassemblyModel.h"
#include "Profile.h"
#include <AK/MappedFile.h>
#include <LibDebug/DebugInfo.h>
#include <LibELF/Image.h>
#include <LibGUI/Painter.h>
#include <LibSymbolication/Symbolication.h>
@ -75,6 +76,7 @@ DisassemblyModel::DisassemblyModel(Profile& profile, ProfileNode& node)
X86::ELFSymbolProvider symbol_provider(*elf);
X86::SimpleInstructionStream stream((const u8*)view.characters_without_null_termination(), view.length());
X86::Disassembler disassembler(stream);
Debug::DebugInfo debug_info { *elf, {}, base_address };
size_t offset_into_symbol = 0;
for (;;) {
@ -89,7 +91,7 @@ DisassemblyModel::DisassemblyModel(Profile& profile, ProfileNode& node)
u32 samples_at_this_instruction = m_node.events_per_address().get(address_in_profiled_program).value_or(0);
float percent = ((float)samples_at_this_instruction / (float)m_node.event_count()) * 100.0f;
m_instructions.append({ insn.value(), disassembly, instruction_bytes, address_in_profiled_program, samples_at_this_instruction, percent });
m_instructions.append({ insn.value(), disassembly, instruction_bytes, address_in_profiled_program, samples_at_this_instruction, percent, debug_info.get_source_position_with_inlines(address_in_profiled_program - base_address) });
offset_into_symbol += insn.value().length();
}
@ -115,6 +117,8 @@ String DisassemblyModel::column_name(int column) const
return "Insn Bytes";
case Column::Disassembly:
return "Disassembly";
case Column::SourceLocation:
return "Source Location";
default:
VERIFY_NOT_REACHED();
return {};
@ -164,8 +168,10 @@ GUI::Variant DisassemblyModel::data(const GUI::ModelIndex& index, GUI::ModelRole
return ((float)insn.event_count / (float)m_node.event_count()) * 100.0f;
return insn.event_count;
}
if (index.column() == Column::Address)
return String::formatted("{:p}", insn.address);
if (index.column() == Column::InstructionBytes) {
StringBuilder builder;
for (auto ch : insn.bytes) {
@ -173,8 +179,29 @@ GUI::Variant DisassemblyModel::data(const GUI::ModelIndex& index, GUI::ModelRole
}
return builder.to_string();
}
if (index.column() == Column::Disassembly)
return insn.disassembly;
if (index.column() == Column::SourceLocation) {
StringBuilder builder;
auto first = true;
for (auto& entry : insn.source_position_with_inlines.inline_chain) {
if (first)
first = false;
else
builder.append(" => ");
builder.appendff("{}:{}", entry.file_path, entry.line_number);
}
if (insn.source_position_with_inlines.source_position.has_value()) {
if (!first)
builder.append(" => ");
auto& entry = insn.source_position_with_inlines.source_position.value();
builder.appendff("{}:{}", entry.file_path, entry.line_number);
}
return builder.build();
}
return {};
}
return {};

View file

@ -6,6 +6,7 @@
#pragma once
#include <LibDebug/DebugInfo.h>
#include <LibGUI/Model.h>
#include <LibX86/Instruction.h>
@ -21,6 +22,7 @@ struct InstructionData {
FlatPtr address { 0 };
u32 event_count { 0 };
float percent { 0 };
Debug::DebugInfo::SourcePositionWithInlines source_position_with_inlines;
};
class DisassemblyModel final : public GUI::Model {
@ -35,6 +37,7 @@ public:
SampleCount,
InstructionBytes,
Disassembly,
SourceLocation,
__Count
};