Don't duplicate interfaces in iftable

Mirroring AOSP Change Idb4a13ca
https://android-review.googlesource.com//#/c/30900/

Change-Id: I5d5a7b2993f8a9b2d96cb3e80c1d47d3b994c1ae
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 045974f..8c46a7e 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -2537,7 +2537,8 @@
   if (super_ifcount != 0) {
     ObjectArray<InterfaceEntry>* super_iftable = klass->GetSuperClass()->GetIfTable();
     for (size_t i = 0; i < super_ifcount; i++) {
-      iftable->Set(i, AllocInterfaceEntry(super_iftable->Get(i)->GetInterface()));
+      Class* super_interface = super_iftable->Get(i)->GetInterface();
+      iftable->Set(i, AllocInterfaceEntry(super_interface));
     }
   }
   // Flatten the interface inheritance hierarchy.
@@ -2555,15 +2556,43 @@
       klass->SetVerifyErrorClass(thread->GetException()->GetClass());
       return false;
     }
-    // Add this interface.
-    iftable->Set(idx++, AllocInterfaceEntry(interface));
-    // Add this interface's superinterfaces.
-    for (int32_t j = 0; j < interface->GetIfTableCount(); j++) {
-      iftable->Set(idx++, AllocInterfaceEntry(interface->GetIfTable()->Get(j)->GetInterface()));
+    // Check if interface is already in iftable
+    bool duplicate = false;
+    for (size_t j = 0; j < idx; j++) {
+      Class* existing_interface = iftable->Get(j)->GetInterface();
+      if (existing_interface == interface) {
+        duplicate = true;
+        break;
+      }
+    }
+    if (!duplicate) {
+      // Add this non-duplicate interface.
+      iftable->Set(idx++, AllocInterfaceEntry(interface));
+      // Add this interface's non-duplicate super-interfaces.
+      for (int32_t j = 0; j < interface->GetIfTableCount(); j++) {
+        Class* super_interface = interface->GetIfTable()->Get(j)->GetInterface();
+        bool super_duplicate = false;
+        for (size_t k = 0; k < idx; k++) {
+          Class* existing_interface = iftable->Get(k)->GetInterface();
+          if (existing_interface == super_interface) {
+            super_duplicate = true;
+            break;
+          }
+        }
+        if (!super_duplicate) {
+          iftable->Set(idx++, AllocInterfaceEntry(super_interface));
+        }
+      }
     }
   }
+  // Shrink iftable in case duplicates were found
+  if (idx < ifcount) {
+    iftable.reset(iftable->CopyOf(idx));
+    ifcount = idx;
+  } else {
+    CHECK_EQ(idx, ifcount);
+  }
   klass->SetIfTable(iftable.get());
-  CHECK_EQ(idx, ifcount);
 
   // If we're an interface, we don't need the vtable pointers, so we're done.
   if (klass->IsInterface() /*|| super_ifcount == ifcount*/) {