1 /* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ART_LIBDEXFILE_DEX_METHOD_REFERENCE_H_ 18 #define ART_LIBDEXFILE_DEX_METHOD_REFERENCE_H_ 19 20 #include <stdint.h> 21 #include <string> 22 #include "dex/dex_file.h" 23 #include "dex/dex_file_reference.h" 24 #include "dex/proto_reference.h" 25 26 namespace art { 27 28 // A method is uniquely located by its DexFile and the method_ids_ table index into that DexFile 29 class MethodReference : public DexFileReference { 30 public: MethodReference(const DexFile * file,uint32_t index)31 MethodReference(const DexFile* file, uint32_t index) : DexFileReference(file, index) {} 32 std::string PrettyMethod(bool with_signature = true) const { 33 return dex_file->PrettyMethod(index, with_signature); 34 } GetMethodId()35 const dex::MethodId& GetMethodId() const { 36 return dex_file->GetMethodId(index); 37 } GetProtoReference()38 const art::ProtoReference GetProtoReference() const { 39 return ProtoReference(dex_file, GetMethodId().proto_idx_); 40 } 41 }; 42 43 // Compare the actual referenced method signatures. Used for method reference deduplication. 44 struct MethodReferenceValueComparator { operatorMethodReferenceValueComparator45 bool operator()(MethodReference mr1, MethodReference mr2) const { 46 if (mr1.dex_file == mr2.dex_file) { 47 DCHECK_EQ(mr1.index < mr2.index, SlowCompare(mr1, mr2)); 48 return mr1.index < mr2.index; 49 } else { 50 return SlowCompare(mr1, mr2); 51 } 52 } 53 SlowCompareMethodReferenceValueComparator54 bool SlowCompare(MethodReference mr1, MethodReference mr2) const { 55 // The order is the same as for method ids in a single dex file. 56 // Compare the class descriptors first. 57 const dex::MethodId& mid1 = mr1.GetMethodId(); 58 const dex::MethodId& mid2 = mr2.GetMethodId(); 59 int descriptor_diff = DexFile::CompareDescriptors( 60 mr1.dex_file->GetTypeDescriptorView(mid1.class_idx_), 61 mr2.dex_file->GetTypeDescriptorView(mid2.class_idx_)); 62 if (descriptor_diff != 0) { 63 return descriptor_diff < 0; 64 } 65 // Compare names second. 66 int name_diff = DexFile::CompareMemberNames(mr1.dex_file->GetMethodNameView(mid1), 67 mr2.dex_file->GetMethodNameView(mid2)); 68 if (name_diff != 0) { 69 return name_diff < 0; 70 } 71 // Then compare protos. 72 return ProtoReferenceValueComparator()(mr1.GetProtoReference(), mr2.GetProtoReference()); 73 } 74 }; 75 76 } // namespace art 77 78 #endif // ART_LIBDEXFILE_DEX_METHOD_REFERENCE_H_ 79