diff options
author | 2023-03-13 15:24:50 +0000 | |
---|---|---|
committer | 2023-03-14 00:10:20 +0000 | |
commit | c069a1ecc85f90bab5969ead6a1ff5d8dacf371a (patch) | |
tree | b82fa8f579c1fd7e9c52e138fb019f341c1319e6 /perfetto_hprof | |
parent | 278297bca84182c22dc78bf61fb21a888ca45801 (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.cc | 23 |
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; |