Add dex location to dirty object identifiers

Bug: 346990440
Test: install ART module with imgdiag, run art/imgdiag/run_imgdiag.py
Change-Id: Ifeeafbe2eb79ebb7b0faca4e6f461c4e519e7a01
diff --git a/imgdiag/imgdiag.cc b/imgdiag/imgdiag.cc
index 165f6e1..a31bb74 100644
--- a/imgdiag/imgdiag.cc
+++ b/imgdiag/imgdiag.cc
@@ -440,7 +440,9 @@
 using ParentMap = std::unordered_map<mirror::Object*, ParentInfo>;
 
 // Returns the "path" from root class to an object in the format:
-// <class_descriptor>(.<field_name>:<field_type_descriptor>)*
+// <dex_location> <class_descriptor>(.<field_name>:<field_type_descriptor>)*
+// <dex_location> is either a full path to the dex file where the class is
+// defined or "primitive" if the class is a primitive array.
 std::string GetPathFromClass(mirror::Object* obj, const ParentMap& parent_map)
     REQUIRES_SHARED(Locks::mutator_lock_) {
   auto parent_info_it = parent_map.find(obj);
@@ -459,7 +461,17 @@
   CHECK(class_obj->IsClass());
 
   std::string temp;
-  path = class_obj->AsClass()->GetDescriptor(&temp) + path;
+  ObjPtr<mirror::Class> klass = class_obj->AsClass();
+  path = klass->GetDescriptor(&temp) + path;
+
+  // Prepend dex location to the path.
+  // Use array value type if class is an array.
+  while (klass->IsArrayClass()) {
+    klass = klass->GetComponentType();
+  }
+  std::string dex_location = klass->IsPrimitive() ? "primitive" : klass->GetDexFile().GetLocation();
+  path = ART_FORMAT("{} {}", dex_location, path);
+
   return path;
 }