Add ClassLinker::VisitRoots
As part of implementing VisitRoots, created ClassLinker::class_roots_
with enum of offsets. This required revising ClassLinker::Init yet
again, so took the opportunity to simplify and document ordering
restrictions. Also simplified special cases in FindClass, as well as
making a fast path for FindClass and CreateArrayClass for post
::Init. Made ClassLinker::Alloc* conveniences private after realizing
they are only used externally by tests. Sprinkled some
Class::IsSynthetic validation in ClassLinkerTest along with adding a
test for VisitRoots. Updated kJavaLangDex to have a java.lang.String
to work with the simplified ::Init code.
Change-Id: I76b92c0bde5da32d9ebc8d3702d8e7ac7972dda7
diff --git a/src/class_linker.h b/src/class_linker.h
index 46d4b1f..6323fb7 100644
--- a/src/class_linker.h
+++ b/src/class_linker.h
@@ -23,21 +23,6 @@
~ClassLinker() {}
- // Alloc* convenience functions to avoid needing to pass in Class*
- // values that are known to the ClassLinker such as
- // object_array_class_ and java_lang_String_ etc.
- DexCache* AllocDexCache();
- Class* AllocClass(DexCache* dex_cache);
- 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(object_array_class_, length);
- }
-
-
// Finds a class by its descriptor name.
// If dex_file is null, searches boot_class_path_.
Class* FindClass(const StringPiece& descriptor,
@@ -60,11 +45,32 @@
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,
@@ -168,35 +174,38 @@
// TODO: classpath
- Class* java_lang_Class_;
- Class* java_lang_Object_;
- Class* java_lang_reflect_Field_;
- Class* java_lang_reflect_Method_;
- Class* java_lang_Cloneable_;
- Class* java_io_Serializable_;
- Class* java_lang_String_;
-
- Class* primitive_boolean_;
- Class* primitive_char_;
- Class* primitive_float_;
- Class* primitive_double_;
- Class* primitive_byte_;
- Class* primitive_short_;
- Class* primitive_int_;
- Class* primitive_long_;
- Class* primitive_void_;
-
- Class* char_array_class_;
- Class* class_array_class_;
- Class* object_array_class_;
- Class* field_array_class_;
- Class* method_array_class_;
+ // 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);
};