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);
 };