Add PrettyMethod overload with result string.

Make it possible to avoid memory allocations.

Test: m test-art-host-gtest
Change-Id: I8914ed9f0768577063692dfe74cb418b3a8db2f0
diff --git a/libdexfile/dex/dex_file.cc b/libdexfile/dex/dex_file.cc
index f50e5cf..247032f 100644
--- a/libdexfile/dex/dex_file.cc
+++ b/libdexfile/dex/dex_file.cc
@@ -526,34 +526,35 @@
   return val;
 }
 
-std::string DexFile::PrettyMethod(uint32_t method_idx, bool with_signature) const {
+void DexFile::AppendPrettyMethod(uint32_t method_idx,
+                                 bool with_signature,
+                                 std::string* const result) const {
   if (method_idx >= NumMethodIds()) {
-    return StringPrintf("<<invalid-method-idx-%d>>", method_idx);
+    android::base::StringAppendF(result, "<<invalid-method-idx-%d>>", method_idx);
+    return;
   }
   const MethodId& method_id = GetMethodId(method_idx);
-  std::string result;
   const ProtoId* proto_id = with_signature ? &GetProtoId(method_id.proto_idx_) : nullptr;
   if (with_signature) {
-    AppendPrettyDescriptor(StringByTypeIdx(proto_id->return_type_idx_), &result);
-    result += ' ';
+    AppendPrettyDescriptor(StringByTypeIdx(proto_id->return_type_idx_), result);
+    result->push_back(' ');
   }
-  AppendPrettyDescriptor(GetMethodDeclaringClassDescriptor(method_id), &result);
-  result += '.';
-  result += GetMethodName(method_id);
+  AppendPrettyDescriptor(GetMethodDeclaringClassDescriptor(method_id), result);
+  result->push_back('.');
+  result->append(GetMethodName(method_id));
   if (with_signature) {
-    result += '(';
+    result->push_back('(');
     const TypeList* params = GetProtoParameters(*proto_id);
     if (params != nullptr) {
       const char* separator = "";
       for (uint32_t i = 0u, size = params->Size(); i != size; ++i) {
-        result += separator;
+        result->append(separator);
         separator = ", ";
-        AppendPrettyDescriptor(StringByTypeIdx(params->GetTypeItem(i).type_idx_), &result);
+        AppendPrettyDescriptor(StringByTypeIdx(params->GetTypeItem(i).type_idx_), result);
       }
     }
-    result += ')';
+    result->push_back(')');
   }
-  return result;
 }
 
 std::string DexFile::PrettyField(uint32_t field_idx, bool with_type) const {
diff --git a/libdexfile/dex/dex_file.h b/libdexfile/dex/dex_file.h
index 6a1ca98..e0406b9 100644
--- a/libdexfile/dex/dex_file.h
+++ b/libdexfile/dex/dex_file.h
@@ -758,13 +758,19 @@
   // when computing the adler32 checksum of the entire file.
   static constexpr uint32_t kNumNonChecksumBytes = OFFSETOF_MEMBER(DexFile::Header, signature_);
 
-  // Returns a human-readable form of the method at an index.
-  std::string PrettyMethod(uint32_t method_idx, bool with_signature = true) const;
+  // Appends a human-readable form of the method at an index.
+  void AppendPrettyMethod(uint32_t method_idx, bool with_signature, std::string* result) const;
   // Returns a human-readable form of the field at an index.
   std::string PrettyField(uint32_t field_idx, bool with_type = true) const;
   // Returns a human-readable form of the type at an index.
   std::string PrettyType(dex::TypeIndex type_idx) const;
 
+  ALWAYS_INLINE std::string PrettyMethod(uint32_t method_idx, bool with_signature = true) const {
+    std::string result;
+    AppendPrettyMethod(method_idx, with_signature, &result);
+    return result;
+  }
+
   // Not virtual for performance reasons.
   ALWAYS_INLINE bool IsCompactDexFile() const {
     return is_compact_dex_;