blob: 87098c6f84d44799a99f7718db521c144c247cf4 [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 Carlstrom4a96b602011-07-26 16:40:23 -070010#include "heap.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070011#include "macros.h"
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070012#include "dex_file.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070013#include "thread.h"
14#include "object.h"
15#include "gtest/gtest.h"
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070016
17namespace art {
18
19class ClassLinker {
20 public:
Carl Shapiro565f5072011-07-10 13:39:43 -070021 // Initializes the class linker.
Carl Shapiro2ed144c2011-07-26 16:52:08 -070022 static ClassLinker* Create(const std::vector<DexFile*>& boot_class_path);
Carl Shapiro61e019d2011-07-14 16:53:09 -070023
24 ~ClassLinker() {}
Carl Shapiro565f5072011-07-10 13:39:43 -070025
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070026 // Finds a class by its descriptor name.
Brian Carlstromf615a612011-07-23 12:50:34 -070027 // If dex_file is null, searches boot_class_path_.
Brian Carlstrom6cc18452011-07-18 15:10:33 -070028 Class* FindClass(const StringPiece& descriptor,
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070029 Object* class_loader,
Brian Carlstromf615a612011-07-23 12:50:34 -070030 const DexFile* dex_file);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070031
Brian Carlstrom6cc18452011-07-18 15:10:33 -070032 Class* FindSystemClass(const StringPiece& descriptor) {
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070033 return FindClass(descriptor, NULL, NULL);
Carl Shapiro565f5072011-07-10 13:39:43 -070034 }
35
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070036 bool InitializeClass(Class* klass);
37
Brian Carlstrom6cc18452011-07-18 15:10:33 -070038 Class* LookupClass(const StringPiece& descriptor, Object* class_loader);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070039
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070040 Class* ResolveClass(const Class* referring,
41 uint32_t class_idx,
Brian Carlstromf615a612011-07-23 12:50:34 -070042 const DexFile* dex_file);
Carl Shapiro5fafe2b2011-07-09 15:34:41 -070043
44 String* ResolveString(const Class* referring, uint32_t string_idx);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070045
Brian Carlstrom4a96b602011-07-26 16:40:23 -070046 void RegisterDexFile(const DexFile* dex_file);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070047
Brian Carlstrom75cb3b42011-07-28 02:13:36 -070048 // TODO replace with heap interface
49 typedef void (RootVistor)(Object* root, void* arg);
Brian Carlstromb88e9442011-07-28 15:15:51 -070050 void VisitRoots(RootVistor* root_visitor, void* arg);
Brian Carlstrom75cb3b42011-07-28 02:13:36 -070051
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070052 private:
Carl Shapiro61e019d2011-07-14 16:53:09 -070053 ClassLinker() {}
54
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
Brian Carlstrom75cb3b42011-07-28 02:13:36 -070057 // For early bootstrapping by Init
58 Class* AllocClass(Class* java_lang_Class);
59
60 // Alloc* convenience functions to avoid needing to pass in Class*
61 // values that are known to the ClassLinker such as
62 // kObjectArrayClass and kJavaLangString etc.
63 Class* AllocClass();
64 DexCache* AllocDexCache();
65 StaticField* AllocStaticField();
66 InstanceField* AllocInstanceField();
67 Method* AllocMethod();
Brian Carlstrom75cb3b42011-07-28 02:13:36 -070068 template <class T>
69 ObjectArray<T>* AllocObjectArray(size_t length) {
70 return ObjectArray<T>::Alloc(class_roots_->Get(kObjectArrayClass), length);
71 }
72
Brian Carlstroma331b3c2011-07-18 17:47:56 -070073 Class* CreatePrimitiveClass(const StringPiece& descriptor);
74
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070075 Class* CreateArrayClass(const StringPiece& descriptor,
76 Object* class_loader,
Brian Carlstromf615a612011-07-23 12:50:34 -070077 const DexFile* dex_file);
Brian Carlstroma331b3c2011-07-18 17:47:56 -070078
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070079 Class* FindPrimitiveClass(char type);
Carl Shapiro565f5072011-07-10 13:39:43 -070080
Brian Carlstromf615a612011-07-23 12:50:34 -070081 const DexFile* FindDexFile(const DexCache* dex_cache) const;
Brian Carlstrom934486c2011-07-12 23:42:50 -070082
Brian Carlstromf615a612011-07-23 12:50:34 -070083 DexCache* FindDexCache(const DexFile* dex_file) const;
Brian Carlstrom934486c2011-07-12 23:42:50 -070084
Brian Carlstromf615a612011-07-23 12:50:34 -070085 typedef std::pair<const DexFile*, const DexFile::ClassDef*> ClassPathEntry;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070086
Brian Carlstromf615a612011-07-23 12:50:34 -070087 void AppendToBootClassPath(DexFile* dex_file);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070088
89 ClassPathEntry FindInBootClassPath(const StringPiece& descriptor);
90
Brian Carlstromf615a612011-07-23 12:50:34 -070091 void LoadClass(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 LoadInterfaces(const DexFile& dex_file,
96 const DexFile::ClassDef& dex_class_def,
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070097 Class *klass);
98
Brian Carlstromf615a612011-07-23 12:50:34 -070099 void LoadField(const DexFile& dex_file,
100 const DexFile::Field& dex_field,
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700101 Class* klass,
102 Field* dst);
103
Brian Carlstromf615a612011-07-23 12:50:34 -0700104 void LoadMethod(const DexFile& dex_file,
105 const DexFile::Method& dex_method,
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700106 Class* klass,
107 Method* dst);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700108
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700109 // Inserts a class into the class table. Returns true if the class
110 // was inserted.
111 bool InsertClass(Class* klass);
112
113 bool InitializeSuperClass(Class* klass);
114
115 void InitializeStaticFields(Class* klass);
116
117 bool ValidateSuperClassDescriptors(const Class* klass);
118
119 bool HasSameDescriptorClasses(const char* descriptor,
120 const Class* klass1,
121 const Class* klass2);
122
123 bool HasSameMethodDescriptorClasses(const Method* descriptor,
124 const Class* klass1,
125 const Class* klass2);
126
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700127 bool HasSameNameAndPrototype(const Method* m1, const Method* m2) const {
128 return HasSameName(m1, m2) && HasSamePrototype(m1, m2);
129 }
130
131 bool HasSameName(const Method* m1, const Method* m2) const {
Jesse Wilsonf7e85a52011-08-01 18:45:58 -0700132 return String::Equals(m1->GetName(), m2->GetName());
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700133 }
134
135 bool HasSamePrototype(const Method* m1, const Method* m2) const {
136 return HasSameReturnType(m1, m2) && HasSameArgumentTypes(m1, m2);
137 }
138
139 bool HasSameReturnType(const Method* m1, const Method* m2) const;
140
141 bool HasSameArgumentTypes(const Method* m1, const Method* m2) const;
142
Brian Carlstromf615a612011-07-23 12:50:34 -0700143 bool LinkClass(Class* klass, const DexFile* dex_file);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700144
145 bool LinkSuperClass(Class* klass);
146
Brian Carlstromf615a612011-07-23 12:50:34 -0700147 bool LinkInterfaces(Class* klass, const DexFile* dex_file);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700148
149 bool LinkMethods(Class* klass);
150
151 bool LinkVirtualMethods(Class* klass);
152
153 bool LinkInterfaceMethods(Class* klass);
154
155 void LinkAbstractMethods(Class* klass);
156
157 bool LinkInstanceFields(Class* klass);
158
159 void CreateReferenceOffsets(Class* klass);
160
Brian Carlstrom4a96b602011-07-26 16:40:23 -0700161 std::vector<const DexFile*> boot_class_path_;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700162
Brian Carlstrom4a96b602011-07-26 16:40:23 -0700163 std::vector<const DexFile*> dex_files_;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700164
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700165 std::vector<DexCache*> dex_caches_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700166
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700167 // TODO: unordered_multimap
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700168 typedef std::map<const StringPiece, Class*> Table;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700169
170 Table classes_;
171
172 Mutex* classes_lock_;
173
174 // TODO: classpath
175
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700176 // indexes into class_roots_
177 enum ClassRoots {
178 kJavaLangClass,
179 kJavaLangObject,
180 kJavaLangReflectField,
181 kJavaLangReflectMethod,
182 kJavaLangString,
183 kPrimitiveBoolean,
184 kPrimitiveChar,
185 kPrimitiveFloat,
186 kPrimitiveDouble,
187 kPrimitiveByte,
188 kPrimitiveShort,
189 kPrimitiveInt,
190 kPrimitiveLong,
191 kPrimitiveVoid,
192 kObjectArrayClass,
193 kCharArrayClass,
194 kClassRootsMax,
195 };
196 ObjectArray<Class>* class_roots_;
Brian Carlstrom913af1b2011-07-23 21:41:13 -0700197
Brian Carlstrom4a96b602011-07-26 16:40:23 -0700198 ObjectArray<Class>* array_interfaces_;
Brian Carlstrom913af1b2011-07-23 21:41:13 -0700199 InterfaceEntry* array_iftable_;
Carl Shapiro565f5072011-07-10 13:39:43 -0700200
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700201 bool init_done_;
202
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700203 FRIEND_TEST(ClassLinkerTest, ProtoCompare);
204 FRIEND_TEST(ClassLinkerTest, ProtoCompare2);
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700205 FRIEND_TEST(DexCacheTest, Open);
206 friend class ObjectTest;
207 FRIEND_TEST(ObjectTest, AllocObjectArray);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700208 DISALLOW_COPY_AND_ASSIGN(ClassLinker);
209};
210
211} // namespace art
212
213#endif // ART_SRC_CLASS_LINKER_H_