blob: e83c850a777a218b8d73d3332e57b675d42492c8 [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"
17
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070018#include "gtest/gtest.h"
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070019
20namespace art {
21
22class ClassLinker {
23 public:
Carl Shapiro565f5072011-07-10 13:39:43 -070024 // Initializes the class linker.
Carl Shapiro2ed144c2011-07-26 16:52:08 -070025 static ClassLinker* Create(const std::vector<DexFile*>& boot_class_path);
Carl Shapiro61e019d2011-07-14 16:53:09 -070026
Elliott Hughesde69d7f2011-08-18 16:49:37 -070027 ~ClassLinker() {
28 delete classes_lock_;
29 }
Carl Shapiro565f5072011-07-10 13:39:43 -070030
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070031 // Finds a class by its descriptor name.
Brian Carlstrom74eb46a2011-08-02 20:10:14 -070032 // If class_loader is null, searches boot_class_path_.
Brian Carlstrom6cc18452011-07-18 15:10:33 -070033 Class* FindClass(const StringPiece& descriptor,
Brian Carlstrom74eb46a2011-08-02 20:10:14 -070034 ClassLoader* class_loader);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070035
Elliott Hughesd8ddfd52011-08-15 14:32:53 -070036 Class* FindPrimitiveClass(char type);
37
Brian Carlstrom6cc18452011-07-18 15:10:33 -070038 Class* FindSystemClass(const StringPiece& descriptor) {
Brian Carlstrom74eb46a2011-08-02 20:10:14 -070039 return FindClass(descriptor, NULL);
Carl Shapiro565f5072011-07-10 13:39:43 -070040 }
41
Elliott Hughesf4c21c92011-08-19 17:31:31 -070042 // Returns true on success, false if there's an exception pending.
43 bool EnsureInitialized(Class* c);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070044
Brian Carlstrom4a96b602011-07-26 16:40:23 -070045 void RegisterDexFile(const DexFile* dex_file);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070046
Brian Carlstrom7e93b502011-08-04 14:16:22 -070047 void VisitRoots(Heap::RootVistor* root_visitor, void* arg);
Brian Carlstrom75cb3b42011-07-28 02:13:36 -070048
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070049 private:
Elliott Hughesd8ddfd52011-08-15 14:32:53 -070050 ClassLinker()
51 : classes_lock_(Mutex::Create("ClassLinker::Lock")),
52 init_done_(false) {
Brian Carlstrom7e93b502011-08-04 14:16:22 -070053 }
Carl Shapiro61e019d2011-07-14 16:53:09 -070054
Carl Shapiro2ed144c2011-07-26 16:52:08 -070055 void Init(const std::vector<DexFile*>& boot_class_path_);
Carl Shapiro61e019d2011-07-14 16:53:09 -070056
Elliott Hughesf4c21c92011-08-19 17:31:31 -070057 bool InitializeClass(Class* klass);
58
Brian Carlstrom75cb3b42011-07-28 02:13:36 -070059 // For early bootstrapping by Init
60 Class* AllocClass(Class* java_lang_Class);
61
62 // Alloc* convenience functions to avoid needing to pass in Class*
63 // values that are known to the ClassLinker such as
64 // kObjectArrayClass and kJavaLangString etc.
65 Class* AllocClass();
66 DexCache* AllocDexCache();
Jesse Wilson35baaab2011-08-10 16:18:03 -040067 Field* AllocField();
Brian Carlstrom75cb3b42011-07-28 02:13:36 -070068 Method* AllocMethod();
Brian Carlstrom75cb3b42011-07-28 02:13:36 -070069 template <class T>
70 ObjectArray<T>* AllocObjectArray(size_t length) {
71 return ObjectArray<T>::Alloc(class_roots_->Get(kObjectArrayClass), length);
72 }
Brian Carlstrom74eb46a2011-08-02 20:10:14 -070073 PathClassLoader* AllocPathClassLoader(std::vector<const DexFile*> dex_files);
Brian Carlstrom75cb3b42011-07-28 02:13:36 -070074
Brian Carlstroma331b3c2011-07-18 17:47:56 -070075 Class* CreatePrimitiveClass(const StringPiece& descriptor);
76
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070077 Class* CreateArrayClass(const StringPiece& descriptor,
Brian Carlstrom74eb46a2011-08-02 20:10:14 -070078 ClassLoader* class_loader);
Brian Carlstroma331b3c2011-07-18 17:47:56 -070079
Brian Carlstrom74eb46a2011-08-02 20:10:14 -070080 const DexFile& FindDexFile(const DexCache* dex_cache) const;
Brian Carlstrom934486c2011-07-12 23:42:50 -070081
Brian Carlstromf615a612011-07-23 12:50:34 -070082 DexCache* FindDexCache(const DexFile* dex_file) const;
Brian Carlstrom934486c2011-07-12 23:42:50 -070083
Brian Carlstromf615a612011-07-23 12:50:34 -070084 void AppendToBootClassPath(DexFile* dex_file);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070085
Brian Carlstromf615a612011-07-23 12:50:34 -070086 void LoadClass(const DexFile& dex_file,
87 const DexFile::ClassDef& dex_class_def,
Brian Carlstrom74eb46a2011-08-02 20:10:14 -070088 Class* klass,
89 ClassLoader* class_loader);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070090
Brian Carlstromf615a612011-07-23 12:50:34 -070091 void LoadInterfaces(const DexFile& dex_file,
92 const DexFile::ClassDef& dex_class_def,
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070093 Class *klass);
94
Brian Carlstromf615a612011-07-23 12:50:34 -070095 void LoadField(const DexFile& dex_file,
96 const DexFile::Field& dex_field,
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070097 Class* klass,
98 Field* dst);
99
Brian Carlstromf615a612011-07-23 12:50:34 -0700100 void LoadMethod(const DexFile& dex_file,
101 const DexFile::Method& dex_method,
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700102 Class* klass,
103 Method* dst);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700104
Brian Carlstrom7e93b502011-08-04 14:16:22 -0700105 Class* ResolveClass(const Class* referring,
106 uint32_t class_idx,
107 const DexFile& dex_file);
108
109 String* ResolveString(const Class* referring,
110 uint32_t string_idx,
111 const DexFile& dex_file);
112
113 Class* LookupClass(const StringPiece& descriptor, ClassLoader* class_loader);
114
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700115 // Inserts a class into the class table. Returns true if the class
116 // was inserted.
117 bool InsertClass(Class* klass);
118
119 bool InitializeSuperClass(Class* klass);
120
121 void InitializeStaticFields(Class* klass);
122
123 bool ValidateSuperClassDescriptors(const Class* klass);
124
125 bool HasSameDescriptorClasses(const char* descriptor,
126 const Class* klass1,
127 const Class* klass2);
128
129 bool HasSameMethodDescriptorClasses(const Method* descriptor,
130 const Class* klass1,
131 const Class* klass2);
132
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700133 bool LinkClass(Class* klass, const DexFile& dex_file);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700134
135 bool LinkSuperClass(Class* klass);
136
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700137 bool LoadSuperAndInterfaces(Class* klass, const DexFile& dex_file);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700138
139 bool LinkMethods(Class* klass);
140
141 bool LinkVirtualMethods(Class* klass);
142
143 bool LinkInterfaceMethods(Class* klass);
144
145 void LinkAbstractMethods(Class* klass);
146
Jesse Wilson7833bd22011-08-09 18:31:44 -0400147 bool LinkStaticFields(Class* klass);
148
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700149 bool LinkInstanceFields(Class* klass);
150
151 void CreateReferenceOffsets(Class* klass);
152
Brian Carlstrom4a96b602011-07-26 16:40:23 -0700153 std::vector<const DexFile*> boot_class_path_;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700154
Brian Carlstrom4a96b602011-07-26 16:40:23 -0700155 std::vector<const DexFile*> dex_files_;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700156
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700157 std::vector<DexCache*> dex_caches_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700158
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700159 // multimap from String::descriptor_ to Class* instances. Results
160 // should be compared for a matching Class::descriptor_ and
161 // Class::class_loader_.
Brian Carlstrom7e93b502011-08-04 14:16:22 -0700162 typedef std::tr1::unordered_multimap<StringPiece, Class*> Table;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700163 Table classes_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700164 Mutex* classes_lock_;
165
Brian Carlstrom7e93b502011-08-04 14:16:22 -0700166 InternTable intern_table_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700167
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700168 // indexes into class_roots_
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700169 enum ClassRoot {
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700170 kJavaLangClass,
171 kJavaLangObject,
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700172 kObjectArrayClass,
173 kJavaLangString,
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700174 kJavaLangReflectField,
175 kJavaLangReflectMethod,
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700176 kJavaLangClassLoader,
177 kDalvikSystemBaseDexClassLoader,
178 kDalvikSystemPathClassLoader,
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700179 kPrimitiveBoolean,
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700180 kPrimitiveByte,
Elliott Hughesd8ddfd52011-08-15 14:32:53 -0700181 kPrimitiveChar,
182 kPrimitiveDouble,
183 kPrimitiveFloat,
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700184 kPrimitiveInt,
185 kPrimitiveLong,
Elliott Hughesd8ddfd52011-08-15 14:32:53 -0700186 kPrimitiveShort,
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700187 kPrimitiveVoid,
Elliott Hughesd8ddfd52011-08-15 14:32:53 -0700188 kBooleanArrayClass,
189 kByteArrayClass,
190 kCharArrayClass,
191 kDoubleArrayClass,
192 kFloatArrayClass,
193 kIntArrayClass,
194 kLongArrayClass,
195 kShortArrayClass,
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700196 kClassRootsMax,
197 };
198 ObjectArray<Class>* class_roots_;
Brian Carlstrom913af1b2011-07-23 21:41:13 -0700199
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700200 Class* GetClassRoot(ClassRoot class_root) {
201 Class* klass = class_roots_->Get(class_root);
202 DCHECK(klass != NULL);
203 return klass;
204 }
205
Brian Carlstrom4a96b602011-07-26 16:40:23 -0700206 ObjectArray<Class>* array_interfaces_;
Brian Carlstrom913af1b2011-07-23 21:41:13 -0700207 InterfaceEntry* array_iftable_;
Carl Shapiro565f5072011-07-10 13:39:43 -0700208
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700209 bool init_done_;
210
Brian Carlstromf734cf52011-08-17 16:28:14 -0700211 friend class CommonTest;
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700212 FRIEND_TEST(DexCacheTest, Open);
213 friend class ObjectTest;
214 FRIEND_TEST(ObjectTest, AllocObjectArray);
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700215 FRIEND_TEST(ExceptionTest, MyClass_F_G);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700216 DISALLOW_COPY_AND_ASSIGN(ClassLinker);
217};
218
219} // namespace art
220
221#endif // ART_SRC_CLASS_LINKER_H_