Cleanup polymorphic inlining to the same target.

- Don't do expensive lookups, just fetch the ArtMethods from the
  imtable or vtable.
- Don't perform the optimization if we may end up in the conflicting
  trampoline.

bug:27398183

(cherry picked from commit 4f97a212b6ff801eb9f7f88a87f44e0584339cca)

Change-Id: Ia4007743ae00860f679f96f45eb14d26e6dc3fce
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index 4d56a41..0fa8782 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -588,6 +588,10 @@
 
   DCHECK(resolved_method != nullptr);
   ArtMethod* actual_method = nullptr;
+  size_t method_index = invoke_instruction->IsInvokeVirtual()
+      ? invoke_instruction->AsInvokeVirtual()->GetVTableIndex()
+      : invoke_instruction->AsInvokeInterface()->GetImtIndex();
+
   // Check whether we are actually calling the same method among
   // the different types seen.
   for (size_t i = 0; i < InlineCache::kIndividualCacheSize; ++i) {
@@ -596,13 +600,18 @@
     }
     ArtMethod* new_method = nullptr;
     if (invoke_instruction->IsInvokeInterface()) {
-      new_method = ic.GetTypeAt(i)->FindVirtualMethodForInterface(
-          resolved_method, pointer_size);
+      new_method = ic.GetTypeAt(i)->GetEmbeddedImTableEntry(
+          method_index % mirror::Class::kImtSize, pointer_size);
+      if (new_method->IsRuntimeMethod()) {
+        // Bail out as soon as we see a conflict trampoline in one of the target's
+        // interface table.
+        return false;
+      }
     } else {
       DCHECK(invoke_instruction->IsInvokeVirtual());
-      new_method = ic.GetTypeAt(i)->FindVirtualMethodForVirtual(
-          resolved_method, pointer_size);
+      new_method = ic.GetTypeAt(i)->GetEmbeddedVTableEntry(method_index, pointer_size);
     }
+    DCHECK(new_method != nullptr);
     if (actual_method == nullptr) {
       actual_method = new_method;
     } else if (actual_method != new_method) {
@@ -626,10 +635,6 @@
   HInstanceFieldGet* receiver_class = BuildGetReceiverClass(
       class_linker, receiver, invoke_instruction->GetDexPc());
 
-  size_t method_offset = invoke_instruction->IsInvokeVirtual()
-      ? actual_method->GetVtableIndex()
-      : invoke_instruction->AsInvokeInterface()->GetImtIndex();
-
   Primitive::Type type = Is64BitInstructionSet(graph_->GetInstructionSet())
       ? Primitive::kPrimLong
       : Primitive::kPrimInt;
@@ -637,7 +642,7 @@
       receiver_class,
       type,
       invoke_instruction->IsInvokeVirtual() ? HClassTableGet::kVTable : HClassTableGet::kIMTable,
-      method_offset,
+      method_index,
       invoke_instruction->GetDexPc());
 
   HConstant* constant;