Optimize string comparisons in Class::FindClassMethod.

The method is relatively hot in non-quickend code.

Avoid full string comparisons by comparing the unicode lengths first.

Test: ./art/test.py -b -r --interpreter --host --64
Change-Id: Ib0aa7008ca36e3916967fe082948d16823b93e02
diff --git a/libdexfile/dex/dex_file-inl.h b/libdexfile/dex/dex_file-inl.h
index eae7efc..c884eee 100644
--- a/libdexfile/dex/dex_file-inl.h
+++ b/libdexfile/dex/dex_file-inl.h
@@ -110,6 +110,14 @@
   return StringDataByIdx(method_id.name_idx_);
 }
 
+inline const char* DexFile::GetMethodName(const MethodId& method_id, uint32_t* utf_length) const {
+  return StringDataAndUtf16LengthByIdx(method_id.name_idx_, utf_length);
+}
+
+inline const char* DexFile::GetMethodName(uint32_t idx, uint32_t* utf_length) const {
+  return StringDataAndUtf16LengthByIdx(GetMethodId(idx).name_idx_, utf_length);
+}
+
 inline const char* DexFile::GetMethodShorty(uint32_t idx) const {
   return StringDataByIdx(GetProtoId(GetMethodId(idx).proto_idx_).shorty_idx_);
 }
diff --git a/libdexfile/dex/dex_file.h b/libdexfile/dex/dex_file.h
index 6a52f67..b3e7ad4 100644
--- a/libdexfile/dex/dex_file.h
+++ b/libdexfile/dex/dex_file.h
@@ -641,6 +641,8 @@
 
   // Returns the name of a method id.
   const char* GetMethodName(const MethodId& method_id) const;
+  const char* GetMethodName(const MethodId& method_id, uint32_t* utf_length) const;
+  const char* GetMethodName(uint32_t idx, uint32_t* utf_length) const;
 
   // Returns the shorty of a method by its index.
   const char* GetMethodShorty(uint32_t idx) const;
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index e655052..e33e407 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -630,9 +630,14 @@
   // If we do not have a dex_cache match, try to find the declared method in this class now.
   if (this_dex_cache != dex_cache && !GetDeclaredMethodsSlice(pointer_size).empty()) {
     DCHECK(name.empty());
-    name = dex_file.StringDataByIdx(method_id.name_idx_);
+    // Avoid string comparisons by comparing the respective unicode lengths first.
+    uint32_t length, other_length;  // UTF16 length.
+    name = dex_file.GetMethodName(method_id, &length);
     for (ArtMethod& method : GetDeclaredMethodsSlice(pointer_size)) {
-      if (method.GetName() == name && method.GetSignature() == signature) {
+      DCHECK_NE(method.GetDexMethodIndex(), dex::kDexNoIndex);
+      const char* other_name = method.GetDexFile()->GetMethodName(
+          method.GetDexMethodIndex(), &other_length);
+      if (length == other_length && name == other_name && signature == method.GetSignature()) {
         return &method;
       }
     }