summaryrefslogtreecommitdiff
path: root/perfetto_hprof
diff options
context:
space:
mode:
author Kevin Jeon <kevinjeon@google.com> 2023-03-13 15:24:50 +0000
committer Kevin Jeon <kevinjeon@google.com> 2023-03-14 00:10:20 +0000
commitc069a1ecc85f90bab5969ead6a1ff5d8dacf371a (patch)
treeb82fa8f579c1fd7e9c52e138fb019f341c1319e6 /perfetto_hprof
parent278297bca84182c22dc78bf61fb21a888ca45801 (diff)
Improve prettified-text performance in heap dumps
This change replaces the char-by-char insert for '.'->'/' conversions with a std::replace, and updates ReferredObjectsFinder to only collect and prettify field_name items if they will be used. This reduces the CPU usage of heap dumps (measured with the heap dump tool at external/perfetto/tools/java_heap_dump) by ~18%. Test: Measure java_heap_dump CPU usage with simpleperf; verify in the perfetto UI that the collected heap dumps still look correct. Bug: 266124917 Change-Id: I5771bd9ef9be26dfa254dcfe7ddbb17c12ff4aae
Diffstat (limited to 'perfetto_hprof')
-rw-r--r--perfetto_hprof/perfetto_hprof.cc23
1 files changed, 13 insertions, 10 deletions
diff --git a/perfetto_hprof/perfetto_hprof.cc b/perfetto_hprof/perfetto_hprof.cc
index ba4c6f259e..d7aa3bd935 100644
--- a/perfetto_hprof/perfetto_hprof.cc
+++ b/perfetto_hprof/perfetto_hprof.cc
@@ -412,8 +412,9 @@ class Writer {
class ReferredObjectsFinder {
public:
explicit ReferredObjectsFinder(
- std::vector<std::pair<std::string, art::mirror::Object*>>* referred_objects)
- : referred_objects_(referred_objects) {}
+ std::vector<std::pair<std::string, art::mirror::Object*>>* referred_objects,
+ bool emit_field_ids)
+ : referred_objects_(referred_objects), emit_field_ids_(emit_field_ids) {}
// For art::mirror::Object::VisitReferences.
void operator()(art::ObjPtr<art::mirror::Object> obj, art::MemberOffset offset,
@@ -431,7 +432,7 @@ class ReferredObjectsFinder {
field = art::ArtField::FindInstanceFieldWithOffset(obj->GetClass(), offset.Uint32Value());
}
std::string field_name = "";
- if (field != nullptr) {
+ if (field != nullptr && emit_field_ids_) {
field_name = field->PrettyField(/*with_type=*/true);
}
referred_objects_->emplace_back(std::move(field_name), ref);
@@ -446,6 +447,8 @@ class ReferredObjectsFinder {
// We can use a raw Object* pointer here, because there are no concurrent GC threads after the
// fork.
std::vector<std::pair<std::string, art::mirror::Object*>>* referred_objects_;
+ // Prettifying field names is expensive; avoid if field name will not be used.
+ bool emit_field_ids_;
};
class RootFinder : public art::SingleRootVisitor {
@@ -583,10 +586,11 @@ size_t EncodedSize(uint64_t n) {
// Returns all the references that `*obj` (an object of type `*klass`) is holding.
std::vector<std::pair<std::string, art::mirror::Object*>> GetReferences(art::mirror::Object* obj,
- art::mirror::Class* klass)
+ art::mirror::Class* klass,
+ bool emit_field_ids)
REQUIRES_SHARED(art::Locks::mutator_lock_) {
std::vector<std::pair<std::string, art::mirror::Object*>> referred_objects;
- ReferredObjectsFinder objf(&referred_objects);
+ ReferredObjectsFinder objf(&referred_objects, emit_field_ids);
if (klass->GetClassFlags() != art::mirror::kClassFlagNormal &&
klass->GetClassFlags() != art::mirror::kClassFlagPhantomReference) {
@@ -797,17 +801,16 @@ class HeapGraphDumper {
art::mirror::Class* klass,
perfetto::protos::pbzero::HeapGraphObject* object_proto)
REQUIRES_SHARED(art::Locks::mutator_lock_) {
+ const bool emit_field_ids = klass->GetClassFlags() != art::mirror::kClassFlagObjectArray &&
+ klass->GetClassFlags() != art::mirror::kClassFlagNormal &&
+ klass->GetClassFlags() != art::mirror::kClassFlagPhantomReference;
std::vector<std::pair<std::string, art::mirror::Object*>> referred_objects =
- GetReferences(obj, klass);
+ GetReferences(obj, klass, emit_field_ids);
art::mirror::Object* min_nonnull_ptr = FilterIgnoredReferencesAndFindMin(referred_objects);
uint64_t base_obj_id = EncodeBaseObjId(referred_objects, min_nonnull_ptr);
- const bool emit_field_ids = klass->GetClassFlags() != art::mirror::kClassFlagObjectArray &&
- klass->GetClassFlags() != art::mirror::kClassFlagNormal &&
- klass->GetClassFlags() != art::mirror::kClassFlagPhantomReference;
-
for (const auto& p : referred_objects) {
const std::string& field_name = p.first;
art::mirror::Object* referred_obj = p.second;