diff options
| author | 2013-09-23 12:57:09 -0700 | |
|---|---|---|
| committer | 2013-09-23 12:57:09 -0700 | |
| commit | b605a4f9a8797046ea1aa05f3405a77fb9a80a76 (patch) | |
| tree | 1173f9c050d1bae8bdf8ba8950e0995c42fc97ba | |
| parent | 2e2deeb6df3e5a952c194276146706e63ab644a1 (diff) | |
Avoid std::string allocations in HasSameNameAndSignature.
Creating a signature requires a std::string that's only used for the purpose of
a comparison. Avoid the std::string by comparing the elements of the method's
proto_ids.
Change-Id: I4394df2ac20bb5896936954f68937fad7e9f7e91
| -rw-r--r-- | runtime/object_utils.h | 58 |
1 files changed, 53 insertions, 5 deletions
diff --git a/runtime/object_utils.h b/runtime/object_utils.h index 6ee3016179..c55e10ebc8 100644 --- a/runtime/object_utils.h +++ b/runtime/object_utils.h @@ -569,16 +569,64 @@ class MethodHelper { 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()) { - const DexFile& dex_file = GetDexFile(); - const DexFile::MethodId& mid = dex_file.GetMethodId(method_->GetDexMethodIndex()); const DexFile::MethodId& other_mid = dex_file.GetMethodId(other->method_->GetDexMethodIndex()); return mid.name_idx_ == other_mid.name_idx_ && mid.proto_idx_ == other_mid.proto_idx_; } - StringPiece name(GetName()); - StringPiece other_name(other->GetName()); - return name == other_name && GetSignature() == other->GetSignature(); + const DexFile& other_dex_file = other->GetDexFile(); + const DexFile::MethodId& other_mid = + other_dex_file.GetMethodId(other->method_->GetDexMethodIndex()); + uint32_t length, other_length; + const char* data = dex_file.StringDataAndLengthByIdx(mid.name_idx_, &length); + const char* other_data = other_dex_file.StringDataAndLengthByIdx(other_mid.name_idx_, + &other_length); + if ((length != other_length) || (strcmp(data, other_data) != 0)) { + return false; // Name mismatch. + } + const DexFile::ProtoId& proto_id = dex_file.GetMethodPrototype(mid); + const DexFile::ProtoId& other_proto_id = other_dex_file.GetMethodPrototype(other_mid); + data = dex_file.StringDataAndLengthByIdx(proto_id.shorty_idx_, &length); + other_data = dex_file.StringDataAndLengthByIdx(proto_id.shorty_idx_, &other_length); + if ((length != other_length) || (strcmp(data, other_data) != 0)) { + return false; // Shorty mismatch. + } + const DexFile::TypeId& return_type_id = dex_file.GetTypeId(proto_id.return_type_idx_); + const DexFile::TypeId& other_return_type_id = + other_dex_file.GetTypeId(other_proto_id.return_type_idx_); + data = dex_file.StringDataAndLengthByIdx(return_type_id.descriptor_idx_, &length); + other_data = other_dex_file.StringDataAndLengthByIdx(other_return_type_id.descriptor_idx_, + &other_length); + if ((length != other_length) || (strcmp(data, other_data) != 0)) { + return false; // Return type mismatch. + } + const DexFile::TypeList* params = dex_file.GetProtoParameters(proto_id); + const DexFile::TypeList* other_params = other_dex_file.GetProtoParameters(other_proto_id); + if (params == nullptr) { + return other_params == nullptr; // Check both lists are empty. + } + if (other_params == nullptr) { + return false; // Parameter list size mismatch. + } + uint32_t params_size = params->Size(); + uint32_t other_params_size = other_params->Size(); + if (params_size != other_params_size) { + return false; // Parameter list size mismatch. + } + for (uint32_t i = 0; i < params_size; ++i) { + const DexFile::TypeId& param_id = dex_file.GetTypeId(params->GetTypeItem(i).type_idx_); + const DexFile::TypeId& other_param_id = + other_dex_file.GetTypeId(other_params->GetTypeItem(i).type_idx_); + data = dex_file.StringDataAndLengthByIdx(param_id.descriptor_idx_, &length); + other_data = other_dex_file.StringDataAndLengthByIdx(other_param_id.descriptor_idx_, + &other_length); + if ((length != other_length) || (strcmp(data, other_data) != 0)) { + return false; // Parameter type mismatch. + } + } + return true; } const DexFile::CodeItem* GetCodeItem() |