mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 14:07:46 +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:
parent
8eaac171d7
commit
e7f8c8a342
2 changed files with 30 additions and 61 deletions
|
@ -43,52 +43,16 @@ static void sort_profile_nodes(Vector<NonnullRefPtr<ProfileNode>>& nodes)
|
||||||
child->sort_children();
|
child->sort_children();
|
||||||
}
|
}
|
||||||
|
|
||||||
Profile::Profile(const JsonArray& json)
|
Profile::Profile(Vector<Event> events)
|
||||||
: m_json(json)
|
: m_events(move(events))
|
||||||
{
|
{
|
||||||
m_first_timestamp = m_json.at(0).as_object().get("timestamp").to_number<u64>();
|
m_first_timestamp = m_events.first().timestamp;
|
||||||
m_last_timestamp = m_json.at(m_json.size() - 1).as_object().get("timestamp").to_number<u64>();
|
m_last_timestamp = m_events.last().timestamp;
|
||||||
|
|
||||||
m_model = ProfileModel::create(*this);
|
m_model = ProfileModel::create(*this);
|
||||||
|
|
||||||
m_events.ensure_capacity(m_json.size());
|
for (auto& event : m_events) {
|
||||||
for (auto& event_value : m_json.values()) {
|
m_deepest_stack_depth = max((u32)event.frames.size(), m_deepest_stack_depth);
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rebuild_tree();
|
rebuild_tree();
|
||||||
|
@ -226,21 +190,26 @@ OwnPtr<Profile> Profile::load_from_perfcore_file(const StringView& path)
|
||||||
if (perf_events.is_empty())
|
if (perf_events.is_empty())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
JsonArray profile_events;
|
Vector<Event> events;
|
||||||
|
|
||||||
for (auto& perf_event_value : perf_events.values()) {
|
for (auto& perf_event_value : perf_events.values()) {
|
||||||
auto& perf_event = perf_event_value.as_object();
|
auto& perf_event = perf_event_value.as_object();
|
||||||
|
|
||||||
JsonObject object;
|
Event event;
|
||||||
object.set("timestamp", perf_event.get("timestamp"));
|
|
||||||
object.set("type", perf_event.get("type"));
|
event.timestamp = perf_event.get("timestamp").to_number<u64>();
|
||||||
object.set("ptr", perf_event.get("ptr"));
|
event.type = perf_event.get("type").to_string();
|
||||||
object.set("size", perf_event.get("size"));
|
|
||||||
|
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();
|
auto stack_array = perf_event.get("stack").as_array();
|
||||||
|
for (ssize_t i = stack_array.values().size() - 1; i >= 1; --i) {
|
||||||
for (auto& frame : stack_array.values()) {
|
auto& frame = stack_array.at(i);
|
||||||
auto ptr = frame.to_number<u32>();
|
auto ptr = frame.to_number<u32>();
|
||||||
u32 offset = 0;
|
u32 offset = 0;
|
||||||
String symbol;
|
String symbol;
|
||||||
|
@ -258,18 +227,19 @@ OwnPtr<Profile> Profile::load_from_perfcore_file(const StringView& path)
|
||||||
if (symbol == "??")
|
if (symbol == "??")
|
||||||
symbol = String::format("??", ptr);
|
symbol = String::format("??", ptr);
|
||||||
|
|
||||||
JsonObject frame_object;
|
event.frames.append({ symbol, ptr, offset });
|
||||||
frame_object.set("address", ptr);
|
|
||||||
frame_object.set("symbol", symbol);
|
|
||||||
frame_object.set("offset", offset);
|
|
||||||
frames_array.append(move(frame_object));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object.set("frames", move(frames_array));
|
if (event.frames.size() < 2)
|
||||||
profile_events.append(move(object));
|
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()
|
void ProfileNode::sort_children()
|
||||||
|
|
|
@ -138,11 +138,10 @@ public:
|
||||||
void set_inverted(bool);
|
void set_inverted(bool);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit Profile(const JsonArray&);
|
explicit Profile(Vector<Event>);
|
||||||
|
|
||||||
void rebuild_tree();
|
void rebuild_tree();
|
||||||
|
|
||||||
JsonArray m_json;
|
|
||||||
RefPtr<ProfileModel> m_model;
|
RefPtr<ProfileModel> m_model;
|
||||||
Vector<NonnullRefPtr<ProfileNode>> m_roots;
|
Vector<NonnullRefPtr<ProfileNode>> m_roots;
|
||||||
u64 m_first_timestamp { 0 };
|
u64 m_first_timestamp { 0 };
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue