Do not resolve name strings in `ArtMethod::GetDeclaredMethodInternal()`. Avoid unnecessary interned strings which are never GC'd. Test: m test-art-host-gtest Test: testrunner.py --host --optimizing Bug: 192658894 Change-Id: I05902a484a99dabccff433749601845cbdef6700
diff --git a/runtime/art_method-inl.h b/runtime/art_method-inl.h index 8dede3a..614a67f 100644 --- a/runtime/art_method-inl.h +++ b/runtime/art_method-inl.h
@@ -220,6 +220,17 @@ return Runtime::Current()->GetClassLinker()->ResolveString(method_id.name_idx_, this); } +inline bool ArtMethod::NameEquals(ObjPtr<mirror::String> name) { + DCHECK(!IsProxyMethod()); + const DexFile* dex_file = GetDexFile(); + const dex::MethodId& method_id = dex_file->GetMethodId(GetDexMethodIndex()); + const dex::StringIndex name_idx = method_id.name_idx_; + uint32_t utf16_length; + const char* utf8_name = dex_file->StringDataAndUtf16LengthByIdx(name_idx, &utf16_length); + return dchecked_integral_cast<uint32_t>(name->GetLength()) == utf16_length && + name->Equals(utf8_name); +} + inline const dex::CodeItem* ArtMethod::GetCodeItem() { if (!HasCodeItem()) { return nullptr;
diff --git a/runtime/art_method.h b/runtime/art_method.h index 5af14b6..7dd19e8 100644 --- a/runtime/art_method.h +++ b/runtime/art_method.h
@@ -621,6 +621,8 @@ ObjPtr<mirror::String> ResolveNameString() REQUIRES_SHARED(Locks::mutator_lock_); + bool NameEquals(ObjPtr<mirror::String> name) REQUIRES_SHARED(Locks::mutator_lock_); + const dex::CodeItem* GetCodeItem() REQUIRES_SHARED(Locks::mutator_lock_); bool IsResolvedTypeIdx(dex::TypeIndex type_idx) REQUIRES_SHARED(Locks::mutator_lock_);
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc index 3199db3..4828ca2 100644 --- a/runtime/mirror/class.cc +++ b/runtime/mirror/class.cc
@@ -1724,14 +1724,11 @@ continue; } ArtMethod* np_method = m.GetInterfaceMethodIfProxy(kPointerSize); - // May cause thread suspension. - ObjPtr<String> np_name = np_method->ResolveNameString(); - if (np_name == nullptr) { - // OOME - DCHECK(self->IsExceptionPending()); - return nullptr; + if (!np_method->NameEquals(h_method_name.Get())) { + continue; } - if (!np_name->Equals(h_method_name.Get()) || !np_method->EqualParameters(h_args)) { + // `ArtMethod::EqualParameters()` may throw when resolving types. + if (!np_method->EqualParameters(h_args)) { if (UNLIKELY(self->IsExceptionPending())) { return nullptr; } @@ -1760,14 +1757,12 @@ if ((modifiers & kAccConstructor) != 0) { continue; } - auto* np_method = m.GetInterfaceMethodIfProxy(kPointerSize); - // May cause thread suspension. - ObjPtr<String> np_name = np_method->ResolveNameString(); - if (np_name == nullptr) { - self->AssertPendingException(); - return nullptr; + ArtMethod* np_method = m.GetInterfaceMethodIfProxy(kPointerSize); + if (!np_method->NameEquals(h_method_name.Get())) { + continue; } - if (!np_name->Equals(h_method_name.Get()) || !np_method->EqualParameters(h_args)) { + // `ArtMethod::EqualParameters()` may throw when resolving types. + if (!np_method->EqualParameters(h_args)) { if (UNLIKELY(self->IsExceptionPending())) { return nullptr; }