Revert "Inline and optimize interface calls."

Went ahead too quickly.

This reverts commit d9faceaa8da92f4a56c2907de949081bd42faf79.

Change-Id: I1610deaf89b38037cf2786d135a59c48b10ced0c
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index 8ee04dd..c67b2d5 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -750,35 +750,7 @@
 bool HInliner::TryInlineAndReplace(HInvoke* invoke_instruction, ArtMethod* method, bool do_rtp) {
   HInstruction* return_replacement = nullptr;
   if (!TryBuildAndInline(invoke_instruction, method, &return_replacement)) {
-    if (invoke_instruction->IsInvokeInterface()) {
-      // Turn an invoke-interface into an invoke-virtual. An invoke-virtual is always
-      // better than an invoke-interface because:
-      // 1) In the best case, the interface call has one more indirection (to fetch the IMT).
-      // 2) We will not go to the conflict trampoline with an invoke-virtual.
-      // TODO: Consider sharpening once it is not dependent on the compiler driver.
-      HInvokeVirtual* new_invoke = new (graph_->GetArena()) HInvokeVirtual(
-          graph_->GetArena(),
-          invoke_instruction->GetNumberOfArguments(),
-          invoke_instruction->GetType(),
-          invoke_instruction->GetDexPc(),
-          invoke_instruction->GetDexMethodIndex(),
-          method->GetMethodIndex());
-      HInputsRef inputs = invoke_instruction->GetInputs();
-      size_t index = 0;
-      for (HInstruction* instr : inputs) {
-        new_invoke->SetArgumentAt(index++, instr);
-      }
-      invoke_instruction->GetBlock()->InsertInstructionBefore(new_invoke, invoke_instruction);
-      new_invoke->CopyEnvironmentFrom(invoke_instruction->GetEnvironment());
-      if (invoke_instruction->GetType() == Primitive::kPrimNot) {
-        new_invoke->SetReferenceTypeInfo(invoke_instruction->GetReferenceTypeInfo());
-      }
-      return_replacement = new_invoke;
-    } else {
-      // TODO: Consider sharpening an invoke virtual once it is not dependent on the
-      // compiler driver.
-      return false;
-    }
+    return false;
   }
   if (return_replacement != nullptr) {
     invoke_instruction->ReplaceWith(return_replacement);
@@ -1267,6 +1239,14 @@
         return false;
       }
 
+      if (current->IsInvokeInterface()) {
+        // Disable inlining of interface calls. The cost in case of entering the
+        // resolution conflict is currently too high.
+        VLOG(compiler) << "Method " << PrettyMethod(method_index, callee_dex_file)
+                       << " could not be inlined because it has an interface call.";
+        return false;
+      }
+
       if (!same_dex_file && current->NeedsEnvironment()) {
         VLOG(compiler) << "Method " << PrettyMethod(method_index, callee_dex_file)
                        << " could not be inlined because " << current->DebugName()
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index 923ea1a..03771aa 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -2141,7 +2141,11 @@
   StackHandleScope<1> hs(self);
   Handle<mirror::Class> cls(hs.NewHandle(this_object->GetClass()));
 
-  ArtMethod* caller_method = QuickArgumentVisitor::GetCallingMethod(sp);
+  // The optimizing compiler currently does not inline methods that have an interface
+  // invocation. We use the outer method directly to avoid fetching a stack map, which is
+  // more expensive.
+  ArtMethod* caller_method = QuickArgumentVisitor::GetOuterMethod(sp);
+  DCHECK_EQ(caller_method, QuickArgumentVisitor::GetCallingMethod(sp));
 
   // Fetch the dex_method_idx of the target interface method from the caller.
   uint32_t dex_pc = QuickArgumentVisitor::GetCallingDexPc(sp);
diff --git a/test/478-checker-clinit-check-pruning/src/Main.java b/test/478-checker-clinit-check-pruning/src/Main.java
index 95ac1ee..6fc12f1 100644
--- a/test/478-checker-clinit-check-pruning/src/Main.java
+++ b/test/478-checker-clinit-check-pruning/src/Main.java
@@ -103,8 +103,10 @@
     static boolean doThrow = false;
 
     static void $noinline$staticMethod() {
-      // Try defeating inlining.
-      if (doThrow) { throw new Error(); }
+      if (doThrow) {
+        // Try defeating inlining.
+        throw new Error();
+      }
     }
   }
 
@@ -179,8 +181,10 @@
     static boolean doThrow = false;
 
     static void $noinline$staticMethod() {
+      if (doThrow) {
         // Try defeating inlining.
-      if (doThrow) { throw new Error(); }
+        throw new Error();
+      }
     }
   }
 
