Adding Object::InstanceOf and Class::IsAssignableFrom

Summary:
- Add Object::InstanceOf and Class::IsAssignableFrom
- Fix Cloneable and Serializable interfaces on arrays to be == with FindSystemClass results
- Changed Object::Alloc(Class*) to be Class->NewInstance()

Details:

Add Object::InstanceOf and Class::IsAssignableFrom

	object.h
	common_test.h
	object_test.cc

Fix bug where Cloneable and Serializable where created with AllocClass
and never inserted in the classes table with FindSystemClass by just
creating them directly with FindSystemClass

	class_linker.cc
	object_test.cc

Changed Object::Alloc(Class*) to be Class->NewInstance()

	class_linker.cc
	object.h

Change-Id: I528767fff43aff32c8dc4f7a2d4157598a7dbb89
diff --git a/src/object_test.cc b/src/object_test.cc
index cf59776..7167732 100644
--- a/src/object_test.cc
+++ b/src/object_test.cc
@@ -55,16 +55,23 @@
 }
 
 TEST_F(ObjectTest, AllocObjectArray) {
-    ObjectArray<Object>* oa = class_linker_->AllocObjectArray<Object>(2);
-    EXPECT_EQ(2U, oa->GetLength());
-    EXPECT_TRUE(oa->Get(0) == NULL);
-    EXPECT_TRUE(oa->Get(1) == NULL);
-    oa->Set(0, oa);
-    EXPECT_TRUE(oa->Get(0) == oa);
-    EXPECT_TRUE(oa->Get(1) == NULL);
-    oa->Set(1, oa);
-    EXPECT_TRUE(oa->Get(0) == oa);
-    EXPECT_TRUE(oa->Get(1) == oa);
+  ObjectArray<Object>* oa = class_linker_->AllocObjectArray<Object>(2);
+  EXPECT_EQ(2U, oa->GetLength());
+  EXPECT_TRUE(oa->Get(0) == NULL);
+  EXPECT_TRUE(oa->Get(1) == NULL);
+  oa->Set(0, oa);
+  EXPECT_TRUE(oa->Get(0) == oa);
+  EXPECT_TRUE(oa->Get(1) == NULL);
+  oa->Set(1, oa);
+  EXPECT_TRUE(oa->Get(0) == oa);
+  EXPECT_TRUE(oa->Get(1) == oa);
+
+  ASSERT_TRUE(oa->GetClass() != NULL);
+  ASSERT_EQ(2U, oa->GetClass()->NumInterfaces());
+  EXPECT_EQ(class_linker_->FindSystemClass("Ljava/lang/Cloneable;"),
+            oa->GetClass()->GetInterface(0));
+  EXPECT_EQ(class_linker_->FindSystemClass("Ljava/io/Serializable;"),
+            oa->GetClass()->GetInterface(1));
 }
 
 TEST_F(ObjectTest, String) {
@@ -169,4 +176,95 @@
   EXPECT_EQ(64578U, String::AllocFromAscii("ABC")->GetHashCode());
 }
 
