Fix ClassLinker::LinkInterfaceMethods bug

Also:
- Expanded class_linker_test with additional vtable and iftable coverage
- Added -fkeep-inline-functions where it works on host for debugging
- Added disabled test for running command line Fibonacci with oatexec

Change-Id: Ie295551e42493c7cca05684e71e56bf55bd362a4
diff --git a/src/class_linker.cc b/src/class_linker.cc
index f25bac0..dde29cf 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -1718,7 +1718,7 @@
   }
   klass->SetIfTable(iftable);
   CHECK_EQ(idx, ifcount);
-  if (klass->IsInterface() || super_ifcount == ifcount) {
+  if (klass->IsInterface()) {
     return true;
   }
   std::vector<Method*> miranda_list;
diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc
index eab184e..4b48892 100644
--- a/src/class_linker_test.cc
+++ b/src/class_linker_test.cc
@@ -54,6 +54,9 @@
     EXPECT_EQ(0U, primitive->NumInstanceFields());
     EXPECT_EQ(0U, primitive->NumStaticFields());
     EXPECT_EQ(0U, primitive->NumInterfaces());
+    EXPECT_TRUE(primitive->GetVTable() == NULL);
+    EXPECT_EQ(0, primitive->GetIfTableCount());
+    EXPECT_TRUE(primitive->GetIfTable() == NULL);
   }
 
   void AssertArrayClass(const StringPiece& array_descriptor,
@@ -95,6 +98,12 @@
     EXPECT_EQ(0U, array->NumInstanceFields());
     EXPECT_EQ(0U, array->NumStaticFields());
     EXPECT_EQ(2U, array->NumInterfaces());
+    EXPECT_TRUE(array->GetVTable() != NULL);
+    EXPECT_EQ(2, array->GetIfTableCount());
+    ObjectArray<InterfaceEntry>* iftable = array->GetIfTable();
+    ASSERT_TRUE(iftable != NULL);
+    EXPECT_TRUE(iftable->Get(0)->GetInterface()->GetDescriptor()->Equals("Ljava/lang/Cloneable;"));
+    EXPECT_TRUE(iftable->Get(1)->GetInterface()->GetDescriptor()->Equals("Ljava/io/Serializable;"));
   }
 
   void AssertMethod(Class* klass, Method* method) {
@@ -159,6 +168,20 @@
         EXPECT_NE(0U, klass->NumDirectMethods());
       }
     }
+    EXPECT_EQ(klass->IsInterface(), klass->GetVTable() == NULL);
+    for (int i = 0; i < klass->GetIfTableCount(); i++) {
+      const InterfaceEntry* interface_entry = klass->GetIfTable()->Get(i);
+      ASSERT_TRUE(interface_entry != NULL);
+      Class* interface = interface_entry->GetInterface();
+      ASSERT_TRUE(interface != NULL);
+      EXPECT_TRUE(interface_entry->GetInterface() != NULL);
+      if (klass->IsInterface()) {
+        EXPECT_EQ(0U, interface_entry->GetMethodArrayCount());
+      } else {
+        CHECK_EQ(interface->NumVirtualMethods(), interface_entry->GetMethodArrayCount());
+        EXPECT_EQ(interface->NumVirtualMethods(), interface_entry->GetMethodArrayCount());
+      }
+    }
     if (klass->IsAbstract()) {
       EXPECT_FALSE(klass->IsFinal());
     } else {
diff --git a/src/object.h b/src/object.h
index 2f9ea33..5e09f2e 100644
--- a/src/object.h
+++ b/src/object.h
@@ -2683,6 +2683,14 @@
     Set(kInterface, interface);
   }
 
+  size_t GetMethodArrayCount() const {
+    ObjectArray<Method>* method_array = down_cast<ObjectArray<Method>*>(Get(kMethodArray));
+    if (method_array == 0) {
+      return 0;
+    }
+    return method_array->GetLength();
+  }
+
   ObjectArray<Method>* GetMethodArray() const {
     ObjectArray<Method>* method_array = down_cast<ObjectArray<Method>*>(Get(kMethodArray));
     DCHECK(method_array != NULL);