Generate unique ID for each type during native debugging.

This allows the native debugger to find dynamic types of variables.

Change-Id: I901022b7db7d3c1db9f4b678ebafcb4eefed4ba7
diff --git a/compiler/dwarf/dwarf_constants.h b/compiler/dwarf/dwarf_constants.h
index 3b570e5..0d7951b 100644
--- a/compiler/dwarf/dwarf_constants.h
+++ b/compiler/dwarf/dwarf_constants.h
@@ -200,11 +200,11 @@
   DW_AT_data_bit_offset = 0x6b,
   DW_AT_const_expr = 0x6c,
   DW_AT_enum_class = 0x6d,
+  DW_AT_linkage_name = 0x6e,
 #ifdef INCLUDE_DWARF5_VALUES
   // Values to be added in Dwarf 5. Final value not yet specified. Values listed
   // may be different than other implementations. Use with caution.
   // TODO Update these values when Dwarf 5 is released.
-  DW_AT_linkage_name = 0x6e,
   DW_AT_call_site_value = 0x6f,
   DW_AT_call_site_data_value = 0x70,
   DW_AT_call_site_target = 0x71,
diff --git a/compiler/elf_writer_debug.cc b/compiler/elf_writer_debug.cc
index f3baf67..a64c9f1 100644
--- a/compiler/elf_writer_debug.cc
+++ b/compiler/elf_writer_debug.cc
@@ -18,9 +18,11 @@
 
 #include <unordered_set>
 #include <vector>
+#include <cstdio>
 
 #include "base/casts.h"
 #include "base/stl_util.h"
+#include "linear_alloc.h"
 #include "compiled_method.h"
 #include "dex_file-inl.h"
 #include "driver/compiler_driver.h"
@@ -591,7 +593,7 @@
       info_.WriteStrp(DW_AT_producer, owner_->WriteString("Android dex2oat"));
       info_.WriteData1(DW_AT_language, DW_LANG_Java);
 
