Force inlining in `InternTable`.

Use function attributes to make sure we inline important
functions in `InternTable`.

Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Bug: 181943478
Change-Id: I09a895c4618a9bb292dc0d60b840f91fdbd9e3be
diff --git a/libartbase/base/hash_set.h b/libartbase/base/hash_set.h
index 37bc5aa..7ed8c61 100644
--- a/libartbase/base/hash_set.h
+++ b/libartbase/base/hash_set.h
@@ -517,7 +517,7 @@
       DCHECK_LT(num_elements_, elements_until_expand_);
     }
     bool find_failed = false;
-    auto find_fail_fn = [&](size_t index) {
+    auto find_fail_fn = [&](size_t index) ALWAYS_INLINE {
       find_failed = true;
       return index;
     };
@@ -544,7 +544,7 @@
       Expand();
       DCHECK_LT(num_elements_, elements_until_expand_);
     }
-    auto find_fail_fn = [](size_t index) { return index; };
+    auto find_fail_fn = [](size_t index) ALWAYS_INLINE { return index; };
     size_t index = FindIndexImpl</*kCanFind=*/ false>(element, hash, find_fail_fn);
     data_[index] = std::forward<U>(element);
     ++num_elements_;
@@ -696,17 +696,19 @@
   // Find the hash table slot for an element, or return NumBuckets() if not found.
   // This value for not found is important so that iterator(this, FindIndex(...)) == end().
   template <typename K>
+  ALWAYS_INLINE
   size_t FindIndex(const K& element, size_t hash) const {
     // Guard against failing to get an element for a non-existing index.
     if (UNLIKELY(NumBuckets() == 0)) {
       return 0;
     }
-    auto fail_fn = [&](size_t index ATTRIBUTE_UNUSED) { return NumBuckets(); };
+    auto fail_fn = [&](size_t index ATTRIBUTE_UNUSED) ALWAYS_INLINE { return NumBuckets(); };
     return FindIndexImpl(element, hash, fail_fn);
   }
 
   // Find the hash table slot for an element, or return an empty slot index if not found.
   template <bool kCanFind = true, typename K, typename FailFn>
+  ALWAYS_INLINE
   size_t FindIndexImpl(const K& element, size_t hash, FailFn fail_fn) const {
     DCHECK_NE(NumBuckets(), 0u);
     DCHECK_EQ(hashfn_(element), hash);
diff --git a/runtime/intern_table-inl.h b/runtime/intern_table-inl.h
index daab3fa..84b730e 100644
--- a/runtime/intern_table-inl.h
+++ b/runtime/intern_table-inl.h
@@ -28,6 +28,7 @@
 
 namespace art {
 
+ALWAYS_INLINE
 inline uint32_t InternTable::Utf8String::Hash(uint32_t utf16_length, const char* utf8_data) {
   DCHECK_EQ(utf16_length, CountModifiedUtf8Chars(utf8_data));
   if (LIKELY(utf8_data[utf16_length] == 0)) {
@@ -39,6 +40,7 @@
   }
 }
 
+ALWAYS_INLINE
 inline size_t InternTable::StringHash::operator()(const GcRoot<mirror::String>& root) const {
   if (kIsDebugBuild) {
     Locks::mutator_lock_->AssertSharedHeld(Thread::Current());
@@ -50,6 +52,7 @@
   return static_cast<uint32_t>(hash);
 }
 
+ALWAYS_INLINE
 inline bool InternTable::StringEquals::operator()(const GcRoot<mirror::String>& a,
                                                   const GcRoot<mirror::String>& b) const {
   if (kIsDebugBuild) {
@@ -58,6 +61,7 @@
   return a.Read<kWithoutReadBarrier>()->Equals(b.Read<kWithoutReadBarrier>());
 }
 
+ALWAYS_INLINE
 inline bool InternTable::StringEquals::operator()(const GcRoot<mirror::String>& a,
                                                   const Utf8String& b) const {
   if (kIsDebugBuild) {
diff --git a/runtime/intern_table.cc b/runtime/intern_table.cc
index 7e950cf..14b8315 100644
--- a/runtime/intern_table.cc
+++ b/runtime/intern_table.cc
@@ -331,6 +331,7 @@
   LOG(FATAL) << "Attempting to remove non-interned string " << s->ToModifiedUtf8();
 }
 
+FLATTEN
 ObjPtr<mirror::String> InternTable::Table::Find(ObjPtr<mirror::String> s,
                                                 uint32_t hash,
                                                 size_t num_searched_frozen_tables) {
@@ -348,6 +349,7 @@
   return nullptr;
 }
 
+FLATTEN
 ObjPtr<mirror::String> InternTable::Table::Find(const Utf8String& string, uint32_t hash) {
   Locks::intern_table_lock_->AssertHeld(Thread::Current());
   for (InternalTable& table : tables_) {