ART: Faster PrettyMethod().

Rewrite DexFile::PrettyMethod() to avoid copying strings.
This improves the performance, especially when requesting
the signature.

Avoid code duplication in ArtMethod::PrettyMethod() and
delegate to DexFile::PrettyMethod().

10 million invocations of ArtMethod/DexFile::PrettyMethod()
for "void Main.main(java.lang.String[] args)" with (+) or
without (-) signature, time in ms:
      host/32-bit  host/64-bit angler/32-bit angler/64-bit
AM+: 10407-> 5020  6374-> 3302  32413->13140  17558->10003
DF+:  7280-> 4259  3881-> 2828  19287-> 9331  10343-> 7375
AM-:  2682-> 1599  2025-> 1186   7206-> 4271   7447-> 4166
DF-:   861->  871   653->  640   1574-> 1430   1828-> 1712

Test: m test-art-host-gtest
Test: testrunner.py --host
Change-Id: Ifb79abe1a7f4fc6adc10a34f5d49dc6681d06699
diff --git a/runtime/utils.cc b/runtime/utils.cc
index 3fe18c7..fc1c91a 100644
--- a/runtime/utils.cc
+++ b/runtime/utils.cc
@@ -148,7 +148,7 @@
   }
 }
 
-std::string PrettyDescriptor(const char* descriptor) {
+void AppendPrettyDescriptor(const char* descriptor, std::string* result) {
   // Count the number of '['s to get the dimensionality.
   const char* c = descriptor;
   size_t dim = 0;
@@ -166,74 +166,41 @@
     // To make life easier, we make primitives look like unqualified
     // reference types.
     switch (*c) {
-    case 'B': c = "byte;"; break;
-    case 'C': c = "char;"; break;
-    case 'D': c = "double;"; break;
-    case 'F': c = "float;"; break;
-    case 'I': c = "int;"; break;
-    case 'J': c = "long;"; break;
-    case 'S': c = "short;"; break;
-    case 'Z': c = "boolean;"; break;
-    case 'V': c = "void;"; break;  // Used when decoding return types.
-    default: return descriptor;
+      case 'B': c = "byte;"; break;
+      case 'C': c = "char;"; break;
+      case 'D': c = "double;"; break;
+      case 'F': c = "float;"; break;
+      case 'I': c = "int;"; break;
+      case 'J': c = "long;"; break;
+      case 'S': c = "short;"; break;
+      case 'Z': c = "boolean;"; break;
+      case 'V': c = "void;"; break;  // Used when decoding return types.
+      default: result->append(descriptor); return;
     }
   }
 
   // At this point, 'c' is a string of the form "fully/qualified/Type;"
   // or "primitive;". Rewrite the type with '.' instead of '/':
-  std::string result;
   const char* p = c;
   while (*p != ';') {
     char ch = *p++;
     if (ch == '/') {
       ch = '.';
     }
-    result.push_back(ch);
+    result->push_back(ch);
   }
   // ...and replace the semicolon with 'dim' "[]" pairs:
   for (size_t i = 0; i < dim; ++i) {
-    result += "[]";
+    result->append("[]");
   }
-  return result;
 }
 
-std::string PrettyArguments(const char* signature) {
+std::string PrettyDescriptor(const char* descriptor) {
   std::string result;
-  result += '(';
-  CHECK_EQ(*signature, '(');
-  ++signature;  // Skip the '('.
-  while (*signature != ')') {
-    size_t argument_length = 0;
-    while (signature[argument_length] == '[') {
-      ++argument_length;
-    }
-    if (signature[argument_length] == 'L') {
-      argument_length = (strchr(signature, ';') - signature + 1);
-    } else {
-      ++argument_length;
-    }
-    {
-      std::string argument_descriptor(signature, argument_length);
-      result += PrettyDescriptor(argument_descriptor.c_str());
-    }
-    if (signature[argument_length] != ')') {
-      result += ", ";
-    }
-    signature += argument_length;
-  }
-  CHECK_EQ(*signature, ')');
-  ++signature;  // Skip the ')'.
-  result += ')';
+  AppendPrettyDescriptor(descriptor, &result);
   return result;
 }
 
-std::string PrettyReturnType(const char* signature) {
-  const char* return_type = strchr(signature, ')');
-  CHECK(return_type != nullptr);
-  ++return_type;  // Skip ')'.
-  return PrettyDescriptor(return_type);
-}
-
 std::string PrettyJavaAccessFlags(uint32_t access_flags) {
   std::string result;
   if ((access_flags & kAccPublic) != 0) {