From 7abf58ecafc4bd3c606724d6ab5f04d2db043c85 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Fri, 13 Aug 2021 01:51:30 +0200 Subject: [PATCH] Profiler: Store event type as enum Also check for the most common event type (sample) first instead of leaving it as the fallback. This avoids a lot of string comparisons while parsing profiles. --- Userland/DevTools/Profiler/Profile.cpp | 49 ++++++++++++++++---------- Userland/DevTools/Profiler/Profile.h | 15 +++++++- 2 files changed, 45 insertions(+), 19 deletions(-) diff --git a/Userland/DevTools/Profiler/Profile.cpp b/Userland/DevTools/Profiler/Profile.cpp index 6597022239..9d2df278b9 100644 --- a/Userland/DevTools/Profiler/Profile.cpp +++ b/Userland/DevTools/Profiler/Profile.cpp @@ -77,9 +77,9 @@ void Profile::rebuild_tree() HashTable live_allocations; for_each_event_in_filter_range([&](auto& event) { - if (event.type == "malloc"sv) + if (event.type == Event::Type::Malloc) live_allocations.set(event.ptr); - else if (event.type == "free"sv) + else if (event.type == Event::Type::Free) live_allocations.remove(event.ptr); }); @@ -99,10 +99,10 @@ void Profile::rebuild_tree() m_filtered_event_indices.append(event_index); - if (event.type == "malloc"sv && !live_allocations.contains(event.ptr)) + if (event.type == Event::Type::Malloc && !live_allocations.contains(event.ptr)) continue; - if (event.type == "free"sv) + if (event.type == Event::Type::Free) continue; auto for_each_frame = [&](Callback callback) { @@ -239,23 +239,27 @@ Result, String> Profile::load_from_perfcore_file(const St next_serial.increment(); event.timestamp = perf_event.get("timestamp").to_number(); event.lost_samples = perf_event.get("lost_samples").to_number(); - event.type = perf_event.get("type").to_string(); event.pid = perf_event.get("pid").to_i32(); event.tid = perf_event.get("tid").to_i32(); - bool is_signpost = false; + auto type_string = perf_event.get("type").to_string(); - if (event.type == "malloc"sv) { + if (type_string == "sample"sv) { + event.type = Event::Type::Sample; + } else if (type_string == "malloc"sv) { + event.type = Event::Type::Malloc; event.ptr = perf_event.get("ptr").to_number(); event.size = perf_event.get("size").to_number(); - } else if (event.type == "free"sv) { + } else if (type_string == "free"sv) { + event.type = Event::Type::Free; event.ptr = perf_event.get("ptr").to_number(); - } else if (event.type == "signpost"sv) { - is_signpost = true; + } else if (type_string == "signpost"sv) { + event.type = Event::Type::Signpost; auto string_id = perf_event.get("arg1").to_number(); event.signpost_string = profile_strings.get(string_id).value_or(String::formatted("Signpost #{}", string_id)); event.arg2 = perf_event.get("arg2").to_number(); - } else if (event.type == "mmap"sv) { + } else if (type_string == "mmap"sv) { + event.type = Event::Type::Mmap; event.ptr = perf_event.get("ptr").to_number(); event.size = perf_event.get("size").to_number(); event.name = perf_event.get("name").to_string(); @@ -264,11 +268,13 @@ Result, String> Profile::load_from_perfcore_file(const St if (it != current_processes.end()) it->value->library_metadata.handle_mmap(event.ptr, event.size, event.name); continue; - } else if (event.type == "munmap"sv) { + } else if (type_string == "munmap"sv) { + event.type = Event::Type::Munmap; event.ptr = perf_event.get("ptr").to_number(); event.size = perf_event.get("size").to_number(); continue; - } else if (event.type == "process_create"sv) { + } else if (type_string == "process_create"sv) { + event.type = Event::Type::ProcessCreate; event.parent_pid = perf_event.get("parent_pid").to_number(); event.executable = perf_event.get("executable").to_string(); @@ -283,7 +289,8 @@ Result, String> Profile::load_from_perfcore_file(const St current_processes.set(sampled_process->pid, sampled_process); all_processes.append(move(sampled_process)); continue; - } else if (event.type == "process_exec"sv) { + } else if (type_string == "process_exec"sv) { + event.type = Event::Type::ProcessExec; event.executable = perf_event.get("executable").to_string(); auto old_process = current_processes.get(event.pid).value(); @@ -302,23 +309,29 @@ Result, String> Profile::load_from_perfcore_file(const St current_processes.set(sampled_process->pid, sampled_process); all_processes.append(move(sampled_process)); continue; - } else if (event.type == "process_exit"sv) { + } else if (type_string == "process_exit"sv) { + event.type = Event::Type::ProcessExit; auto old_process = current_processes.get(event.pid).value(); old_process->end_valid = event.serial; current_processes.remove(event.pid); continue; - } else if (event.type == "thread_create"sv) { + } else if (type_string == "thread_create"sv) { + event.type = Event::Type::ThreadCreate; event.parent_tid = perf_event.get("parent_tid").to_i32(); auto it = current_processes.find(event.pid); if (it != current_processes.end()) it->value->handle_thread_create(event.tid, event.serial); continue; - } else if (event.type == "thread_exit"sv) { + } else if (type_string == "thread_exit"sv) { + event.type = Event::Type::ThreadExit; auto it = current_processes.find(event.pid); if (it != current_processes.end()) it->value->handle_thread_exit(event.tid, event.serial); continue; + } else { + dbgln("Unknown event type '{}'", type_string); + VERIFY_NOT_REACHED(); } auto maybe_kernel_base = Symbolication::kernel_base(); @@ -362,7 +375,7 @@ Result, String> Profile::load_from_perfcore_file(const St FlatPtr innermost_frame_address = event.frames.at(1).address; event.in_kernel = maybe_kernel_base.has_value() && innermost_frame_address >= maybe_kernel_base.value(); - if (is_signpost) + if (event.type == Event::Type::Signpost) signposts.append(move(event)); else events.append(move(event)); diff --git a/Userland/DevTools/Profiler/Profile.h b/Userland/DevTools/Profiler/Profile.h index cb5cc30327..37ddabc345 100644 --- a/Userland/DevTools/Profiler/Profile.h +++ b/Userland/DevTools/Profiler/Profile.h @@ -163,9 +163,22 @@ public: }; struct Event { + enum class Type { + Free, + Malloc, + Mmap, + Munmap, + ProcessCreate, + ProcessExec, + ProcessExit, + Sample, + Signpost, + ThreadCreate, + ThreadExit, + }; + Type type {}; EventSerialNumber serial; u64 timestamp { 0 }; - String type; FlatPtr ptr { 0 }; size_t size { 0 }; String name;