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