mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 07:57:47 +00:00
Profiler: Share the mapped kernel between Profile and DisassemblyModel
There is no point in keeping around a separate MappedFile object for /boot/Kernel.debug for each DisassemblyModel we create and re-parsing the kernel image multiple times. This will significantly speed up browsing through profile entries from the kernel in disassembly view.
This commit is contained in:
parent
c19c306744
commit
80b660132c
4 changed files with 18 additions and 18 deletions
|
@ -38,19 +38,12 @@ DisassemblyModel::DisassemblyModel(Profile& profile, ProfileNode& node)
|
||||||
: m_profile(profile)
|
: m_profile(profile)
|
||||||
, m_node(node)
|
, m_node(node)
|
||||||
{
|
{
|
||||||
OwnPtr<ELF::Image> kernel_elf;
|
|
||||||
const ELF::Image* elf;
|
const ELF::Image* elf;
|
||||||
FlatPtr base_address = 0;
|
FlatPtr base_address = 0;
|
||||||
auto maybe_kernel_base = Symbolication::kernel_base();
|
if (auto maybe_kernel_base = Symbolication::kernel_base(); maybe_kernel_base.has_value() && m_node.address() >= *maybe_kernel_base) {
|
||||||
if (maybe_kernel_base.has_value() && m_node.address() >= maybe_kernel_base.value()) {
|
if (!g_kernel_debuginfo_object.has_value())
|
||||||
if (!m_kernel_file) {
|
return;
|
||||||
auto file_or_error = MappedFile::map("/boot/Kernel.debug");
|
elf = &g_kernel_debuginfo_object->elf;
|
||||||
if (file_or_error.is_error())
|
|
||||||
return;
|
|
||||||
m_kernel_file = file_or_error.release_value();
|
|
||||||
}
|
|
||||||
kernel_elf = make<ELF::Image>((const u8*)m_kernel_file->data(), m_kernel_file->size());
|
|
||||||
elf = kernel_elf.ptr();
|
|
||||||
base_address = maybe_kernel_base.value();
|
base_address = maybe_kernel_base.value();
|
||||||
} else {
|
} else {
|
||||||
auto& process = node.process();
|
auto& process = node.process();
|
||||||
|
|
|
@ -54,7 +54,6 @@ private:
|
||||||
|
|
||||||
Profile& m_profile;
|
Profile& m_profile;
|
||||||
ProfileNode& m_node;
|
ProfileNode& m_node;
|
||||||
RefPtr<MappedFile> m_kernel_file;
|
|
||||||
|
|
||||||
Vector<InstructionData> m_instructions;
|
Vector<InstructionData> m_instructions;
|
||||||
};
|
};
|
||||||
|
|
|
@ -211,6 +211,8 @@ void Profile::rebuild_tree()
|
||||||
m_model->invalidate();
|
m_model->invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Optional<MappedObject> g_kernel_debuginfo_object;
|
||||||
|
|
||||||
Result<NonnullOwnPtr<Profile>, String> Profile::load_from_perfcore_file(const StringView& path)
|
Result<NonnullOwnPtr<Profile>, String> Profile::load_from_perfcore_file(const StringView& path)
|
||||||
{
|
{
|
||||||
auto file = Core::File::construct(path);
|
auto file = Core::File::construct(path);
|
||||||
|
@ -223,10 +225,14 @@ Result<NonnullOwnPtr<Profile>, String> Profile::load_from_perfcore_file(const St
|
||||||
|
|
||||||
auto& object = json.value().as_object();
|
auto& object = json.value().as_object();
|
||||||
|
|
||||||
auto file_or_error = MappedFile::map("/boot/Kernel.debug");
|
if (!g_kernel_debuginfo_object.has_value()) {
|
||||||
OwnPtr<ELF::Image> kernel_elf;
|
auto debuginfo_file_or_error = MappedFile::map("/boot/Kernel.debug");
|
||||||
if (!file_or_error.is_error())
|
if (!debuginfo_file_or_error.is_error()) {
|
||||||
kernel_elf = make<ELF::Image>(file_or_error.value()->bytes());
|
auto debuginfo_file = debuginfo_file_or_error.release_value();
|
||||||
|
auto debuginfo_image = ELF::Image(debuginfo_file->bytes());
|
||||||
|
g_kernel_debuginfo_object = { { debuginfo_file, move(debuginfo_image) } };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto strings_value = object.get_ptr("strings"sv);
|
auto strings_value = object.get_ptr("strings"sv);
|
||||||
if (!strings_value || !strings_value->is_array())
|
if (!strings_value || !strings_value->is_array())
|
||||||
|
@ -380,8 +386,8 @@ Result<NonnullOwnPtr<Profile>, String> Profile::load_from_perfcore_file(const St
|
||||||
String symbol;
|
String symbol;
|
||||||
|
|
||||||
if (maybe_kernel_base.has_value() && ptr >= maybe_kernel_base.value()) {
|
if (maybe_kernel_base.has_value() && ptr >= maybe_kernel_base.value()) {
|
||||||
if (kernel_elf) {
|
if (g_kernel_debuginfo_object.has_value()) {
|
||||||
symbol = kernel_elf->symbolicate(ptr - maybe_kernel_base.value(), &offset);
|
symbol = g_kernel_debuginfo_object->elf.symbolicate(ptr - maybe_kernel_base.value(), &offset);
|
||||||
} else {
|
} else {
|
||||||
symbol = String::formatted("?? <{:p}>", ptr);
|
symbol = String::formatted("?? <{:p}>", ptr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
|
|
||||||
namespace Profiler {
|
namespace Profiler {
|
||||||
|
|
||||||
|
extern Optional<MappedObject> g_kernel_debuginfo_object;
|
||||||
|
|
||||||
class ProfileNode : public RefCounted<ProfileNode> {
|
class ProfileNode : public RefCounted<ProfileNode> {
|
||||||
public:
|
public:
|
||||||
static NonnullRefPtr<ProfileNode> create(Process const& process, FlyString object_name, String symbol, FlatPtr address, u32 offset, u64 timestamp, pid_t pid)
|
static NonnullRefPtr<ProfileNode> create(Process const& process, FlyString object_name, String symbol, FlatPtr address, u32 offset, u64 timestamp, pid_t pid)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue