1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 03:57:44 +00:00

LibDebug: Memoize resolved paths in DebugInfo::prepare_lines()

When loading debug info, we encounter the same filename over and over
(since files usually have many lines!) and we were wasting a ton of
time re-checking if the filename was part of the Toolchain or libgcc,
along with some other checks.

This patch makes prepare_lines() significantly faster by memoizing
the result of these checks per filename.

This makes "bt 12" ~25% faster (from 850ms to 650ms on my machine.) :^)
This commit is contained in:
Andreas Kling 2021-05-23 23:01:11 +02:00
parent d27616cf36
commit 0bf3df28b9

View file

@ -90,20 +90,28 @@ void DebugInfo::prepare_lines()
all_lines.append(program.lines());
}
String serenity_slash("serenity/");
HashMap<FlyString, Optional<String>> memoized_full_paths;
auto compute_full_path = [&](FlyString const& file_path) -> Optional<String> {
if (file_path.view().contains("Toolchain/"sv) || file_path.view().contains("libgcc"sv))
return {};
if (file_path.view().starts_with("./"sv) && !m_source_root.is_null())
return LexicalPath::join(m_source_root, file_path).string();
if (auto index_of_serenity_slash = file_path.view().find("serenity/"sv); index_of_serenity_slash.has_value()) {
auto start_index = index_of_serenity_slash.value() + "serenity/"sv.length();
return file_path.view().substring_view(start_index, file_path.length() - start_index);
}
return file_path;
};
for (auto& line_info : all_lines) {
String file_path = line_info.file;
if (file_path.contains("Toolchain/") || file_path.contains("libgcc"))
for (auto const& line_info : all_lines) {
auto it = memoized_full_paths.find(line_info.file);
if (it == memoized_full_paths.end()) {
memoized_full_paths.set(line_info.file, compute_full_path(line_info.file));
it = memoized_full_paths.find(line_info.file);
}
if (!it->value.has_value())
continue;
if (file_path.contains(serenity_slash)) {
auto start_index = file_path.index_of(serenity_slash).value() + serenity_slash.length();
file_path = file_path.substring(start_index, file_path.length() - start_index);
}
if (file_path.starts_with("./") && !m_source_root.is_null()) {
file_path = LexicalPath::canonicalized_path(String::formatted("{}/{}", m_source_root, file_path));
}
m_sorted_lines.append({ line_info.address, file_path, line_info.line });
m_sorted_lines.append({ line_info.address, it->value.value(), line_info.line });
}
quick_sort(m_sorted_lines, [](auto& a, auto& b) {
return a.address < b.address;