class_linker.h revision b63ec393a5c4ba2be1d34dd871cda811eaa803c7
1// 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 10#include "dex_file.h" 11#include "heap.h" 12#include "intern_table.h" 13#include "macros.h" 14#include "object.h" 15#include "thread.h" 16#include "unordered_map.h" 17#include "unordered_set.h" 18 19#include "gtest/gtest.h" 20 21namespace art { 22 23class ClassLinker { 24 public: 25 // Initializes the class linker using DexFile and an optional boot Space. 26 static ClassLinker* Create(const std::vector<const DexFile*>& boot_class_path, Space* boot_space); 27 28 ~ClassLinker(); 29 30 // Finds a class by its descriptor name. 31 // If class_loader is null, searches boot_class_path_. 32 Class* FindClass(const StringPiece& descriptor, 33 const ClassLoader* class_loader); 34 35 Class* FindPrimitiveClass(char type); 36 37 Class* FindSystemClass(const StringPiece& descriptor) { 38 return FindClass(descriptor, NULL); 39 } 40 41 size_t NumLoadedClasses() const; 42 43 // Resolve a String with the given index from the DexFile, storing the 44 // result in the DexCache. 45 String* ResolveString(const DexFile& dex_file, 46 uint32_t string_idx, 47 DexCache* dex_cache); 48 49 // Resolve a Type with the given index from the DexFile, storing the 50 // result in the DexCache. The referrer is used to identity the 51 // target DexCache and ClassLoader to use for resolution. 52 Class* ResolveType(const DexFile& dex_file, 53 uint32_t type_idx, 54 const Class* referrer) { 55 return ResolveType(dex_file, 56 type_idx, 57 referrer->GetDexCache(), 58 referrer->GetClassLoader()); 59 } 60 61 // Resolve a Type with the given index from the DexFile, storing the 62 // result in the DexCache. The referrer is used to identity the 63 // target DexCache and ClassLoader to use for resolution. 64 Class* ResolveType(uint32_t type_idx, Method* referrer) { 65 Class* declaring_class = referrer->GetDeclaringClass(); 66 DexCache* dex_cache = declaring_class->GetDexCache(); 67 const ClassLoader* class_loader = declaring_class->GetClassLoader(); 68 const DexFile& dex_file = FindDexFile(dex_cache); 69 return ResolveType(dex_file, type_idx, dex_cache, class_loader); 70 } 71 72 // Resolve a type with the given ID from the DexFile, storing the 73 // result in DexCache. The ClassLoader is used to search for the 74 // type, since it may be referenced from but not contained within 75 // the given DexFile. 76 Class* ResolveType(const DexFile& dex_file, 77 uint32_t type_idx, 78 DexCache* dex_cache, 79 const ClassLoader* class_loader); 80 81 // Resolve a method with a given ID from the DexFile, storing the 82 // result in DexCache. The ClassLinker and ClassLoader are used as 83 // in ResolveType. What is unique is the method type argument which 84 // is used to determine if this method is a direct, static, or 85 // virtual method. 86 Method* ResolveMethod(const DexFile& dex_file, 87 uint32_t method_idx, 88 DexCache* dex_cache, 89 const ClassLoader* class_loader, 90 bool is_direct); 91 92 // Resolve a method with a given ID from the DexFile, storing the 93 // result in DexCache. The ClassLinker and ClassLoader are used as 94 // in ResolveType. What is unique is the is_static argument which is 95 // used to determine if we are resolving a static or non-static 96 // field. 97 Field* ResolveField(const DexFile& dex_file, 98 uint32_t field_idx, 99 DexCache* dex_cache, 100 const ClassLoader* class_loader, 101 bool is_static); 102 103 // Returns true on success, false if there's an exception pending. 104 bool EnsureInitialized(Class* c); 105 106 void RegisterDexFile(const DexFile& dex_file); 107 void RegisterDexFile(const DexFile& dex_file, DexCache* dex_cache); 108 109 const InternTable& GetInternTable() { 110 return intern_table_; 111 } 112 113 void VisitRoots(Heap::RootVistor* root_visitor, void* arg) const; 114 115 const DexFile& FindDexFile(const DexCache* dex_cache) const; 116 DexCache* FindDexCache(const DexFile& dex_file) const; 117 118 ObjectArray<StackTraceElement>* AllocStackTraceElementArray(size_t length); 119 120 private: 121 ClassLinker(); 122 123 // Initialize class linker from DexFile instances. 124 void Init(const std::vector<const DexFile*>& boot_class_path_); 125 126 // Initialize class linker from pre-initialized space. 127 void Init(const std::vector<const DexFile*>& boot_class_path_, Space* space); 128 static void InitCallback(Object* obj, void *arg); 129 struct InitCallbackState; 130 131 void FinishInit(); 132 133 bool InitializeClass(Class* klass); 134 135 // For early bootstrapping by Init 136 Class* AllocClass(Class* java_lang_Class, size_t class_size); 137 138 // Alloc* convenience functions to avoid needing to pass in Class* 139 // values that are known to the ClassLinker such as 140 // kObjectArrayClass and kJavaLangString etc. 141 Class* AllocClass(size_t class_size); 142 DexCache* AllocDexCache(const DexFile& dex_file); 143 Field* AllocField(); 144 Method* AllocMethod(); 145 template <class T> 146 ObjectArray<T>* AllocObjectArray(size_t length) { 147 return ObjectArray<T>::Alloc(GetClassRoot(kObjectArrayClass), length); 148 } 149 CodeAndMethods* AllocCodeAndMethods(size_t length); 150 151 Class* CreatePrimitiveClass(const char* descriptor); 152 153 Class* CreateArrayClass(const StringPiece& descriptor, 154 const ClassLoader* class_loader); 155 156 void AppendToBootClassPath(const DexFile& dex_file); 157 void AppendToBootClassPath(const DexFile& dex_file, DexCache* dex_cache); 158 159 size_t SizeOfClass(const DexFile& dex_file, 160 const DexFile::ClassDef& dex_class_def); 161 162 void LoadClass(const DexFile& dex_file, 163 const DexFile::ClassDef& dex_class_def, 164 Class* klass, 165 const ClassLoader* class_loader); 166 167 void LoadInterfaces(const DexFile& dex_file, 168 const DexFile::ClassDef& dex_class_def, 169 Class *klass); 170 171 void LoadField(const DexFile& dex_file, 172 const DexFile::Field& dex_field, 173 Class* klass, 174 Field* dst); 175 176 void LoadMethod(const DexFile& dex_file, 177 const DexFile::Method& dex_method, 178 Class* klass, 179 Method* dst); 180 181 Class* LookupClass(const StringPiece& descriptor, const ClassLoader* class_loader); 182 183 // Inserts a class into the class table. Returns true if the class 184 // was inserted. 185 bool InsertClass(const StringPiece& descriptor, Class* klass); 186 187 bool InitializeSuperClass(Class* klass); 188 189 void InitializeStaticFields(Class* klass); 190 191 bool ValidateSuperClassDescriptors(const Class* klass); 192 193 bool HasSameDescriptorClasses(const char* descriptor, 194 const Class* klass1, 195 const Class* klass2); 196 197 bool HasSameMethodDescriptorClasses(const Method* descriptor, 198 const Class* klass1, 199 const Class* klass2); 200 201 bool LinkClass(Class* klass, const DexFile& dex_file); 202 203 bool LinkSuperClass(Class* klass); 204 205 bool LoadSuperAndInterfaces(Class* klass, const DexFile& dex_file); 206 207 bool LinkMethods(Class* klass); 208 209 bool LinkVirtualMethods(Class* klass); 210 211 bool LinkInterfaceMethods(Class* klass); 212 213 void LinkAbstractMethods(Class* klass); 214 215 bool LinkStaticFields(Class* klass); 216 bool LinkInstanceFields(Class* klass); 217 bool LinkFields(size_t field_offset, 218 size_t& num_reference_fields, 219 size_t num_fields, 220 ObjectArray<Field>* fields, 221 size_t& size); 222 223 void CreateReferenceInstanceOffsets(Class* klass); 224 void CreateReferenceStaticOffsets(Class* klass); 225 void CreateReferenceOffsets(uint32_t& reference_offsets, 226 size_t num_reference_fields, 227 const ObjectArray<Field>* fields); 228 229 std::vector<const DexFile*> boot_class_path_; 230 231 std::vector<const DexFile*> dex_files_; 232 233 std::vector<DexCache*> dex_caches_; 234 235 // multimap from a StringPiece hash code of a class descriptor to 236 // Class* instances. Results should be compared for a matching 237 // Class::descriptor_ and Class::class_loader_. 238 typedef std::tr1::unordered_multimap<size_t, Class*> Table; 239 Table classes_; 240 Mutex* classes_lock_; 241 242 InternTable intern_table_; 243 244 // indexes into class_roots_. 245 // needs to be kept in sync with class_roots_descriptors_. 246 enum ClassRoot { 247 kJavaLangClass, 248 kJavaLangObject, 249 kObjectArrayClass, 250 kJavaLangString, 251 kJavaLangReflectField, 252 kJavaLangReflectMethod, 253 kJavaLangClassLoader, 254 kDalvikSystemBaseDexClassLoader, 255 kDalvikSystemPathClassLoader, 256 kJavaLangStackTraceElement, 257 kPrimitiveBoolean, 258 kPrimitiveByte, 259 kPrimitiveChar, 260 kPrimitiveDouble, 261 kPrimitiveFloat, 262 kPrimitiveInt, 263 kPrimitiveLong, 264 kPrimitiveShort, 265 kPrimitiveVoid, 266 kBooleanArrayClass, 267 kByteArrayClass, 268 kCharArrayClass, 269 kDoubleArrayClass, 270 kFloatArrayClass, 271 kIntArrayClass, 272 kLongArrayClass, 273 kShortArrayClass, 274 kJavaLangStackTraceElementArrayClass, 275 kClassRootsMax, 276 }; 277 ObjectArray<Class>* class_roots_; 278 279 Class* GetClassRoot(ClassRoot class_root) { 280 DCHECK(class_roots_ != NULL); 281 Class* klass = class_roots_->Get(class_root); 282 DCHECK(klass != NULL); 283 return klass; 284 } 285 286 void SetClassRoot(ClassRoot class_root, Class* klass) { 287 DCHECK(!init_done_); 288 289 DCHECK(klass != NULL); 290 DCHECK(klass->class_loader_ == NULL); 291 DCHECK(klass->descriptor_ != NULL); 292 DCHECK(klass->descriptor_->Equals(GetClassRootDescriptor(class_root))); 293 294 DCHECK(class_roots_ != NULL); 295 DCHECK(class_roots_->Get(class_root) == NULL); 296 class_roots_->Set(class_root, klass); 297 } 298 299 static const char* class_roots_descriptors_[kClassRootsMax]; 300 301 const char* GetClassRootDescriptor(ClassRoot class_root) { 302 const char* descriptor = class_roots_descriptors_[class_root]; 303 CHECK(descriptor != NULL); 304 return descriptor; 305 } 306 307 ObjectArray<Class>* array_interfaces_; 308 InterfaceEntry* array_iftable_; 309 310 bool init_done_; 311 312 friend class CommonTest; 313 FRIEND_TEST(DexCacheTest, Open); 314 friend class ObjectTest; 315 FRIEND_TEST(ObjectTest, AllocObjectArray); 316 FRIEND_TEST(ExceptionTest, FindExceptionHandler); 317 DISALLOW_COPY_AND_ASSIGN(ClassLinker); 318}; 319 320} // namespace art 321 322#endif // ART_SRC_CLASS_LINKER_H_ 323