-      std::vector<uint8_t> count_expr_buffer;
+      std::vector<uint8_t> expr_buffer;
       for (mirror::Class* type : types) {
         if (type->IsPrimitive()) {
           // For primitive types the definition and the declaration is the same.
@@ -607,16 +609,33 @@
           info_.StartTag(DW_TAG_array_type);
           std::string descriptor_string;
           WriteLazyType(element_type->GetDescriptor(&descriptor_string));
+          WriteLinkageName(type);
           info_.WriteUdata(DW_AT_data_member_location, data_offset);
           info_.StartTag(DW_TAG_subrange_type);
-          Expression count_expr(&count_expr_buffer);
+          Expression count_expr(&expr_buffer);
           count_expr.WriteOpPushObjectAddress();
           count_expr.WriteOpPlusUconst(length_offset);
           count_expr.WriteOpDerefSize(4);  // Array length is always 32-bit wide.
           info_.WriteExprLoc(DW_AT_count, count_expr);
           info_.EndTag();  // DW_TAG_subrange_type.
           info_.EndTag();  // DW_TAG_array_type.
+        } else if (type->IsInterface()) {
+          // Skip.  Variables cannot have an interface as a dynamic type.
+          // We do not expose the interface information to the debugger in any way.
         } else {
+          // Declare base class.  We can not use the standard WriteLazyType
+          // since we want to avoid the DW_TAG_reference_tag wrapping.
+          mirror::Class* base_class = type->GetSuperClass();
+          size_t base_class_declaration_offset = 0;
+          if (base_class != nullptr) {
+            std::string tmp_storage;
+            const char* base_class_desc = base_class->GetDescriptor(&tmp_storage);
+            base_class_declaration_offset = StartClassTag(base_class_desc);
+            info_.WriteFlag(DW_AT_declaration, true);
+            WriteLinkageName(base_class);
+            EndClassTag(base_class_desc);
+          }
+
           std::string descriptor_string;
           const char* desc = type->GetDescriptor(&descriptor_string);
           StartClassTag(desc);
@@ -625,11 +644,40 @@
             info_.WriteUdata(DW_AT_byte_size, type->GetObjectSize());
           }
 
+          WriteLinkageName(type);
+
+          if (type->IsObjectClass()) {
+            // Generate artificial member which is used to get the dynamic type of variable.
+            // The run-time value of this field will correspond to linkage name of some type.
+            // We need to do it only once in j.l.Object since all other types inherit it.
+            info_.StartTag(DW_TAG_member);
+            WriteName(".dynamic_type");
+            WriteLazyType(sizeof(uintptr_t) == 8 ? "J" : "I");
+            info_.WriteFlag(DW_AT_artificial, true);
+            // Create DWARF expression to get the value of the methods_ field.
+            Expression expr(&expr_buffer);
+            // The address of the object has been implicitly pushed on the stack.
+            // Dereference the klass_ field of Object (32-bit; possibly poisoned).
+            DCHECK_EQ(type->ClassOffset().Uint32Value(), 0u);
+            DCHECK_EQ(sizeof(mirror::HeapReference<mirror::Class>), 4u);
+            expr.WriteOpDerefSize(4);
+            if (kPoisonHeapReferences) {
+              expr.WriteOpNeg();
+              // DWARF stack is pointer sized. Ensure that the high bits are clear.
+              expr.WriteOpConstu(0xFFFFFFFF);
+              expr.WriteOpAnd();
+            }
+            // Add offset to the methods_ field.
+            expr.WriteOpPlusUconst(mirror::Class::MethodsOffset().Uint32Value());
+            // Top of stack holds the location of the field now.
+            info_.WriteExprLoc(DW_AT_data_member_location, expr);
+            info_.EndTag();  // DW_TAG_member.
+          }
+
           // Base class.
-          mirror::Class* base_class = type->GetSuperClass();
           if (base_class != nullptr) {
             info_.StartTag(DW_TAG_inheritance);
-            WriteLazyType(base_class->GetDescriptor(&descriptor_string));
+            info_.WriteRef4(DW_AT_type, base_class_declaration_offset);
             info_.WriteUdata(DW_AT_data_member_location, 0);
             info_.WriteSdata(DW_AT_accessibility, DW_ACCESS_public);
             info_.EndTag();  // DW_TAG_inheritance.
@@ -684,6 +732,24 @@
       owner_->builder_->GetDebugInfo()->WriteFully(buffer.data(), buffer.size());
     }
 
+    // Linkage name uniquely identifies type.
+    // It is used to determine the dynamic type of objects.
+    // We use the methods_ field of class since it is unique and it is not moved by the GC.
+    void WriteLinkageName(mirror::Class* type) SHARED_REQUIRES(Locks::mutator_lock_) {
+      auto* methods_ptr = type->GetMethodsPtr();
+      if (methods_ptr == nullptr) {
+        // Some types might have no methods.  Allocate empty array instead.
+        LinearAlloc* allocator = Runtime::Current()->GetLinearAlloc();
+        void* storage = allocator->Alloc(Thread::Current(), sizeof(LengthPrefixedArray<ArtMethod>));
+        methods_ptr = new (storage) LengthPrefixedArray<ArtMethod>(0);
+        type->SetMethodsPtr(methods_ptr, 0, 0);
+        DCHECK(type->GetMethodsPtr() != nullptr);
+      }
+      char name[32];
+      snprintf(name, sizeof(name), "0x%" PRIXPTR, reinterpret_cast<uintptr_t>(methods_ptr));
+      info_.WriteString(DW_AT_linkage_name, name);
+    }
+
     // Write table into .debug_loc which describes location of dex register.
     // The dex register might be valid only at some points and it might
     // move between machine registers and stack.
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index 3a06b82..6b5ed91 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -706,6 +706,10 @@
   ALWAYS_INLINE LengthPrefixedArray<ArtMethod>* GetMethodsPtr()
       SHARED_REQUIRES(Locks::mutator_lock_);
 
+  static MemberOffset MethodsOffset() {
+    return MemberOffset(OFFSETOF_MEMBER(Class, methods_));
+  }
+
   ALWAYS_INLINE IterationRange<StrideIterator<ArtMethod>> GetMethods(size_t pointer_size)
       SHARED_REQUIRES(Locks::mutator_lock_);
 
@@ -1357,6 +1361,8 @@
   // The slice methods_ [copied_methods_offset_, |methods_|) are the methods that are copied from
   // interfaces such as miranda or default methods. These are copied for resolution purposes as this
   // class is where they are (logically) declared as far as the virtual dispatch is concerned.
+  //
+  // Note that this field is used by the native debugger as the unique identifier for the type.
   uint64_t methods_;
 
   // Static fields length-prefixed array.