Implement reflective method invocation.

Change-Id: Ib3af9d7e00bf226398610b5ac6efbfe3eb2d15e8
diff --git a/src/class_linker.cc b/src/class_linker.cc
index be1de23..6daa27a 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -72,9 +72,10 @@
 
 }
 
-const char* ClassLinker::class_roots_descriptors_[kClassRootsMax] = {
+const char* ClassLinker::class_roots_descriptors_[] = {
   "Ljava/lang/Class;",
   "Ljava/lang/Object;",
+  "[Ljava/lang/Class;",
   "[Ljava/lang/Object;",
   "Ljava/lang/String;",
   "Ljava/lang/reflect/Field;",
@@ -153,6 +154,7 @@
       array_iftable_(NULL),
       init_done_(false),
       intern_table_(intern_table) {
+  CHECK_EQ(arraysize(class_roots_descriptors_), size_t(kClassRootsMax));
 }
 
 void ClassLinker::Init(const std::vector<const DexFile*>& boot_class_path,
@@ -167,6 +169,10 @@
   java_lang_Class->SetClassSize(sizeof(ClassClass));
   // AllocClass(Class*) can now be used
 
+  // Class[] is used for reflection support.
+  Class* class_array_class = AllocClass(java_lang_Class, sizeof(Class));
+  class_array_class->SetComponentType(java_lang_Class);
+
   // java_lang_Object comes next so that object_array_class can be created
   Class* java_lang_Object = AllocClass(java_lang_Class, sizeof(Class));
   CHECK(java_lang_Object != NULL);
@@ -195,6 +201,7 @@
   // Backfill Class descriptors missing until this point
   java_lang_Class->SetDescriptor(intern_table_->InternStrong("Ljava/lang/Class;"));
   java_lang_Object->SetDescriptor(intern_table_->InternStrong("Ljava/lang/Object;"));
+  class_array_class->SetDescriptor(intern_table_->InternStrong("[Ljava/lang/Class;"));
   object_array_class->SetDescriptor(intern_table_->InternStrong("[Ljava/lang/Object;"));
   java_lang_String->SetDescriptor(intern_table_->InternStrong("Ljava/lang/String;"));
   char_array_class->SetDescriptor(intern_table_->InternStrong("[C"));
@@ -204,6 +211,7 @@
   class_roots_ = ObjectArray<Class>::Alloc(object_array_class, kClassRootsMax);
   SetClassRoot(kJavaLangClass, java_lang_Class);
   SetClassRoot(kJavaLangObject, java_lang_Object);
+  SetClassRoot(kClassArrayClass, class_array_class);
   SetClassRoot(kObjectArrayClass, object_array_class);
   SetClassRoot(kCharArrayClass, char_array_class);
   SetClassRoot(kJavaLangString, java_lang_String);
@@ -219,7 +227,7 @@
   SetClassRoot(kPrimitiveVoid, CreatePrimitiveClass("V", Class::kPrimVoid));
 
   // Create array interface entries to populate once we can load system classes
-  array_interfaces_ = AllocObjectArray<Class>(2);
+  array_interfaces_ = AllocClassArray(2);
   array_iftable_ = AllocObjectArray<InterfaceEntry>(2);
 
   // Create int array type for AllocDexCache (done in AppendToBootClassPath)
@@ -303,6 +311,9 @@
   SetClassRoot(kDoubleArrayClass, FindSystemClass("[D"));
   DoubleArray::SetArrayClass(GetClassRoot(kDoubleArrayClass));
 
+  Class* found_class_array_class = FindSystemClass("[Ljava/lang/Class;");
+  CHECK_EQ(class_array_class, found_class_array_class);
+
   Class* found_object_array_class = FindSystemClass("[Ljava/lang/Object;");
   CHECK_EQ(object_array_class, found_object_array_class);
 
@@ -320,7 +331,9 @@
   array_iftable_->Set(0, AllocInterfaceEntry(array_interfaces_->Get(0)));
   array_iftable_->Set(1, AllocInterfaceEntry(array_interfaces_->Get(1)));
 
-  // Sanity check Object[]'s interfaces
+  // Sanity check Class[] and Object[]'s interfaces
+  CHECK_EQ(java_lang_Cloneable, class_array_class->GetInterface(0));
+  CHECK_EQ(java_io_Serializable, class_array_class->GetInterface(1));
   CHECK_EQ(java_lang_Cloneable, object_array_class->GetInterface(0));
   CHECK_EQ(java_io_Serializable, object_array_class->GetInterface(1));
 
@@ -598,7 +611,7 @@
   DexCache* dex_cache = down_cast<DexCache*>(AllocObjectArray<Object>(DexCache::LengthAsArray()));
   dex_cache->Init(intern_table_->InternStrong(dex_file.GetLocation().c_str()),
                   AllocObjectArray<String>(dex_file.NumStringIds()),
-                  AllocObjectArray<Class>(dex_file.NumTypeIds()),
+                  AllocClassArray(dex_file.NumTypeIds()),
                   AllocObjectArray<Method>(dex_file.NumMethodIds()),
                   AllocObjectArray<Field>(dex_file.NumFieldIds()),
                   AllocCodeAndDirectMethods(dex_file.NumMethodIds()),
@@ -908,7 +921,7 @@
                                  Class* klass) {
   const DexFile::TypeList* list = dex_file.GetInterfacesList(dex_class_def);
   if (list != NULL) {
-    klass->SetInterfaces(AllocObjectArray<Class>(list->Size()));
+    klass->SetInterfaces(AllocClassArray(list->Size()));
     IntArray* interfaces_idx = IntArray::Alloc(list->Size());
     klass->SetInterfacesTypeIdx(interfaces_idx);
     for (size_t i = 0; i < list->Size(); ++i) {
@@ -1099,7 +1112,9 @@
   Class* new_class = NULL;
   if (!init_done_) {
     // Classes that were hand created, ie not by FindSystemClass
-    if (descriptor == "[Ljava/lang/Object;") {
+    if (descriptor == "[Ljava/lang/Class;") {
+      new_class = GetClassRoot(kClassArrayClass);
+    } else if (descriptor == "[Ljava/lang/Object;") {
       new_class = GetClassRoot(kObjectArrayClass);
     } else if (descriptor == "[C") {
       new_class = GetClassRoot(kCharArrayClass);