blob: 6323fb7600ecc7c998af9e9b80c517494539c9b4 [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);
50 void VisitRoots(RootVistor* rootVisitor, void* arg);
51
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();
68 String* AllocStringFromModifiedUtf8(int32_t utf16_length, const char* utf8_data_in);
69 template <class T>
70 ObjectArray<T>* AllocObjectArray(size_t length) {
71 return ObjectArray<T>::Alloc(class_roots_->Get(kObjectArrayClass), length);
72 }
73
Brian Carlstroma331b3c2011-07-18 17:47:56 -070074 Class* CreatePrimitiveClass(const StringPiece& descriptor);
75
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070076 Class* CreateArrayClass(const StringPiece& descriptor,
77 Object* class_loader,
Brian Carlstromf615a612011-07-23 12:50:34 -070078 const DexFile* dex_file);
Brian Carlstroma331b3c2011-07-18 17:47:56 -070079
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070080 Class* FindPrimitiveClass(char type);
Carl Shapiro565f5072011-07-10 13:39:43 -070081
Brian Carlstromf615a612011-07-23 12:50:34 -070082 const DexFile* FindDexFile(const DexCache* dex_cache) const;
Brian Carlstrom934486c2011-07-12 23:42:50 -070083
Brian Carlstromf615a612011-07-23 12:50:34 -070084 DexCache* FindDexCache(const DexFile* dex_file) const;
Brian Carlstrom934486c2011-07-12 23:42:50 -070085
Brian Carlstromf615a612011-07-23 12:50:34 -070086 typedef std::pair<const DexFile*, const DexFile::ClassDef*> ClassPathEntry;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070087
Brian Carlstromf615a612011-07-23 12:50:34 -070088 void AppendToBootClassPath(DexFile* dex_file);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070089
90 ClassPathEntry FindInBootClassPath(const StringPiece& descriptor);
91
Brian Carlstromf615a612011-07-23 12:50:34 -070092 void LoadClass(const DexFile& dex_file,
93 const DexFile::ClassDef& dex_class_def,
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070094 Class* klass);
95
Brian Carlstromf615a612011-07-23 12:50:34 -070096 void LoadInterfaces(const DexFile& dex_file,
97 const DexFile::ClassDef& dex_class_def,
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070098 Class *klass);
99
Brian Carlstromf615a612011-07-23 12:50:34 -0700100 void LoadField(const DexFile& dex_file,
101 const DexFile::Field& dex_field,
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700102 Class* klass,
103 Field* dst);
104
Brian Carlstromf615a612011-07-23 12:50:34 -0700105 void LoadMethod(const DexFile& dex_file,
106 const DexFile::Method& dex_method,
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700107 Class* klass,
108 Method* dst);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700109
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700110 // Inserts a class into the class table. Returns true if the class
111 // was inserted.
112 bool InsertClass(Class* klass);
113
114 bool InitializeSuperClass(Class* klass);
115
116 void InitializeStaticFields(Class* klass);
117
118 bool ValidateSuperClassDescriptors(const Class* klass);
119
120 bool HasSameDescriptorClasses(const char* descriptor,
121 const Class* klass1,
122 const Class* klass2);
123
124 bool HasSameMethodDescriptorClasses(const Method* descriptor,
125 const Class* klass1,
126 const Class* klass2);
127
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700128 bool HasSameNameAndPrototype(const Method* m1, const Method* m2) const {
129 return HasSameName(m1, m2) && HasSamePrototype(m1, m2);
130 }
131
132 bool HasSameName(const Method* m1, const Method* m2) const {
133 return m1->GetName() == m2->GetName();
134 }
135
136 bool HasSamePrototype(const Method* m1, const Method* m2) const {
137 return HasSameReturnType(m1, m2) && HasSameArgumentTypes(m1, m2);
138 }
139
140 bool HasSameReturnType(const Method* m1, const Method* m2) const;
141
142 bool HasSameArgumentTypes(const Method* m1, const Method* m2) const;
143
Brian Carlstromf615a612011-07-23 12:50:34 -0700144 bool LinkClass(Class* klass, const DexFile* dex_file);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700145
146 bool LinkSuperClass(Class* klass);
147
Brian Carlstromf615a612011-07-23 12:50:34 -0700148 bool LinkInterfaces(Class* klass, const DexFile* dex_file);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700149
150 bool LinkMethods(Class* klass);
151
152 bool LinkVirtualMethods(Class* klass);
153
154 bool LinkInterfaceMethods(Class* klass);
155
156 void LinkAbstractMethods(Class* klass);
157
158 bool LinkInstanceFields(Class* klass);
159
160 void CreateReferenceOffsets(Class* klass);
161
Brian Carlstrom4a96b602011-07-26 16:40:23 -0700162 std::vector<const DexFile*> boot_class_path_;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700163
Brian Carlstrom4a96b602011-07-26 16:40:23 -0700164 std::vector<const DexFile*> dex_files_;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700165
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700166 std::vector<DexCache*> dex_caches_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700167
168 // TODO: multimap
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700169 typedef std::map<const StringPiece, Class*> Table;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700170
171 Table classes_;
172
173 Mutex* classes_lock_;
174
175 // TODO: classpath
176
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700177 // indexes into class_roots_
178 enum ClassRoots {
179 kJavaLangClass,
180 kJavaLangObject,
181 kJavaLangReflectField,
182 kJavaLangReflectMethod,
183 kJavaLangString,
184 kPrimitiveBoolean,
185 kPrimitiveChar,
186 kPrimitiveFloat,
187 kPrimitiveDouble,
188 kPrimitiveByte,
189 kPrimitiveShort,
190 kPrimitiveInt,
191 kPrimitiveLong,
192 kPrimitiveVoid,
193 kObjectArrayClass,
194 kCharArrayClass,
195 kClassRootsMax,
196 };
197 ObjectArray<Class>* class_roots_;
Brian Carlstrom913af1b2011-07-23 21:41:13 -0700198
Brian Carlstrom4a96b602011-07-26 16:40:23 -0700199 ObjectArray<Class>* array_interfaces_;
Brian Carlstrom913af1b2011-07-23 21:41:13 -0700200 InterfaceEntry* array_iftable_;
Carl Shapiro565f5072011-07-10 13:39:43 -0700201
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700202 bool init_done_;
203
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700204 FRIEND_TEST(ClassLinkerTest, ProtoCompare);
205 FRIEND_TEST(ClassLinkerTest, ProtoCompare2);
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700206 FRIEND_TEST(DexCacheTest, Open);
207 friend class ObjectTest;
208 FRIEND_TEST(ObjectTest, AllocObjectArray);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700209 DISALLOW_COPY_AND_ASSIGN(ClassLinker);
210};
211
212} // namespace art
213
214#endif // ART_SRC_CLASS_LINKER_H_