class_linker.h revision 4a96b60e45fba4a9d4a2e9c8fc849660eacef684
10e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro// Copyright 2011 Google Inc. All Rights Reserved. 20e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 30e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#ifndef ART_SRC_CLASS_LINKER_H_ 40e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#define ART_SRC_CLASS_LINKER_H_ 50e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 60e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#include <map> 70e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#include <utility> 80e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#include <vector> 90e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 104a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom#include "heap.h" 11578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "macros.h" 127e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom#include "dex_file.h" 13578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "thread.h" 14578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "object.h" 15578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "gtest/gtest.h" 160e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 170e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapironamespace art { 180e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 190e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiroclass ClassLinker { 200e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro public: 21565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro // Initializes the class linker. 222ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro static ClassLinker* Create(const std::vector<DexFile*>& boot_class_path); 2361e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 2461e019d291583029c01b61b93bea750f2b663c37Carl Shapiro ~ClassLinker() {} 25565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro 267e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom DexCache* AllocDexCache(); 277e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom Class* AllocClass(DexCache* dex_cache); 28a080803c2f0af91cc0de18919a762f4fcd5cce29Brian Carlstrom StaticField* AllocStaticField(); 29a080803c2f0af91cc0de18919a762f4fcd5cce29Brian Carlstrom InstanceField* AllocInstanceField(); 30a080803c2f0af91cc0de18919a762f4fcd5cce29Brian Carlstrom Method* AllocMethod(); 314a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom template <class C> ObjectArray<C>* AllocObjectArray(size_t length) { 324a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom return Heap::AllocObjectArray<C>(object_array_class_, length); 334a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom } 344a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom 35a080803c2f0af91cc0de18919a762f4fcd5cce29Brian Carlstrom 360e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro // Finds a class by its descriptor name. 37f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom // If dex_file is null, searches boot_class_path_. 386cc18456b6d0d1348ad1d64116b7ab78108ff814Brian Carlstrom Class* FindClass(const StringPiece& descriptor, 39578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom Object* class_loader, 40f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom const DexFile* dex_file); 410e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 426cc18456b6d0d1348ad1d64116b7ab78108ff814Brian Carlstrom Class* FindSystemClass(const StringPiece& descriptor) { 43578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom return FindClass(descriptor, NULL, NULL); 44565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro } 45565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro 460e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro bool InitializeClass(Class* klass); 470e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 486cc18456b6d0d1348ad1d64116b7ab78108ff814Brian Carlstrom Class* LookupClass(const StringPiece& descriptor, Object* class_loader); 490e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 50578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom Class* ResolveClass(const Class* referring, 51578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom uint32_t class_idx, 52f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom const DexFile* dex_file); 535fafe2b12d465cdee6fab76a06c78cef0a6776b6Carl Shapiro 545fafe2b12d465cdee6fab76a06c78cef0a6776b6Carl Shapiro String* ResolveString(const Class* referring, uint32_t string_idx); 550e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 564a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom void RegisterDexFile(const DexFile* dex_file); 570e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 580e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro private: 5961e019d291583029c01b61b93bea750f2b663c37Carl Shapiro ClassLinker() {} 6061e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 612ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro void Init(const std::vector<DexFile*>& boot_class_path_); 6261e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 63a331b3cc392132c7333d36649a8310f38f4822ccBrian Carlstrom Class* CreatePrimitiveClass(const StringPiece& descriptor); 64a331b3cc392132c7333d36649a8310f38f4822ccBrian Carlstrom 65578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom Class* CreateArrayClass(const StringPiece& descriptor, 66578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom Object* class_loader, 67f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom const DexFile* dex_file); 68578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom 69578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom Class* FindPrimitiveClass(char type); 70578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom 71f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom const DexFile* FindDexFile(const DexCache* dex_cache) const; 72578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom 73f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom DexCache* FindDexCache(const DexFile* dex_file) const; 74578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom 75f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom typedef std::pair<const DexFile*, const DexFile::ClassDef*> ClassPathEntry; 76578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom 77f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom void AppendToBootClassPath(DexFile* dex_file); 78578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom 79578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom ClassPathEntry FindInBootClassPath(const StringPiece& descriptor); 80a331b3cc392132c7333d36649a8310f38f4822ccBrian Carlstrom 81f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom void LoadClass(const DexFile& dex_file, 82f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom const DexFile::ClassDef& dex_class_def, 83578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom Class* klass); 84565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro 85f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom void LoadInterfaces(const DexFile& dex_file, 86f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom const DexFile::ClassDef& dex_class_def, 87578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom Class *klass); 88934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom 89f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom void LoadField(const DexFile& dex_file, 90f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom const DexFile::Field& dex_field, 91578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom Class* klass, 92578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom Field* dst); 93934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom 94f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom void LoadMethod(const DexFile& dex_file, 95f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom const DexFile::Method& dex_method, 96578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom Class* klass, 97578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom Method* dst); 98934486cf07c578b6494417ca5dcbae89cf04b019Brian Carlstrom 990e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro // Inserts a class into the class table. Returns true if the class 1000e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro // was inserted. 1010e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro bool InsertClass(Class* klass); 1020e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 1030e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro bool InitializeSuperClass(Class* klass); 1040e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 1050e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro void InitializeStaticFields(Class* klass); 1060e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 1070e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro bool ValidateSuperClassDescriptors(const Class* klass); 1080e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 1090e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro bool HasSameDescriptorClasses(const char* descriptor, 1100e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro const Class* klass1, 1110e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro const Class* klass2); 1120e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 1130e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro bool HasSameMethodDescriptorClasses(const Method* descriptor, 1140e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro const Class* klass1, 1150e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro const Class* klass2); 1160e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 117578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom bool HasSameNameAndPrototype(const Method* m1, const Method* m2) const { 118578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom return HasSameName(m1, m2) && HasSamePrototype(m1, m2); 119578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom } 120578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom 121578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom bool HasSameName(const Method* m1, const Method* m2) const { 122578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom return m1->GetName() == m2->GetName(); 123578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom } 124578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom 125578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom bool HasSamePrototype(const Method* m1, const Method* m2) const { 126578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom return HasSameReturnType(m1, m2) && HasSameArgumentTypes(m1, m2); 127578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom } 128578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom 129578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom bool HasSameReturnType(const Method* m1, const Method* m2) const; 130578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom 131578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom bool HasSameArgumentTypes(const Method* m1, const Method* m2) const; 132578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom 133f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom bool LinkClass(Class* klass, const DexFile* dex_file); 1340e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 1350e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro bool LinkSuperClass(Class* klass); 1360e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 137f615a61aef972cfc1dc23931ac2ed0da14c3fedbBrian Carlstrom bool LinkInterfaces(Class* klass, const DexFile* dex_file); 1380e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 1390e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro bool LinkMethods(Class* klass); 1400e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 1410e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro bool LinkVirtualMethods(Class* klass); 1420e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 1430e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro bool LinkInterfaceMethods(Class* klass); 1440e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 1450e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro void LinkAbstractMethods(Class* klass); 1460e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 1470e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro bool LinkInstanceFields(Class* klass); 1480e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 1490e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro void CreateReferenceOffsets(Class* klass); 1500e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 1514a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom std::vector<const DexFile*> boot_class_path_; 152578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom 1534a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom std::vector<const DexFile*> dex_files_; 154578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom 1557e49dca262933bc30cbc8b9f07cfc8cce2343389Brian Carlstrom std::vector<DexCache*> dex_caches_; 1560e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 1570e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro // TODO: multimap 1586cc18456b6d0d1348ad1d64116b7ab78108ff814Brian Carlstrom typedef std::map<const StringPiece, Class*> Table; 1590e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 1600e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro Table classes_; 1610e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 1620e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro Mutex* classes_lock_; 1630e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 1640e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro // TODO: classpath 1650e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 166a331b3cc392132c7333d36649a8310f38f4822ccBrian Carlstrom Class* java_lang_Class_; 167a331b3cc392132c7333d36649a8310f38f4822ccBrian Carlstrom Class* java_lang_Object_; 168913af1bd90a6e8fd56f1f851db1f098636dae6a5Brian Carlstrom Class* java_lang_reflect_Field_; 169913af1bd90a6e8fd56f1f851db1f098636dae6a5Brian Carlstrom Class* java_lang_reflect_Method_; 170a331b3cc392132c7333d36649a8310f38f4822ccBrian Carlstrom Class* java_lang_Cloneable_; 171a331b3cc392132c7333d36649a8310f38f4822ccBrian Carlstrom Class* java_io_Serializable_; 172a331b3cc392132c7333d36649a8310f38f4822ccBrian Carlstrom Class* java_lang_String_; 173a331b3cc392132c7333d36649a8310f38f4822ccBrian Carlstrom 174565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro Class* primitive_boolean_; 175565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro Class* primitive_char_; 176565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro Class* primitive_float_; 177565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro Class* primitive_double_; 178565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro Class* primitive_byte_; 179565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro Class* primitive_short_; 180565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro Class* primitive_int_; 181565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro Class* primitive_long_; 182565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro Class* primitive_void_; 183565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro 184a080803c2f0af91cc0de18919a762f4fcd5cce29Brian Carlstrom Class* char_array_class_; 185913af1bd90a6e8fd56f1f851db1f098636dae6a5Brian Carlstrom Class* class_array_class_; 186913af1bd90a6e8fd56f1f851db1f098636dae6a5Brian Carlstrom Class* object_array_class_; 187913af1bd90a6e8fd56f1f851db1f098636dae6a5Brian Carlstrom Class* field_array_class_; 188913af1bd90a6e8fd56f1f851db1f098636dae6a5Brian Carlstrom Class* method_array_class_; 189913af1bd90a6e8fd56f1f851db1f098636dae6a5Brian Carlstrom 1904a96b60e45fba4a9d4a2e9c8fc849660eacef684Brian Carlstrom ObjectArray<Class>* array_interfaces_; 191913af1bd90a6e8fd56f1f851db1f098636dae6a5Brian Carlstrom InterfaceEntry* array_iftable_; 192565f50731db360584d0080af7f14f0b7ca10371cCarl Shapiro 193578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom FRIEND_TEST(ClassLinkerTest, ProtoCompare); 194578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom FRIEND_TEST(ClassLinkerTest, ProtoCompare2); 1950e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro DISALLOW_COPY_AND_ASSIGN(ClassLinker); 1960e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro}; 1970e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 1980e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro} // namespace art 1990e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 2000e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#endif // ART_SRC_CLASS_LINKER_H_ 201