creating workflow for mirror::String compression

All-ASCII String characters are stored in 8-bit blocks
instead of 16-bit. The compression has not taken place, but all
workflow are in the code already (changing kUseStringCompression in
string.h file to TRUE will enable the feature)

Notes: Feature works on interpreter only without optimizing

Test art: m ART_TEST_INTERPRETER=true ART_TEST_OPTIMIZING=false
          test-art-host

Also tested with String tests from libcore/:
1. libcore.java.lang.StringTest
2. libcore.java.lang.StringBufferTest
3. libcore.java.lang.StringBuilderTest
4. libcore.java.lang.OldStringTest
5. libcore.java.lang.OldStringBufferTest

Memory improvement is 33% (from 6.03% to 4.03%, total String memory
from all apps per total memory of all apps) measured on Angler
with Hprof tools

Bug: 31040547
Change-Id: I9cc92c265ebf1305fc06b5fc33efd83797660cce
diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc
index 6d5e7c7..d4e54cf 100644
--- a/runtime/native/java_lang_Class.cc
+++ b/runtime/native/java_lang_Class.cc
@@ -198,12 +198,25 @@
   }
   size_t low = 0;
   size_t high = fields->size();
-  const uint16_t* const data = name->GetValue();
+  const bool is_name_compressed = name->IsCompressed();
+  const uint16_t* const data = (is_name_compressed) ? nullptr : name->GetValue();
+  const uint8_t* const data_compressed = (is_name_compressed) ? name->GetValueCompressed()
+                                                              : nullptr;
   const size_t length = name->GetLength();
   while (low < high) {
     auto mid = (low + high) / 2;
     ArtField& field = fields->At(mid);
-    int result = CompareModifiedUtf8ToUtf16AsCodePointValues(field.GetName(), data, length);
+    int result = 0;
+    if (is_name_compressed) {
+      size_t field_length = strlen(field.GetName());
+      size_t min_size = (length < field_length) ? length : field_length;
+      result = memcmp(field.GetName(), data_compressed, min_size);
+      if (result == 0) {
+        result = field_length - length;
+      }
+    } else {
+      result = CompareModifiedUtf8ToUtf16AsCodePointValues(field.GetName(), data, length);
+    }
     // Alternate approach, only a few % faster at the cost of more allocations.
     // int result = field->GetStringName(self, true)->CompareTo(name);
     if (result < 0) {
@@ -636,8 +649,7 @@
   // Invoke the string allocator to return an empty string for the string class.
   if (klass->IsStringClass()) {
     gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
-    mirror::SetStringCountVisitor visitor(0);
-    mirror::Object* obj = mirror::String::Alloc<true>(soa.Self(), 0, allocator_type, visitor);
+    mirror::Object* obj = mirror::String::AllocEmptyString<true>(soa.Self(), allocator_type);
     if (UNLIKELY(soa.Self()->IsExceptionPending())) {
       return nullptr;
     } else {