diff options
| author | 2014-05-06 11:27:27 -0700 | |
|---|---|---|
| committer | 2014-05-06 14:42:27 -0700 | |
| commit | 151f2214d95f6003fe067fa2ebcd8ddad11e735c (patch) | |
| tree | 0b9d01940d0f483526134e5e1136e69ce9db3c6f /runtime/object_utils.h | |
| parent | 36b65964d128471d917c2efc69c81bc50ef9360b (diff) | |
Improve ValidateSuperClassDescriptors performance.
ValidateSuperClassDescriptors uses FindClass with the 2 class loaders that are
being used in validating method parameter types. The use of 2 class loaders
ensures at least one miss with LookupClass and thereby a call to
ClassLoader.loadClass which will then defer to the parent class loader eating
time. This change modifies the behavior to instead lookup types with a dex
cache, so that resolution and load class are only performed once per type.
Bug: 12804658
Change-Id: Ia7be1f7bab8175a6934fd59fc54e0829beed0198
Diffstat (limited to 'runtime/object_utils.h')
| -rw-r--r-- | runtime/object_utils.h | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/runtime/object_utils.h b/runtime/object_utils.h index 072f074e85..504537a66f 100644 --- a/runtime/object_utils.h +++ b/runtime/object_utils.h @@ -520,8 +520,7 @@ class MethodHelper { return GetParamPrimitiveType(param) == Primitive::kPrimNot; } - bool HasSameNameAndSignature(MethodHelper* other) - SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + bool HasSameNameAndSignature(MethodHelper* other) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { const DexFile& dex_file = GetDexFile(); const DexFile::MethodId& mid = dex_file.GetMethodId(method_->GetDexMethodIndex()); if (GetDexCache() == other->GetDexCache()) { @@ -539,6 +538,33 @@ class MethodHelper { return dex_file.GetMethodSignature(mid) == other_dex_file.GetMethodSignature(other_mid); } + bool HasSameSignatureWithDifferentClassLoaders(MethodHelper* other) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + if (UNLIKELY(GetReturnType() != other->GetReturnType())) { + return false; + } + const DexFile::TypeList* types = GetParameterTypeList(); + const DexFile::TypeList* other_types = other->GetParameterTypeList(); + if (types == nullptr) { + return (other_types == nullptr) || (other_types->Size() == 0); + } else if (UNLIKELY(other_types == nullptr)) { + return types->Size() == 0; + } + uint32_t num_types = types->Size(); + if (UNLIKELY(num_types != other_types->Size())) { + return false; + } + for (uint32_t i = 0; i < num_types; ++i) { + mirror::Class* param_type = GetClassFromTypeIdx(types->GetTypeItem(i).type_idx_); + mirror::Class* other_param_type = + other->GetClassFromTypeIdx(other_types->GetTypeItem(i).type_idx_); + if (UNLIKELY(param_type != other_param_type)) { + return false; + } + } + return true; + } + const DexFile::CodeItem* GetCodeItem() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { return GetDexFile().GetCodeItem(method_->GetCodeItemOffset()); |