Optimizing compiler support for directly calling interface methods

This teaches the optimizing compiler how to perform invoke-super on
interfaces. This should make the invokes generally faster.

Bug: 24618811

Change-Id: I7f9b0fb1209775c1c8837ab5d21f8acba3cc72a5
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index 638fdb4..24986253 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -1036,8 +1036,15 @@
       } else {
         DCHECK_EQ(invoke_type, kSuper);
         CHECK(caller != nullptr) << invoke_type;
-        called = caller->GetDeclaringClass()->GetSuperClass()->GetVTableEntry(
-            called->GetMethodIndex(), sizeof(void*));
+        // TODO Maybe put this into a mirror::Class function.
+        mirror::Class* ref_class = linker->ResolveReferencedClassOfMethod(
+            self, called_method.dex_method_index, caller);
+        if (ref_class->IsInterface()) {
+          called = ref_class->FindVirtualMethodForInterfaceSuper(called, sizeof(void*));
+        } else {
+          called = caller->GetDeclaringClass()->GetSuperClass()->GetVTableEntry(
+              called->GetMethodIndex(), sizeof(void*));
+        }
       }
 
       CHECK(called != nullptr) << PrettyMethod(orig_called) << " "