blob: ad293833cfb26a6e593f68160c4b698d67241cfc [file] [log] [blame]
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001// Copyright 2011 Google Inc. All Rights Reserved.
2
3#ifndef ART_SRC_CLASS_LINKER_H_
4#define ART_SRC_CLASS_LINKER_H_
5
6#include <map>
7#include <utility>
8#include <vector>
9
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070010#include "dex_file.h"
Brian Carlstrom7e93b502011-08-04 14:16:22 -070011#include "heap.h"
12#include "intern_table.h"
13#include "macros.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070014#include "object.h"
Brian Carlstrom7e93b502011-08-04 14:16:22 -070015#include "thread.h"
16#include "unordered_map.h"
Brian Carlstroma663ea52011-08-19 23:33:41 -070017#include "unordered_set.h"
Brian Carlstrom7e93b502011-08-04 14:16:22 -070018
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070019#include "gtest/gtest.h"
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070020
21namespace art {
22
23class ClassLinker {
24 public:
Brian Carlstroma663ea52011-08-19 23:33:41 -070025 // Initializes the class linker using DexFile and an optional boot Space.
26 static ClassLinker* Create(const std::vector<DexFile*>& boot_class_path, Space* boot_space);
Carl Shapiro61e019d2011-07-14 16:53:09 -070027
Elliott Hughesde69d7f2011-08-18 16:49:37 -070028 ~ClassLinker() {
29 delete classes_lock_;
Brian Carlstroma663ea52011-08-19 23:33:41 -070030 String::ResetClass();
31 BooleanArray::ResetArrayClass();
32 ByteArray::ResetArrayClass();
33 CharArray::ResetArrayClass();
34 DoubleArray::ResetArrayClass();
35 FloatArray::ResetArrayClass();
36 IntArray::ResetArrayClass();
37 LongArray::ResetArrayClass();
38 ShortArray::ResetArrayClass();
Elliott Hughesde69d7f2011-08-18 16:49:37 -070039 }
Carl Shapiro565f5072011-07-10 13:39:43 -070040
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070041 // Finds a class by its descriptor name.
Brian Carlstrom74eb46a2011-08-02 20:10:14 -070042 // If class_loader is null, searches boot_class_path_.
Brian Carlstrom6cc18452011-07-18 15:10:33 -070043 Class* FindClass(const StringPiece& descriptor,
Brian Carlstrom74eb46a2011-08-02 20:10:14 -070044 ClassLoader* class_loader);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070045
Elliott Hughesd8ddfd52011-08-15 14:32:53 -070046 Class* FindPrimitiveClass(char type);
47
Brian Carlstrom6cc18452011-07-18 15:10:33 -070048 Class* FindSystemClass(const StringPiece& descriptor) {
Brian Carlstrom74eb46a2011-08-02 20:10:14 -070049 return FindClass(descriptor, NULL);
Carl Shapiro565f5072011-07-10 13:39:43 -070050 }
51
Elliott Hughesf4c21c92011-08-19 17:31:31 -070052 // Returns true on success, false if there's an exception pending.
53 bool EnsureInitialized(Class* c);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070054
Brian Carlstrom4a96b602011-07-26 16:40:23 -070055 void RegisterDexFile(const DexFile* dex_file);
Brian Carlstroma663ea52011-08-19 23:33:41 -070056 void RegisterDexFile(const DexFile* dex_file, DexCache* dex_cache);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070057
Brian Carlstroma663ea52011-08-19 23:33:41 -070058 const InternTable& GetInternTable() {
59 return intern_table_;
60 }
61
62 void VisitRoots(Heap::RootVistor* root_visitor, void* arg) const;
Brian Carlstrom75cb3b42011-07-28 02:13:36 -070063
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070064 private:
Elliott Hughesd8ddfd52011-08-15 14:32:53 -070065 ClassLinker()
66 : classes_lock_(Mutex::Create("ClassLinker::Lock")),
Brian Carlstroma663ea52011-08-19 23:33:41 -070067 class_roots_(NULL),
Elliott Hughesd8ddfd52011-08-15 14:32:53 -070068 init_done_(false) {
Brian Carlstrom7e93b502011-08-04 14:16:22 -070069 }
Carl Shapiro61e019d2011-07-14 16:53:09 -070070
Brian Carlstroma663ea52011-08-19 23:33:41 -070071 // Initialize class linker from DexFile instances.
Carl Shapiro2ed144c2011-07-26 16:52:08 -070072 void Init(const std::vector<DexFile*>& boot_class_path_);
Carl Shapiro61e019d2011-07-14 16:53:09 -070073
Brian Carlstroma663ea52011-08-19 23:33:41 -070074 // Initialize class linker from pre-initialized space.
75 void Init(const std::vector<DexFile*>& boot_class_path_, Space* space);
76 static void InitCallback(Object *obj, void *arg);
77 struct InitCallbackState;
78
79 void FinishInit();
80
Elliott Hughesf4c21c92011-08-19 17:31:31 -070081 bool InitializeClass(Class* klass);
82
Brian Carlstrom75cb3b42011-07-28 02:13:36 -070083 // For early bootstrapping by Init
84 Class* AllocClass(Class* java_lang_Class);
85
86 // Alloc* convenience functions to avoid needing to pass in Class*
87 // values that are known to the ClassLinker such as
88 // kObjectArrayClass and kJavaLangString etc.
89 Class* AllocClass();
Brian Carlstroma663ea52011-08-19 23:33:41 -070090 DexCache* AllocDexCache(const DexFile* dex_file);
Jesse Wilson35baaab2011-08-10 16:18:03 -040091 Field* AllocField();
Brian Carlstrom75cb3b42011-07-28 02:13:36 -070092 Method* AllocMethod();
Brian Carlstrom75cb3b42011-07-28 02:13:36 -070093 template <class T>
94 ObjectArray<T>* AllocObjectArray(size_t length) {
Brian Carlstroma663ea52011-08-19 23:33:41 -070095 return ObjectArray<T>::Alloc(GetClassRoot(kObjectArrayClass), length);
Brian Carlstrom75cb3b42011-07-28 02:13:36 -070096 }
Brian Carlstrom74eb46a2011-08-02 20:10:14 -070097 PathClassLoader* AllocPathClassLoader(std::vector<const DexFile*> dex_files);
Brian Carlstrom75cb3b42011-07-28 02:13:36 -070098
Brian Carlstrom9cff8e12011-08-18 16:47:29 -070099 Class* CreatePrimitiveClass(const char* descriptor);
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700100
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700101 Class* CreateArrayClass(const StringPiece& descriptor,
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700102 ClassLoader* class_loader);
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700103
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700104 const DexFile& FindDexFile(const DexCache* dex_cache) const;
Brian Carlstrom934486c2011-07-12 23:42:50 -0700105
Brian Carlstromf615a612011-07-23 12:50:34 -0700106 DexCache* FindDexCache(const DexFile* dex_file) const;
Brian Carlstrom934486c2011-07-12 23:42:50 -0700107
Brian Carlstroma663ea52011-08-19 23:33:41 -0700108 void AppendToBootClassPath(const DexFile* dex_file);
109 void AppendToBootClassPath(const DexFile* dex_file, DexCache* dex_cache);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700110
Brian Carlstromf615a612011-07-23 12:50:34 -0700111 void LoadClass(const DexFile& dex_file,
112 const DexFile::ClassDef& dex_class_def,
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700113 Class* klass,
114 ClassLoader* class_loader);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700115
Brian Carlstromf615a612011-07-23 12:50:34 -0700116 void LoadInterfaces(const DexFile& dex_file,
117 const DexFile::ClassDef& dex_class_def,
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700118 Class *klass);
119
Brian Carlstromf615a612011-07-23 12:50:34 -0700120 void LoadField(const DexFile& dex_file,
121 const DexFile::Field& dex_field,
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700122 Class* klass,
123 Field* dst);
124
Brian Carlstromf615a612011-07-23 12:50:34 -0700125 void LoadMethod(const DexFile& dex_file,
126 const DexFile::Method& dex_method,
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700127 Class* klass,
128 Method* dst);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700129
Brian Carlstrom7e93b502011-08-04 14:16:22 -0700130 Class* ResolveClass(const Class* referring,
131 uint32_t class_idx,
132 const DexFile& dex_file);
133
134 String* ResolveString(const Class* referring,
135 uint32_t string_idx,
136 const DexFile& dex_file);
137
138 Class* LookupClass(const StringPiece& descriptor, ClassLoader* class_loader);
139
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700140 // Inserts a class into the class table. Returns true if the class
141 // was inserted.
Brian Carlstrom9cff8e12011-08-18 16:47:29 -0700142 bool InsertClass(const StringPiece& descriptor, Class* klass);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700143
144 bool InitializeSuperClass(Class* klass);
145
146 void InitializeStaticFields(Class* klass);
147
148 bool ValidateSuperClassDescriptors(const Class* klass);
149
150 bool HasSameDescriptorClasses(const char* descriptor,
151 const Class* klass1,
152 const Class* klass2);
153
154 bool HasSameMethodDescriptorClasses(const Method* descriptor,
155 const Class* klass1,
156 const Class* klass2);
157
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700158 bool LinkClass(Class* klass, const DexFile& dex_file);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700159
160 bool LinkSuperClass(Class* klass);
161
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700162 bool LoadSuperAndInterfaces(Class* klass, const DexFile& dex_file);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700163
164 bool LinkMethods(Class* klass);
165
166 bool LinkVirtualMethods(Class* klass);
167
168 bool LinkInterfaceMethods(Class* klass);
169
170 void LinkAbstractMethods(Class* klass);
171
Jesse Wilson7833bd22011-08-09 18:31:44 -0400172 bool LinkStaticFields(Class* klass);
173
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700174 bool LinkInstanceFields(Class* klass);
175
176 void CreateReferenceOffsets(Class* klass);
177
Brian Carlstrom4a96b602011-07-26 16:40:23 -0700178 std::vector<const DexFile*> boot_class_path_;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700179
Brian Carlstrom4a96b602011-07-26 16:40:23 -0700180 std::vector<const DexFile*> dex_files_;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700181
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700182 std::vector<DexCache*> dex_caches_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700183
Brian Carlstrom9cff8e12011-08-18 16:47:29 -0700184 // multimap from a StringPiece hash code of a class descriptor to
185 // Class* instances. Results should be compared for a matching
186 // Class::descriptor_ and Class::class_loader_.
187 typedef std::tr1::unordered_multimap<size_t, Class*> Table;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700188 Table classes_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700189 Mutex* classes_lock_;
190
Brian Carlstrom7e93b502011-08-04 14:16:22 -0700191 InternTable intern_table_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700192
Brian Carlstroma663ea52011-08-19 23:33:41 -0700193 // indexes into class_roots_.
194 // needs to be kept in sync with class_roots_descriptors_.
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700195 enum ClassRoot {
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700196 kJavaLangClass,
197 kJavaLangObject,
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700198 kObjectArrayClass,
199 kJavaLangString,
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700200 kJavaLangReflectField,
201 kJavaLangReflectMethod,
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700202 kJavaLangClassLoader,
203 kDalvikSystemBaseDexClassLoader,
204 kDalvikSystemPathClassLoader,
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700205 kPrimitiveBoolean,
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700206 kPrimitiveByte,
Elliott Hughesd8ddfd52011-08-15 14:32:53 -0700207 kPrimitiveChar,
208 kPrimitiveDouble,
209 kPrimitiveFloat,
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700210 kPrimitiveInt,
211 kPrimitiveLong,
Elliott Hughesd8ddfd52011-08-15 14:32:53 -0700212 kPrimitiveShort,
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700213 kPrimitiveVoid,
Elliott Hughesd8ddfd52011-08-15 14:32:53 -0700214 kBooleanArrayClass,
215 kByteArrayClass,
216 kCharArrayClass,
217 kDoubleArrayClass,
218 kFloatArrayClass,
219 kIntArrayClass,
220 kLongArrayClass,
221 kShortArrayClass,
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700222 kClassRootsMax,
223 };
224 ObjectArray<Class>* class_roots_;
Brian Carlstrom913af1b2011-07-23 21:41:13 -0700225
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700226 Class* GetClassRoot(ClassRoot class_root) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700227 DCHECK(class_roots_ != NULL);
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700228 Class* klass = class_roots_->Get(class_root);
229 DCHECK(klass != NULL);
230 return klass;
231 }
232
Brian Carlstroma663ea52011-08-19 23:33:41 -0700233 void SetClassRoot(ClassRoot class_root, Class* klass) {
234 DCHECK(!init_done_);
235
236 DCHECK(klass != NULL);
237 DCHECK(klass->class_loader_ == NULL);
238 DCHECK(klass->descriptor_ != NULL);
239 DCHECK(klass->descriptor_->Equals(GetClassRootDescriptor(class_root)));
240
241 DCHECK(class_roots_ != NULL);
242 DCHECK(class_roots_->Get(class_root) == NULL);
243 class_roots_->Set(class_root, klass);
244 }
245
246 static const char* class_roots_descriptors_[kClassRootsMax];
247
248 const char* GetClassRootDescriptor(ClassRoot class_root) {
249 const char* descriptor = class_roots_descriptors_[class_root];
250 CHECK(descriptor != NULL);
251 return descriptor;
252 }
253
Brian Carlstrom4a96b602011-07-26 16:40:23 -0700254 ObjectArray<Class>* array_interfaces_;
Brian Carlstrom913af1b2011-07-23 21:41:13 -0700255 InterfaceEntry* array_iftable_;
Carl Shapiro565f5072011-07-10 13:39:43 -0700256
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700257 bool init_done_;
258
Brian Carlstromf734cf52011-08-17 16:28:14 -0700259 friend class CommonTest;
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700260 FRIEND_TEST(DexCacheTest, Open);
261 friend class ObjectTest;
262 FRIEND_TEST(ObjectTest, AllocObjectArray);
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700263 FRIEND_TEST(ExceptionTest, MyClass_F_G);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700264 DISALLOW_COPY_AND_ASSIGN(ClassLinker);
265};
266
267} // namespace art
268
269#endif // ART_SRC_CLASS_LINKER_H_