@@ -241,8 +245,10 @@
     static boolean doThrow = false;
 
     static void $noinline$staticMethod() {
+      if (doThrow) {
         // Try defeating inlining.
-      if (doThrow) { throw new Error(); }
+        throw new Error();
+      }
     }
 
     static {
@@ -308,7 +314,7 @@
 
   static void constClassAndInvokeStatic(Iterable<?> it) {
     $opt$inline$ignoreClass(ClassWithClinit7.class);
-    ClassWithClinit7.$noinline$someStaticMethod(it);
+    ClassWithClinit7.someStaticMethod(it);
   }
 
   static void $opt$inline$ignoreClass(Class<?> c) {
@@ -319,10 +325,10 @@
       System.out.println("Main$ClassWithClinit7's static initializer");
     }
 
-    static void $noinline$someStaticMethod(Iterable<?> it) {
+    // Note: not inlined from constClassAndInvokeStatic() but fully inlined from main().
+    static void someStaticMethod(Iterable<?> it) {
+      // We're not inlining invoke-interface at the moment.
       it.iterator();
-      // We're not inlining throw at the moment.
-      if (doThrow) { throw new Error(""); }
     }
   }
 
@@ -339,7 +345,7 @@
 
   static void sgetAndInvokeStatic(Iterable<?> it) {
     $opt$inline$ignoreInt(ClassWithClinit8.value);
-    ClassWithClinit8.$noinline$someStaticMethod(it);
+    ClassWithClinit8.someStaticMethod(it);
   }
 
   static void $opt$inline$ignoreInt(int i) {
@@ -351,10 +357,10 @@
       System.out.println("Main$ClassWithClinit8's static initializer");
     }
 
-    static void $noinline$someStaticMethod(Iterable<?> it) {
+    // Note: not inlined from sgetAndInvokeStatic() but fully inlined from main().
+    static void someStaticMethod(Iterable<?> it) {
+      // We're not inlining invoke-interface at the moment.
       it.iterator();
-      // We're not inlining throw at the moment.
-      if (doThrow) { throw new Error(""); }
     }
   }
 
@@ -371,7 +377,7 @@
   static void constClassSgetAndInvokeStatic(Iterable<?> it) {
     $opt$inline$ignoreClass(ClassWithClinit9.class);
     $opt$inline$ignoreInt(ClassWithClinit9.value);
-    ClassWithClinit9.$noinline$someStaticMethod(it);
+    ClassWithClinit9.someStaticMethod(it);
   }
 
   static class ClassWithClinit9 {
@@ -380,10 +386,10 @@
       System.out.println("Main$ClassWithClinit9's static initializer");
     }
 
-    static void $noinline$someStaticMethod(Iterable<?> it) {
+    // Note: not inlined from constClassSgetAndInvokeStatic() but fully inlined from main().
+    static void someStaticMethod(Iterable<?> it) {
+      // We're not inlining invoke-interface at the moment.
       it.iterator();
-      // We're not inlining throw at the moment.
-      if (doThrow) { throw new Error(""); }
     }
   }
 
@@ -416,9 +422,8 @@
 
     static void inlinedForNull(Iterable<?> it) {
       if (it != null) {
+        // We're not inlining invoke-interface at the moment.
         it.iterator();
-        // We're not inlining throw at the moment.
-        if (doThrow) { throw new Error(""); }
       }
     }
   }
@@ -455,11 +460,8 @@
     }
 
     static void inlinedForNull(Iterable<?> it) {
+      // We're not inlining invoke-interface at the moment.
       it.iterator();
-      if (it != null) {
-        // We're not inlining throw at the moment.
-        if (doThrow) { throw new Error(""); }
-      }
     }
   }
 
@@ -492,8 +494,8 @@
 
     static void inlinedForNull(Iterable<?> it) {
       if (it != null) {
-        // We're not inlining throw at the moment.
-        if (doThrow) { throw new Error(""); }
+        // We're not inlining invoke-interface at the moment.
+        it.iterator();
       }
     }
   }