+TEST_F(ObjectTest, InstanceOf) {
+  scoped_ptr<DexFile> dex(OpenDexFileBase64(kXandY));
+  PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
+  Class* X = class_linker_->FindClass("LX;", class_loader);
+  Class* Y = class_linker_->FindClass("LY;", class_loader);
+  ASSERT_TRUE(X != NULL);
+  ASSERT_TRUE(Y != NULL);
+
+  EXPECT_FALSE(Object::InstanceOf(NULL, X));
+  EXPECT_FALSE(Object::InstanceOf(NULL, Y));
+
+  Object* x = X->NewInstance();
+  Object* y = Y->NewInstance();
+  ASSERT_TRUE(x != NULL);
+  ASSERT_TRUE(y != NULL);
+
+  EXPECT_TRUE(Object::InstanceOf(x, X));
+  EXPECT_FALSE(Object::InstanceOf(x, Y));
+  EXPECT_TRUE(Object::InstanceOf(y, X));
+  EXPECT_TRUE(Object::InstanceOf(y, Y));
+
+  EXPECT_TRUE(x->InstanceOf(X));
+  EXPECT_FALSE(x->InstanceOf(Y));
+  EXPECT_TRUE(y->InstanceOf(X));
+  EXPECT_TRUE(y->InstanceOf(Y));
+}
+
+TEST_F(ObjectTest, IsAssignableFrom) {
+  scoped_ptr<DexFile> dex(OpenDexFileBase64(kXandY));
+  PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
+  Class* X = class_linker_->FindClass("LX;", class_loader);
+  Class* Y = class_linker_->FindClass("LY;", class_loader);
+
+  EXPECT_TRUE(X->IsAssignableFrom(X));
+  EXPECT_TRUE(X->IsAssignableFrom(Y));
+  EXPECT_FALSE(Y->IsAssignableFrom(X));
+  EXPECT_TRUE(Y->IsAssignableFrom(Y));
+}
+
+TEST_F(ObjectTest, IsAssignableFromArray) {
+  scoped_ptr<DexFile> dex(OpenDexFileBase64(kXandY));
+  PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
+  Class* X = class_linker_->FindClass("LX;", class_loader);
+  Class* Y = class_linker_->FindClass("LY;", class_loader);
+  ASSERT_TRUE(X != NULL);
+  ASSERT_TRUE(Y != NULL);
+
+  Class* YA = class_linker_->FindClass("[LY;", class_loader);
+  Class* YAA = class_linker_->FindClass("[[LY;", class_loader);
+  ASSERT_TRUE(YA != NULL);
+  ASSERT_TRUE(YAA != NULL);
+
+  Class* XAA = class_linker_->FindClass("[[LX;", class_loader);
+  ASSERT_TRUE(XAA != NULL);
+
+  Class* O = class_linker_->FindSystemClass("Ljava/lang/Object;");
+  Class* OA = class_linker_->FindSystemClass("[Ljava/lang/Object;");
+  Class* OAA = class_linker_->FindSystemClass("[[Ljava/lang/Object;");
+  Class* OAAA = class_linker_->FindSystemClass("[[[Ljava/lang/Object;");
+  ASSERT_TRUE(O != NULL);
+  ASSERT_TRUE(OA != NULL);
+  ASSERT_TRUE(OAA != NULL);
+  ASSERT_TRUE(OAAA != NULL);
+
+  Class* S = class_linker_->FindSystemClass("Ljava/io/Serializable;");
+  Class* SA = class_linker_->FindSystemClass("[Ljava/io/Serializable;");
+  Class* SAA = class_linker_->FindSystemClass("[[Ljava/io/Serializable;");
+  ASSERT_TRUE(S != NULL);
+  ASSERT_TRUE(SA != NULL);
+  ASSERT_TRUE(SAA != NULL);
+
+  Class* IA = class_linker_->FindSystemClass("[I");
+  ASSERT_TRUE(IA != NULL);
+
+  EXPECT_TRUE(YAA->IsAssignableFrom(YAA));  // identity
+  EXPECT_TRUE(XAA->IsAssignableFrom(YAA));  // element superclass
+  EXPECT_FALSE(YAA->IsAssignableFrom(XAA));
+  EXPECT_FALSE(Y->IsAssignableFrom(YAA));
+  EXPECT_FALSE(YA->IsAssignableFrom(YAA));
+  EXPECT_TRUE(O->IsAssignableFrom(YAA));  // everything is an Object
+  EXPECT_TRUE(OA->IsAssignableFrom(YAA));
+  EXPECT_TRUE(OAA->IsAssignableFrom(YAA));
+  EXPECT_TRUE(S->IsAssignableFrom(YAA));  // all arrays are Serializable
+  EXPECT_TRUE(SA->IsAssignableFrom(YAA));
+  EXPECT_FALSE(SAA->IsAssignableFrom(YAA));  // unless Y was Serializable
+
+  EXPECT_FALSE(IA->IsAssignableFrom(OA));
+  EXPECT_FALSE(OA->IsAssignableFrom(IA));
+  EXPECT_TRUE(O->IsAssignableFrom(IA));
+}
+
 }  // namespace art