blob: 6323fb7600ecc7c998af9e9b80c517494539c9b4 [file] [log] [blame]
// Copyright 2011 Google Inc. All Rights Reserved.
#ifndef ART_SRC_CLASS_LINKER_H_
#define ART_SRC_CLASS_LINKER_H_
#include <map>
#include <utility>
#include <vector>
#include "heap.h"
#include "macros.h"
#include "dex_file.h"
#include "thread.h"
#include "object.h"
#include "gtest/gtest.h"
namespace art {
class ClassLinker {
public:
// Initializes the class linker.
static ClassLinker* Create(const std::vector<DexFile*>& boot_class_path);
~ClassLinker() {}
// Finds a class by its descriptor name.
// If dex_file is null, searches boot_class_path_.
Class* FindClass(const StringPiece& descriptor,
Object* class_loader,
const DexFile* dex_file);
Class* FindSystemClass(const StringPiece& descriptor) {
return FindClass(descriptor, NULL, NULL);
}
bool InitializeClass(Class* klass);
Class* LookupClass(const StringPiece& descriptor, Object* class_loader);
Class* ResolveClass(const Class* referring,
uint32_t class_idx,
const DexFile* dex_file);
String* ResolveString(const Class* referring, uint32_t string_idx);
void RegisterDexFile(const DexFile* dex_file);
// TODO replace with heap interface
typedef void (RootVistor)(Object* root, void* arg);
void VisitRoots(RootVistor* rootVisitor, void* arg);
private:
ClassLinker() {}
void Init(const std::vector<DexFile*>& boot_class_path_);
// For early bootstrapping by Init
Class* AllocClass(Class* java_lang_Class);
// Alloc* convenience functions to avoid needing to pass in Class*
// values that are known to the ClassLinker such as
// kObjectArrayClass and kJavaLangString etc.
Class* AllocClass();
DexCache* AllocDexCache();
StaticField* AllocStaticField();
InstanceField* AllocInstanceField();
Method* AllocMethod();
String* AllocStringFromModifiedUtf8(int32_t utf16_length, const char* utf8_data_in);
template <class T>
ObjectArray<T>* AllocObjectArray(size_t length) {
return ObjectArray<T>::Alloc(class_roots_->Get(kObjectArrayClass), length);
}
Class* CreatePrimitiveClass(const StringPiece& descriptor);
Class* CreateArrayClass(const StringPiece& descriptor,
Object* class_loader,
const DexFile* dex_file);
Class* FindPrimitiveClass(char type);
const DexFile* FindDexFile(const DexCache* dex_cache) const;
DexCache* FindDexCache(const DexFile* dex_file) const;
typedef std::pair<const DexFile*, const DexFile::ClassDef*> ClassPathEntry;
void AppendToBootClassPath(DexFile* dex_file);
ClassPathEntry FindInBootClassPath(const StringPiece& descriptor);
void LoadClass(const DexFile& dex_file,
const DexFile::ClassDef& dex_class_def,
Class* klass);
void LoadInterfaces(const DexFile& dex_file,
const DexFile::ClassDef& dex_class_def,
Class *klass);
void LoadField(const DexFile& dex_file,
const DexFile::Field& dex_field,
Class* klass,
Field* dst);
void LoadMethod(const DexFile& dex_file,
const DexFile::Method& dex_method,
Class* klass,
Method* dst);
// Inserts a class into the class table. Returns true if the class
// was inserted.
bool InsertClass(Class* klass);
bool InitializeSuperClass(Class* klass);
void InitializeStaticFields(Class* klass);
bool ValidateSuperClassDescriptors(const Class* klass);
bool HasSameDescriptorClasses(const char* descriptor,
const Class* klass1,
const Class* klass2);
bool HasSameMethodDescriptorClasses(const Method* descriptor,
const Class* klass1,
const Class* klass2);
bool HasSameNameAndPrototype(const Method* m1, const Method* m2) const {
return HasSameName(m1, m2) && HasSamePrototype(m1, m2);
}
bool HasSameName(const Method* m1, const Method* m2) const {
return m1->GetName() == m2->GetName();
}
bool HasSamePrototype(const Method* m1, const Method* m2) const {
return HasSameReturnType(m1, m2) && HasSameArgumentTypes(m1, m2);
}
bool HasSameReturnType(const Method* m1, const Method* m2) const;
bool HasSameArgumentTypes(const Method* m1, const Method* m2) const;
bool LinkClass(Class* klass, const DexFile* dex_file);
bool LinkSuperClass(Class* klass);
bool LinkInterfaces(Class* klass, const DexFile* dex_file);
bool LinkMethods(Class* klass);
bool LinkVirtualMethods(Class* klass);
bool LinkInterfaceMethods(Class* klass);
void LinkAbstractMethods(Class* klass);
bool LinkInstanceFields(Class* klass);
void CreateReferenceOffsets(Class* klass);
std::vector<const DexFile*> boot_class_path_;
std::vector<const DexFile*> dex_files_;
std::vector<DexCache*> dex_caches_;
// TODO: multimap
typedef std::map<const StringPiece, Class*> Table;
Table classes_;
Mutex* classes_lock_;
// TODO: classpath
// indexes into class_roots_
enum ClassRoots {
kJavaLangClass,
kJavaLangObject,
kJavaLangReflectField,
kJavaLangReflectMethod,
kJavaLangString,
kPrimitiveBoolean,
kPrimitiveChar,
kPrimitiveFloat,
kPrimitiveDouble,
kPrimitiveByte,
kPrimitiveShort,
kPrimitiveInt,
kPrimitiveLong,
kPrimitiveVoid,
kObjectArrayClass,
kCharArrayClass,
kClassRootsMax,
};
ObjectArray<Class>* class_roots_;
ObjectArray<Class>* array_interfaces_;
InterfaceEntry* array_iftable_;
bool init_done_;
FRIEND_TEST(ClassLinkerTest, ProtoCompare);
FRIEND_TEST(ClassLinkerTest, ProtoCompare2);
FRIEND_TEST(DexCacheTest, Open);
friend class ObjectTest;
FRIEND_TEST(ObjectTest, AllocObjectArray);
DISALLOW_COPY_AND_ASSIGN(ClassLinker);
};
} // namespace art
#endif // ART_SRC_CLASS_LINKER_H_