@@ -508,9 +510,8 @@
     }
 
     public static void $noinline$getIterator(Iterable<?> it) {
+      // We're not inlining invoke-interface at the moment.
       it.iterator();
-      // We're not inlining throws at the moment.
-      if (doThrow) { throw new Error(""); }
     }
   }
 
diff --git a/test/548-checker-inlining-and-dce/src/Main.java b/test/548-checker-inlining-and-dce/src/Main.java
index bf64c3b..38fdcc0 100644
--- a/test/548-checker-inlining-and-dce/src/Main.java
+++ b/test/548-checker-inlining-and-dce/src/Main.java
@@ -16,19 +16,17 @@
 
 public class Main {
 
-  static boolean doThrow = false;
-
   private void inlinedForNull(Iterable it) {
     if (it != null) {
-      // We're not inlining throw at the moment.
-      if (doThrow) { throw new Error(""); }
+      // We're not inlining invoke-interface at the moment.
+      it.iterator();
     }
   }
 
   private void inlinedForFalse(boolean value, Iterable it) {
     if (value) {
-      // We're not inlining throw at the moment.
-      if (doThrow) { throw new Error(""); }
+      // We're not inlining invoke-interface at the moment.
+      it.iterator();
     }
   }
 
diff --git a/test/609-checker-inline-interface/expected.txt b/test/609-checker-inline-interface/expected.txt
deleted file mode 100644
index e69de29..0000000
--- a/test/609-checker-inline-interface/expected.txt
+++ /dev/null
diff --git a/test/609-checker-inline-interface/info.txt b/test/609-checker-inline-interface/info.txt
deleted file mode 100644
index 35eee08..0000000
--- a/test/609-checker-inline-interface/info.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Checker test that we inline interface calls and if we can't inline
-them, we can turn them into a virtual invoke.
diff --git a/test/609-checker-inline-interface/src/Main.java b/test/609-checker-inline-interface/src/Main.java
deleted file mode 100644
index e9b3e87..0000000
--- a/test/609-checker-inline-interface/src/Main.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-public final class Main implements Interface {
-
-  static void methodWithInvokeInterface(Interface interf) {
-    interf.$noinline$doCall();
-  }
-
-  public void $noinline$doCall() {
-    if (doThrow) throw new Error("");
-  }
-
-  public static void main(String[] args) {
-    testInlineInterfaceCall();
-    testInterfaceToVirtualCall();
-  }
-
-  /// CHECK-START: void Main.testInlineInterfaceCall() inliner (before)
-  /// CHECK:                          InvokeStaticOrDirect method_name:Main.methodWithInvokeInterface
-
-  /// CHECK-START: void Main.testInlineInterfaceCall() inliner (before)
-  /// CHECK-NOT:                      InvokeInterface
-
-  /// CHECK-START: void Main.testInlineInterfaceCall() inliner (after)
-  /// CHECK:                          InvokeInterface method_name:Interface.$noinline$doCall
-
-  /// CHECK-START: void Main.testInlineInterfaceCall() inliner (after)
-  /// CHECK-NOT:                      InvokeStaticOrDirect
-  public static void testInlineInterfaceCall() {
-    methodWithInvokeInterface(itf);
-  }
-
-  /// CHECK-START: void Main.testInterfaceToVirtualCall() inliner (before)
-  /// CHECK:                          InvokeStaticOrDirect method_name:Main.methodWithInvokeInterface
-
-  /// CHECK-START: void Main.testInterfaceToVirtualCall() inliner (before)
-  /// CHECK-NOT:                      InvokeInterface
-
-  /// CHECK-START: void Main.testInterfaceToVirtualCall() inliner (after)
-  /// CHECK:                          InvokeVirtual method_name:Main.$noinline$doCall
-
-  /// CHECK-START: void Main.testInterfaceToVirtualCall() inliner (after)
-  /// CHECK-NOT:                      InvokeStaticOrDirect
-  /// CHECK-NOT:                      InvokeInterface
-  public static void testInterfaceToVirtualCall() {
-    methodWithInvokeInterface(m);
-  }
-
-  static Interface itf = new Main();
-  static Main m = new Main();
-  static boolean doThrow = false;
-}
-
-interface Interface {
-  public void $noinline$doCall();
-}