1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-06-01 03:18:11 +00:00

ProfileViewer: Parse the JSON input directly to Profile::Event

We were going from "new JSON format" => "old JSON format" => Event.
This made loading longer profiles unnecessarily slow. It's still pretty
slow, and we should... profile it! :^)
This commit is contained in:
Andreas Kling 2020-03-02 20:24:58 +01:00
parent 8eaac171d7
commit e7f8c8a342
2 changed files with 30 additions and 61 deletions

View file

@ -43,52 +43,16 @@ static void sort_profile_nodes(Vector<NonnullRefPtr<ProfileNode>>& nodes)
child->sort_children();
}
Profile::Profile(const JsonArray& json)
: m_json(json)
Profile::Profile(Vector<Event> events)
: m_events(move(events))
{
m_first_timestamp = m_json.at(0).as_object().get("timestamp").to_number<u64>();
m_last_timestamp = m_json.at(m_json.size() - 1).as_object().get("timestamp").to_number<u64>();
m_first_timestamp = m_events.first().timestamp;
m_last_timestamp = m_events.last().timestamp;
m_model = ProfileModel::create(*this);
m_events.ensure_capacity(m_json.size());
for (auto& event_value : m_json.values()) {
auto& event_object = event_value.as_object();
Event event;
event.timestamp = event_object.get("timestamp").to_number<u64>();
event.type = event_object.get("type").to_string();
if (event.type == "malloc") {
event.ptr = event_object.get("ptr").to_number<u32>();
event.size = event_object.get("size").to_number<u32>();
} else if (event.type == "free") {
event.ptr = event_object.get("ptr").to_number<u32>();
}
auto frames_value = event_object.get("frames");
auto& frames_array = frames_value.as_array();
if (frames_array.size() < 2)
continue;
u32 innermost_frame_address = frames_array.at(1).as_object().get("address").to_number<u32>();
event.in_kernel = innermost_frame_address >= 0xc0000000;
for (int i = frames_array.size() - 1; i >= 1; --i) {
auto& frame_value = frames_array.at(i);
auto& frame_object = frame_value.as_object();
Frame frame;
frame.symbol = frame_object.get("symbol").as_string_or({});
frame.address = frame_object.get("address").as_u32();
frame.offset = frame_object.get("offset").as_u32();
event.frames.append(move(frame));
};
m_deepest_stack_depth = max((u32)frames_array.size(), m_deepest_stack_depth);
m_events.append(move(event));
for (auto& event : m_events) {
m_deepest_stack_depth = max((u32)event.frames.size(), m_deepest_stack_depth);
}
rebuild_tree();
@ -226,21 +190,26 @@ OwnPtr<Profile> Profile::load_from_perfcore_file(const StringView& path)
if (perf_events.is_empty())
return nullptr;
JsonArray profile_events;
Vector<Event> events;
for (auto& perf_event_value : perf_events.values()) {
auto& perf_event = perf_event_value.as_object();
JsonObject object;
object.set("timestamp", perf_event.get("timestamp"));
object.set("type", perf_event.get("type"));
object.set("ptr", perf_event.get("ptr"));
object.set("size", perf_event.get("size"));
Event event;
event.timestamp = perf_event.get("timestamp").to_number<u64>();
event.type = perf_event.get("type").to_string();
if (event.type == "malloc") {
event.ptr = perf_event.get("ptr").to_number<uintptr_t>();
event.size = perf_event.get("size").to_number<size_t>();
} else if (event.type == "free") {
event.ptr = perf_event.get("ptr").to_number<uintptr_t>();
}
JsonArray frames_array;
auto stack_array = perf_event.get("stack").as_array();
for (auto& frame : stack_array.values()) {
for (ssize_t i = stack_array.values().size() - 1; i >= 1; --i) {
auto& frame = stack_array.at(i);
auto ptr = frame.to_number<u32>();
u32 offset = 0;
String symbol;
@ -258,18 +227,19 @@ OwnPtr<Profile> Profile::load_from_perfcore_file(const StringView& path)
if (symbol == "??")
symbol = String::format("??", ptr);
JsonObject frame_object;
frame_object.set("address", ptr);
frame_object.set("symbol", symbol);
frame_object.set("offset", offset);
frames_array.append(move(frame_object));
event.frames.append({ symbol, ptr, offset });
}
object.set("frames", move(frames_array));
profile_events.append(move(object));
if (event.frames.size() < 2)
continue;
uintptr_t innermost_frame_address = event.frames.at(1).address;
event.in_kernel = innermost_frame_address >= 0xc0000000;
events.append(move(event));
}
return NonnullOwnPtr<Profile>(NonnullOwnPtr<Profile>::Adopt, *new Profile(move(profile_events)));
return NonnullOwnPtr<Profile>(NonnullOwnPtr<Profile>::Adopt, *new Profile(move(events)));
}
void ProfileNode::sort_children()

View file

@ -138,11 +138,10 @@ public:
void set_inverted(bool);
private:
explicit Profile(const JsonArray&);
explicit Profile(Vector<Event>);
void rebuild_tree();
JsonArray m_json;
RefPtr<ProfileModel> m_model;
Vector<NonnullRefPtr<ProfileNode>> m_roots;
u64 m_first_timestamp { 0 };