Fix hprof/ahat for string compression.

Test: m test-art-host
Test: m ahat-test
Test: m test-art-host with string compression enabled
Test: m ahat-test with string compression enabled
Bug: 31040547
Change-Id: I660e39c586d23f4a95686d484ca108466e52d249
diff --git a/runtime/hprof/hprof.cc b/runtime/hprof/hprof.cc
index 3d3ad59..133502e 100644
--- a/runtime/hprof/hprof.cc
+++ b/runtime/hprof/hprof.cc
@@ -224,12 +224,6 @@
     HandleU1List(values, count);
     length_ += count;
   }
-  void AddU1AsU2List(const uint8_t* values, size_t count) {
-    HandleU1AsU2List(values, count);
-    // Array of char from compressed String (8-bit) is added as 16-bit blocks
-    int ceil_count_to_even = count + ((count & 1) ? 1 : 0);
-    length_ += ceil_count_to_even * sizeof(uint8_t);
-  }
   void AddU2List(const uint16_t* values, size_t count) {
     HandleU2List(values, count);
     length_ += count * sizeof(uint16_t);
@@ -1277,7 +1271,7 @@
     HprofBasicType t = SignatureToBasicTypeAndSize(f->GetTypeDescriptor(), nullptr);
     __ AddU1(t);
   }
-  // Add native value character array for strings.
+  // Add native value character array for strings / byte array for compressed strings.
   if (klass->IsStringClass()) {
     __ AddStringId(LookupStringId("value"));
     __ AddU1(hprof_basic_object);
@@ -1359,8 +1353,16 @@
       case hprof_basic_short:
         __ AddU2(f->GetShort(obj));
         break;
-      case hprof_basic_float:
       case hprof_basic_int:
+        if (mirror::kUseStringCompression &&
+            klass->IsStringClass() &&
+            f->GetOffset().SizeValue() == mirror::String::CountOffset().SizeValue()) {
+          // Store the string length instead of the raw count field with compression flag.
+          __ AddU4(obj->AsString()->GetLength());
+          break;
+        }
+        FALLTHROUGH_INTENDED;
+      case hprof_basic_float:
       case hprof_basic_object:
         __ AddU4(f->Get32(obj));
         break;
@@ -1397,16 +1399,15 @@
   CHECK_EQ(obj->IsString(), string_value != nullptr);
   if (string_value != nullptr) {
     mirror::String* s = obj->AsString();
-    // Compressed string's (8-bit) length is ceil(length/2) in 16-bit blocks
-    int length_in_16_bit = (s->IsCompressed()) ? ((s->GetLength() + 1) / 2) : s->GetLength();
     __ AddU1(HPROF_PRIMITIVE_ARRAY_DUMP);
     __ AddObjectId(string_value);
     __ AddStackTraceSerialNumber(LookupStackTraceSerialNumber(obj));
-    __ AddU4(length_in_16_bit);
-    __ AddU1(hprof_basic_char);
+    __ AddU4(s->GetLength());
     if (s->IsCompressed()) {
-      __ AddU1AsU2List(s->GetValueCompressed(), s->GetLength());
+      __ AddU1(hprof_basic_byte);
+      __ AddU1List(s->GetValueCompressed(), s->GetLength());
     } else {
+      __ AddU1(hprof_basic_char);
       __ AddU2List(s->GetValue(), s->GetLength());
     }
   }