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/dex_file_test.cc b/runtime/dex_file_test.cc
index 1a73062..a7bf59e 100644
--- a/runtime/dex_file_test.cc
+++ b/runtime/dex_file_test.cc
@@ -423,28 +423,83 @@
     ASSERT_EQ("()V", signature);
   }
 
-  // Check both virtual methods.
-  ASSERT_EQ(2U, it.NumVirtualMethods());
-  {
+  // Check all virtual methods.
+  struct Result {
+    const char* name;
+    const char* signature;
+    const char* pretty_method;
+  };
+  static const Result results[] = {
+      {
+          "m1",
+          "(IDJLjava/lang/Object;)Ljava/lang/Float;",
+          "java.lang.Float GetMethodSignature.m1(int, double, long, java.lang.Object)"
+      },
+      {  // NOLINT [whitespace/braces] [4]
+          "m2",
+          "(ZSC)LGetMethodSignature;",
+          "GetMethodSignature GetMethodSignature.m2(boolean, short, char)"
+      },
+      {  // NOLINT [whitespace/braces] [4]
+          "m3",
+          "()V",
+          "void GetMethodSignature.m3()"
+      },
+      {  // NOLINT [whitespace/braces] [4]
+          "m4",
+          "(I)V",
+          "void GetMethodSignature.m4(int)"
+      },
+      {  // NOLINT [whitespace/braces] [4]
+          "m5",
+          "(II)V",
+          "void GetMethodSignature.m5(int, int)"
+      },
+      {  // NOLINT [whitespace/braces] [4]
+          "m6",
+          "(II[[I)V",
+          "void GetMethodSignature.m6(int, int, int[][])"
+      },
+      {  // NOLINT [whitespace/braces] [4]
+          "m7",
+          "(II[[ILjava/lang/Object;)V",
+          "void GetMethodSignature.m7(int, int, int[][], java.lang.Object)"
+      },
+      {  // NOLINT [whitespace/braces] [4]
+          "m8",
+          "(II[[ILjava/lang/Object;[[Ljava/lang/Object;)V",
+          "void GetMethodSignature.m8(int, int, int[][], java.lang.Object, java.lang.Object[][])"
+      },
+      {  // NOLINT [whitespace/braces] [4]
+          "m9",
+          "()I",
+          "int GetMethodSignature.m9()"
+      },
+      {  // NOLINT [whitespace/braces] [4]
+          "mA",
+          "()[[I",
+          "int[][] GetMethodSignature.mA()"
+      },
+      {  // NOLINT [whitespace/braces] [4]
+          "mB",
+          "()[[Ljava/lang/Object;",
+          "java.lang.Object[][] GetMethodSignature.mB()"
+      },
+  };
+  ASSERT_EQ(arraysize(results), it.NumVirtualMethods());
+  for (const Result& r : results) {
     it.Next();
     const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
 
     const char* name = raw->StringDataByIdx(method_id.name_idx_);
-    ASSERT_STREQ("m1", name);
+    ASSERT_STREQ(r.name, name);
 
     std::string signature(raw->GetMethodSignature(method_id).ToString());
-    ASSERT_EQ("(IDJLjava/lang/Object;)Ljava/lang/Float;", signature);
-  }
+    ASSERT_EQ(r.signature, signature);
 
-  {
-    it.Next();
-    const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
-
-    const char* name = raw->StringDataByIdx(method_id.name_idx_);
-    ASSERT_STREQ("m2", name);
-
-    std::string signature(raw->GetMethodSignature(method_id).ToString());
-    ASSERT_EQ("(ZSC)LGetMethodSignature;", signature);
+    std::string plain_method = std::string("GetMethodSignature.") + r.name;
+    ASSERT_EQ(plain_method, raw->PrettyMethod(it.GetMemberIndex(), /* with_signature */ false));
+    ASSERT_EQ(r.pretty_method, raw->PrettyMethod(it.GetMemberIndex(), /* with_signature */ true));
   }
 }