Assignability checks for SetFieldObject.

Adds check to SetFieldObject that is enabled with VERIFY_OBJECT_ENABLED.
The check verifies that the object being set to the field is assignable
to that field.

Fix bug that iftable was typed to be Object[][] but being assigned a
Object[].

Change-Id: I3d3744347f2dd142ca90db321ed876eaebfe7f7f
diff --git a/src/class_linker.cc b/src/class_linker.cc
index c7c3a33..26af575 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -165,6 +165,7 @@
   "Ljava/lang/Object;",
   "[Ljava/lang/Class;",
   "[Ljava/lang/Object;",
+  "[[Ljava/lang/Object;",
   "Ljava/lang/String;",
   "Ljava/lang/DexCache;",
   "Ljava/lang/ref/Reference;",
@@ -242,39 +243,43 @@
   SirtRef<Class> class_array_class(AllocClass(java_lang_Class.get(), sizeof(Class)));
   class_array_class->SetComponentType(java_lang_Class.get());
 
-  // java_lang_Object comes next so that object_array_class can be created
+  // java_lang_Object comes next so that object_array_class can be created.
   SirtRef<Class> java_lang_Object(AllocClass(java_lang_Class.get(), sizeof(Class)));
   CHECK(java_lang_Object.get() != NULL);
-  // backfill Object as the super class of Class
+  // backfill Object as the super class of Class.
   java_lang_Class->SetSuperClass(java_lang_Object.get());
   java_lang_Object->SetStatus(Class::kStatusLoaded);
 
-  // Object[] next to hold class roots
+  // Object[] next to hold class roots.
   SirtRef<Class> object_array_class(AllocClass(java_lang_Class.get(), sizeof(Class)));
   object_array_class->SetComponentType(java_lang_Object.get());
 
-  // Setup the char class to be used for char[]
+  // Object[][] needed for iftables.
+  SirtRef<Class> object_array_array_class(AllocClass(java_lang_Class.get(), sizeof(Class)));
+  object_array_array_class->SetComponentType(object_array_class.get());
+
+  // Setup the char class to be used for char[].
   SirtRef<Class> char_class(AllocClass(java_lang_Class.get(), sizeof(Class)));
 
-  // Setup the char[] class to be used for String
+  // Setup the char[] class to be used for String.
   SirtRef<Class> char_array_class(AllocClass(java_lang_Class.get(), sizeof(Class)));
   char_array_class->SetComponentType(char_class.get());
   CharArray::SetArrayClass(char_array_class.get());
 
-  // Setup String
+  // Setup String.
   SirtRef<Class> java_lang_String(AllocClass(java_lang_Class.get(), sizeof(StringClass)));
   String::SetClass(java_lang_String.get());
   java_lang_String->SetObjectSize(sizeof(String));
   java_lang_String->SetStatus(Class::kStatusResolved);
 
-  // Create storage for root classes, save away our work so far (requires
-  // descriptors)
+  // Create storage for root classes, save away our work so far (requires descriptors).
   class_roots_ = ObjectArray<Class>::Alloc(object_array_class.get(), kClassRootsMax);
   CHECK(class_roots_ != NULL);
   SetClassRoot(kJavaLangClass, java_lang_Class.get());
   SetClassRoot(kJavaLangObject, java_lang_Object.get());
   SetClassRoot(kClassArrayClass, class_array_class.get());
   SetClassRoot(kObjectArrayClass, object_array_class.get());
+  SetClassRoot(kObjectArrayArrayClass, object_array_array_class.get());
   SetClassRoot(kCharArrayClass, char_array_class.get());
   SetClassRoot(kJavaLangString, java_lang_String.get());
 
@@ -288,10 +293,10 @@
   SetClassRoot(kPrimitiveDouble, CreatePrimitiveClass(Primitive::kPrimDouble));
   SetClassRoot(kPrimitiveVoid, CreatePrimitiveClass(Primitive::kPrimVoid));
 
-  // Create array interface entries to populate once we can load system classes
-  array_iftable_ = AllocObjectArray<InterfaceEntry>(2);
+  // Create array interface entries to populate once we can load system classes.
+  array_iftable_ = AllocIfTable(2);
 
-  // Create int array type for AllocDexCache (done in AppendToBootClassPath)
+  // Create int array type for AllocDexCache (done in AppendToBootClassPath).
   SirtRef<Class> int_array_class(AllocClass(java_lang_Class.get(), sizeof(Class)));
   int_array_class->SetComponentType(GetClassRoot(kPrimitiveInt));
   IntArray::SetArrayClass(int_array_class.get());
@@ -347,9 +352,9 @@
   object_array_abstract_method->SetComponentType(java_lang_reflect_AbstractMethod.get());
   SetClassRoot(kJavaLangReflectAbstractMethodArrayClass, object_array_abstract_method.get());
 
