Dump NativeAllocationRegistry size

This commits dumps the value of
the "libcore.util.NativeAllocationRegistry.size" field.

This is useful to understand native allocations.

Bug: 194395971
Change-Id: I8de37fe7b3b6f68ae85a6bbd4c6bba4d0da23df6
diff --git a/perfetto_hprof/perfetto_hprof.cc b/perfetto_hprof/perfetto_hprof.cc
index 78bc1c2..face456 100644
--- a/perfetto_hprof/perfetto_hprof.cc
+++ b/perfetto_hprof/perfetto_hprof.cc
@@ -669,6 +669,8 @@
     }
 
     FillReferences(obj, klass, object_proto);
+
+    FillFieldValues(obj, klass, object_proto);
   }
 
   // Writes `*klass` into `writer`.
@@ -771,6 +773,31 @@
     return min_nonnull_ptr;
   }
 
+  // Fills `*object_proto` with the value of a subset of potentially interesting fields of `*obj`
+  // (an object of type `*klass`).
+  void FillFieldValues(art::mirror::Object* obj,
+                       art::mirror::Class* klass,
+                       perfetto::protos::pbzero::HeapGraphObject* object_proto) const
+      REQUIRES_SHARED(art::Locks::mutator_lock_) {
+    if (obj->IsClass() || klass->IsClassClass()) {
+      return;
+    }
+
+    for (art::mirror::Class* cls = klass; cls != nullptr; cls = cls->GetSuperClass().Ptr()) {
+      if (cls->IsArrayClass()) {
+        continue;
+      }
+
+      if (cls->DescriptorEquals("Llibcore/util/NativeAllocationRegistry;")) {
+        art::ArtField* af = cls->FindDeclaredInstanceField(
+            "size", art::Primitive::Descriptor(art::Primitive::kPrimLong));
+        if (af) {
+          object_proto->set_native_allocation_registry_size_field(af->GetLong(obj));
+        }
+      }
+    }
+  }
+
   // Returns true if `*obj` has a type that's supposed to be ignored.
   bool IsIgnored(art::mirror::Object* obj) const REQUIRES_SHARED(art::Locks::mutator_lock_) {
     if (obj->IsClass()) {