Make some hash/equals operators inline.

Namely class descriptor hash/equals in ClassTable and
string hash/equals in InternTable.

This should reduce reliance on ThinLTO for performance.

Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Bug: 179799979
Bug: 179837605
Change-Id: Ie513b2312d30e1b52efefd705a26d13035789e4a
diff --git a/runtime/class_table-inl.h b/runtime/class_table-inl.h
index d043af3..3645b64 100644
--- a/runtime/class_table-inl.h
+++ b/runtime/class_table-inl.h
@@ -20,6 +20,7 @@
 #include "class_table.h"
 
 #include "base/mutex-inl.h"
+#include "dex/utf.h"
 #include "gc_root-inl.h"
 #include "mirror/class.h"
 #include "oat_file.h"
@@ -27,6 +28,44 @@
 
 namespace art {
 
+inline uint32_t ClassTable::ClassDescriptorHash::operator()(const TableSlot& slot) const {
+  std::string temp;
+  // No read barrier needed, we're reading a chain of constant references for comparison
+  // with null and retrieval of constant primitive data. See ReadBarrierOption.
+  return ComputeModifiedUtf8Hash(slot.Read<kWithoutReadBarrier>()->GetDescriptor(&temp));
+}
+
+inline uint32_t ClassTable::ClassDescriptorHash::operator()(const DescriptorHashPair& pair) const {
+  DCHECK_EQ(ComputeModifiedUtf8Hash(pair.first), pair.second);
+  return pair.second;
+}
+
+inline bool ClassTable::ClassDescriptorEquals::operator()(const TableSlot& a,
+                                                          const TableSlot& b) const {
+  // No read barrier needed, we're reading a chain of constant references for comparison
+  // with null and retrieval of constant primitive data. See ReadBarrierOption.
+  if (a.Hash() != b.Hash()) {
+    std::string temp;
+    DCHECK(!a.Read<kWithoutReadBarrier>()->DescriptorEquals(
+        b.Read<kWithoutReadBarrier>()->GetDescriptor(&temp)));
+    return false;
+  }
+  std::string temp;
+  return a.Read<kWithoutReadBarrier>()->DescriptorEquals(
+      b.Read<kWithoutReadBarrier>()->GetDescriptor(&temp));
+}
+
+inline bool ClassTable::ClassDescriptorEquals::operator()(const TableSlot& a,
+                                                          const DescriptorHashPair& b) const {
+  // No read barrier needed, we're reading a chain of constant references for comparison
+  // with null and retrieval of constant primitive data. See ReadBarrierOption.
+  if (!a.MaskedHashEquals(b.second)) {
+    DCHECK(!a.Read<kWithoutReadBarrier>()->DescriptorEquals(b.first));
+    return false;
+  }
+  return a.Read<kWithoutReadBarrier>()->DescriptorEquals(b.first);
+}
+
 template<class Visitor>
 void ClassTable::VisitRoots(Visitor& visitor) {
   ReaderMutexLock mu(Thread::Current(), lock_);
diff --git a/runtime/class_table.cc b/runtime/class_table.cc
index fc2640c..288e312 100644
--- a/runtime/class_table.cc
+++ b/runtime/class_table.cc
@@ -164,44 +164,6 @@
   return false;
 }
 
-uint32_t ClassTable::ClassDescriptorHash::operator()(const TableSlot& slot)
-    const {
-  std::string temp;
-  // No read barrier needed, we're reading a chain of constant references for comparison
-  // with null and retrieval of constant primitive data. See ReadBarrierOption.
-  return ComputeModifiedUtf8Hash(slot.Read<kWithoutReadBarrier>()->GetDescriptor(&temp));
-}
-
-uint32_t ClassTable::ClassDescriptorHash::operator()(const DescriptorHashPair& pair) const {
-  DCHECK_EQ(ComputeModifiedUtf8Hash(pair.first), pair.second);
-  return pair.second;
-}
-
-bool ClassTable::ClassDescriptorEquals::operator()(const TableSlot& a, const TableSlot& b) const {
-  // No read barrier needed, we're reading a chain of constant references for comparison
-  // with null and retrieval of constant primitive data. See ReadBarrierOption.
-  if (a.Hash() != b.Hash()) {
-    std::string temp;
-    DCHECK(!a.Read<kWithoutReadBarrier>()->DescriptorEquals(
-        b.Read<kWithoutReadBarrier>()->GetDescriptor(&temp)));
-    return false;
-  }
-  std::string temp;
-  return a.Read<kWithoutReadBarrier>()->DescriptorEquals(
-      b.Read<kWithoutReadBarrier>()->GetDescriptor(&temp));
-}
-
-bool ClassTable::ClassDescriptorEquals::operator()(const TableSlot& a,
-                                                   const DescriptorHashPair& b) const {
-  // No read barrier needed, we're reading a chain of constant references for comparison
-  // with null and retrieval of constant primitive data. See ReadBarrierOption.
-  if (!a.MaskedHashEquals(b.second)) {
-    DCHECK(!a.Read<kWithoutReadBarrier>()->DescriptorEquals(b.first));
-    return false;
-  }
-  return a.Read<kWithoutReadBarrier>()->DescriptorEquals(b.first);
-}
-
 bool ClassTable::InsertStrongRoot(ObjPtr<mirror::Object> obj) {
   WriterMutexLock mu(Thread::Current(), lock_);
   DCHECK(obj != nullptr);
diff --git a/runtime/gc/space/image_space_test.cc b/runtime/gc/space/image_space_test.cc
index 6208a73..0b22a6f 100644
--- a/runtime/gc/space/image_space_test.cc
+++ b/runtime/gc/space/image_space_test.cc
@@ -24,7 +24,7 @@
 #include "class_linker.h"
 #include "dexopt_test.h"
 #include "dex/utf.h"
-#include "intern_table.h"
+#include "intern_table-inl.h"
 #include "noop_compiler_callbacks.h"
 #include "oat_file.h"
 
diff --git a/runtime/intern_table-inl.h b/runtime/intern_table-inl.h
index 687f5ee..44bdb1f 100644
--- a/runtime/intern_table-inl.h
+++ b/runtime/intern_table-inl.h
@@ -19,12 +19,61 @@
 
 #include "intern_table.h"
 
+#include "dex/utf.h"
 #include "gc/space/image_space.h"
+#include "gc_root-inl.h"
 #include "image.h"
-#include "mirror/string-inl.h"  // Required for ToModifiedUtf8 below.
+#include "mirror/string-inl.h"
+#include "thread-current-inl.h"
 
 namespace art {
 
+inline std::size_t InternTable::StringHash::operator()(const GcRoot<mirror::String>& root) const {
+  if (kIsDebugBuild) {
+    Locks::mutator_lock_->AssertSharedHeld(Thread::Current());
+  }
+  // An additional cast to prevent undesired sign extension.
+  return static_cast<size_t>(
+      static_cast<uint32_t>(root.Read<kWithoutReadBarrier>()->GetHashCode()));
+}
+
+inline bool InternTable::StringEquals::operator()(const GcRoot<mirror::String>& a,
+                                                  const GcRoot<mirror::String>& b) const {
+  if (kIsDebugBuild) {
+    Locks::mutator_lock_->AssertSharedHeld(Thread::Current());
+  }
+  return a.Read<kWithoutReadBarrier>()->Equals(b.Read<kWithoutReadBarrier>());
+}
+
+inline bool InternTable::StringEquals::operator()(const GcRoot<mirror::String>& a,
+                                                  const Utf8String& b) const {
+  if (kIsDebugBuild) {
+    Locks::mutator_lock_->AssertSharedHeld(Thread::Current());
+  }
+  ObjPtr<mirror::String> a_string = a.Read<kWithoutReadBarrier>();
+  uint32_t a_length = static_cast<uint32_t>(a_string->GetLength());
+  if (a_length != b.GetUtf16Length()) {
+    return false;
+  }
+  if (a_string->IsCompressed()) {
+    size_t b_byte_count = strlen(b.GetUtf8Data());
+    size_t b_utf8_length = CountModifiedUtf8Chars(b.GetUtf8Data(), b_byte_count);
+    // Modified UTF-8 single byte character range is 0x01 .. 0x7f
+    // The string compression occurs on regular ASCII with same exact range,
+    // not on extended ASCII which up to 0xff
+    const bool is_b_regular_ascii = (b_byte_count == b_utf8_length);
+    if (is_b_regular_ascii) {
+      return memcmp(b.GetUtf8Data(),
+                    a_string->GetValueCompressed(), a_length * sizeof(uint8_t)) == 0;
+    } else {
+      return false;
+    }
+  } else {
+    const uint16_t* a_value = a_string->GetValue();
+    return CompareModifiedUtf8ToUtf16AsCodePointValues(b.GetUtf8Data(), a_value, a_length) == 0;
+  }
+}
+
 template <typename Visitor>
 inline void InternTable::AddImageStringsToTable(gc::space::ImageSpace* image_space,
                                                 const Visitor& visitor) {
diff --git a/runtime/intern_table.cc b/runtime/intern_table.cc
index b11de51..6af0455 100644
--- a/runtime/intern_table.cc
+++ b/runtime/intern_table.cc
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "intern_table.h"
+#include "intern_table-inl.h"
 
 #include <memory>
 
@@ -100,8 +100,8 @@
 }
 
 ObjPtr<mirror::String> InternTable::LookupStrong(Thread* self,
-                                          uint32_t utf16_length,
-                                          const char* utf8_data) {
+                                                 uint32_t utf16_length,
+                                                 const char* utf8_data) {
   DCHECK_EQ(utf16_length, CountModifiedUtf8Chars(utf8_data));
   Utf8String string(utf16_length,
                     utf8_data,
@@ -307,52 +307,6 @@
   weak_interns_.SweepWeaks(visitor);
 }
 
-std::size_t InternTable::StringHash::operator()(const GcRoot<mirror::String>& root) const {
-  if (kIsDebugBuild) {
-    Locks::mutator_lock_->AssertSharedHeld(Thread::Current());
-  }
-  // An additional cast to prevent undesired sign extension.
-  return static_cast<size_t>(
-      static_cast<uint32_t>(root.Read<kWithoutReadBarrier>()->GetHashCode()));
-}
-
-bool InternTable::StringEquals::operator()(const GcRoot<mirror::String>& a,
-                                           const GcRoot<mirror::String>& b) const {
-  if (kIsDebugBuild) {
-    Locks::mutator_lock_->AssertSharedHeld(Thread::Current());
-  }
-  return a.Read<kWithoutReadBarrier>()->Equals(b.Read<kWithoutReadBarrier>());
-}
-
-bool InternTable::StringEquals::operator()(const GcRoot<mirror::String>& a,
-                                           const Utf8String& b) const {
-  if (kIsDebugBuild) {
-    Locks::mutator_lock_->AssertSharedHeld(Thread::Current());
-  }
-  ObjPtr<mirror::String> a_string = a.Read<kWithoutReadBarrier>();
-  uint32_t a_length = static_cast<uint32_t>(a_string->GetLength());
-  if (a_length != b.GetUtf16Length()) {
-    return false;
-  }
-  if (a_string->IsCompressed()) {
-    size_t b_byte_count = strlen(b.GetUtf8Data());
-    size_t b_utf8_length = CountModifiedUtf8Chars(b.GetUtf8Data(), b_byte_count);
-    // Modified UTF-8 single byte character range is 0x01 .. 0x7f
-    // The string compression occurs on regular ASCII with same exact range,
-    // not on extended ASCII which up to 0xff
-    const bool is_b_regular_ascii = (b_byte_count == b_utf8_length);
-    if (is_b_regular_ascii) {
-      return memcmp(b.GetUtf8Data(),
-                    a_string->GetValueCompressed(), a_length * sizeof(uint8_t)) == 0;
-    } else {
-      return false;
-    }
-  } else {
-    const uint16_t* a_value = a_string->GetValue();
-    return CompareModifiedUtf8ToUtf16AsCodePointValues(b.GetUtf8Data(), a_value, a_length) == 0;
-  }
-}
-
 void InternTable::Table::Remove(ObjPtr<mirror::String> s) {
   for (InternalTable& table : tables_) {
     auto it = table.set_.find(GcRoot<mirror::String>(s));
diff --git a/runtime/intern_table_test.cc b/runtime/intern_table_test.cc
index b64ca7d..e4eed55 100644
--- a/runtime/intern_table_test.cc
+++ b/runtime/intern_table_test.cc
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "intern_table.h"
+#include "intern_table-inl.h"
 
 #include "base/hash_set.h"
 #include "common_runtime_test.h"