-  // setup boot_class_path_ and register class_path now that we can
-  // use AllocObjectArray to create DexCache instances
-  // Needs to be after String, Field, Method arrays since AllocDexCache uses these roots.
+  // Setup boot_class_path_ and register class_path now that we can use AllocObjectArray to create
+  // DexCache instances. Needs to be after String, Field, Method arrays since AllocDexCache uses
+  // these roots.
   CHECK_NE(0U, boot_class_path.size());
   for (size_t i = 0; i != boot_class_path.size(); ++i) {
     const DexFile* dex_file = boot_class_path[i];
@@ -378,7 +383,7 @@
   CHECK_EQ(java_lang_DexCache.get(), DexCache_class);
   CHECK_EQ(java_lang_DexCache->GetObjectSize(), sizeof(DexCache));
 
-  // Setup the primitive array type classes - can't be done until Object has a vtable
+  // Setup the primitive array type classes - can't be done until Object has a vtable.
   SetClassRoot(kBooleanArrayClass, FindSystemClass("[Z"));
   BooleanArray::SetArrayClass(GetClassRoot(kBooleanArrayClass));
 
@@ -409,26 +414,28 @@
   Class* found_object_array_class = FindSystemClass("[Ljava/lang/Object;");
   CHECK_EQ(object_array_class.get(), found_object_array_class);
 
-  // Setup the single, global copies of "interfaces" and "iftable"
+  Class* found_object_array_array_class = FindSystemClass("[[Ljava/lang/Object;");
+  CHECK_EQ(object_array_array_class.get(), found_object_array_array_class);
+
+  // Setup the single, global copy of "iftable".
   Class* java_lang_Cloneable = FindSystemClass("Ljava/lang/Cloneable;");
   CHECK(java_lang_Cloneable != NULL);
   Class* java_io_Serializable = FindSystemClass("Ljava/io/Serializable;");
   CHECK(java_io_Serializable != NULL);
-  // We assume that Cloneable/Serializable don't have superinterfaces --
-  // normally we'd have to crawl up and explicitly list all of the
-  // supers as well.
+  // We assume that Cloneable/Serializable don't have superinterfaces -- normally we'd have to
+  // crawl up and explicitly list all of the supers as well.
   array_iftable_->Set(0, AllocInterfaceEntry(java_lang_Cloneable));
   array_iftable_->Set(1, AllocInterfaceEntry(java_io_Serializable));
 
-  // Sanity check Class[] and Object[]'s interfaces
+  // Sanity check Class[] and Object[]'s interfaces.
   ClassHelper kh(class_array_class.get(), this);
   CHECK_EQ(java_lang_Cloneable, kh.GetDirectInterface(0));
   CHECK_EQ(java_io_Serializable, kh.GetDirectInterface(1));
   kh.ChangeClass(object_array_class.get());
   CHECK_EQ(java_lang_Cloneable, kh.GetDirectInterface(0));
   CHECK_EQ(java_io_Serializable, kh.GetDirectInterface(1));
-  // run Class, Constructor, Field, and Method through FindSystemClass.
-  // this initializes their dex_cache_ fields and register them in classes_.
+  // Run Class, Constructor, Field, and Method through FindSystemClass. This initializes their
+  // dex_cache_ fields and register them in classes_.
   Class* Class_class = FindSystemClass("Ljava/lang/Class;");
   CHECK_EQ(java_lang_Class.get(), Class_class);
 
@@ -460,9 +467,9 @@
       FindSystemClass(class_roots_descriptors_[kJavaLangReflectAbstractMethodArrayClass]);
   CHECK_EQ(object_array_abstract_method.get(), Abstract_method_array_class);
 
-  // End of special init trickery, subsequent classes may be loaded via FindSystemClass
+  // End of special init trickery, subsequent classes may be loaded via FindSystemClass.
 
-  // Create java.lang.reflect.Proxy root
+  // Create java.lang.reflect.Proxy root.
   Class* java_lang_reflect_Proxy = FindSystemClass("Ljava/lang/reflect/Proxy;");
   SetClassRoot(kJavaLangReflectProxy, java_lang_reflect_Proxy);
 
@@ -485,13 +492,13 @@
       java_lang_ref_WeakReference->GetAccessFlags() |
           kAccClassIsReference | kAccClassIsWeakReference);
 
-  // Setup the ClassLoader, verifying the object_size_
+  // Setup the ClassLoader, verifying the object_size_.
   Class* java_lang_ClassLoader = FindSystemClass("Ljava/lang/ClassLoader;");
   CHECK_EQ(java_lang_ClassLoader->GetObjectSize(), sizeof(ClassLoader));
   SetClassRoot(kJavaLangClassLoader, java_lang_ClassLoader);
 
   // Set up java.lang.Throwable, java.lang.ClassNotFoundException, and
-  // java.lang.StackTraceElement as a convenience
+  // java.lang.StackTraceElement as a convenience.
   SetClassRoot(kJavaLangThrowable, FindSystemClass("Ljava/lang/Throwable;"));
   Throwable::SetClass(GetClassRoot(kJavaLangThrowable));
   SetClassRoot(kJavaLangClassNotFoundException, FindSystemClass("Ljava/lang/ClassNotFoundException;"));
@@ -1862,6 +1869,8 @@
       new_class.reset(GetClassRoot(kClassArrayClass));
     } else if (descriptor == "[Ljava/lang/Object;") {
       new_class.reset(GetClassRoot(kObjectArrayClass));
+    } else if (descriptor == "[[Ljava/lang/Object;") {
+      new_class.reset(GetClassRoot(kObjectArrayArrayClass));
     } else if (descriptor == class_roots_descriptors_[kJavaLangStringArrayClass]) {
       new_class.reset(GetClassRoot(kJavaLangStringArrayClass));
     } else if (descriptor == class_roots_descriptors_[kJavaLangReflectFieldArrayClass]) {
@@ -3037,7 +3046,7 @@
     // DCHECK(klass->GetIfTable() == NULL);
     return true;
   }
-  SirtRef<ObjectArray<InterfaceEntry> > iftable(AllocObjectArray<InterfaceEntry>(ifcount));
+  SirtRef<ObjectArray<InterfaceEntry> > iftable(AllocIfTable(ifcount));
   if (super_ifcount != 0) {
     ObjectArray<InterfaceEntry>* super_iftable = klass->GetSuperClass()->GetIfTable();
     for (size_t i = 0; i < super_ifcount; i++) {