diff options
author | 2016-07-06 14:01:50 +0000 | |
---|---|---|
committer | 2016-07-06 14:01:50 +0000 | |
commit | 19dc255bf94a4229de8627a2079ee6f0e9005e2d (patch) | |
tree | 38ce4ec6ab0ae5ed99f16c695441135fd36d26dd | |
parent | d9faceaa8da92f4a56c2907de949081bd42faf79 (diff) |
Revert "Inline and optimize interface calls."
Went ahead too quickly.
This reverts commit d9faceaa8da92f4a56c2907de949081bd42faf79.
Change-Id: I1610deaf89b38037cf2786d135a59c48b10ced0c
-rw-r--r-- | compiler/optimizing/inliner.cc | 38 | ||||
-rw-r--r-- | runtime/entrypoints/quick/quick_trampoline_entrypoints.cc | 6 | ||||
-rw-r--r-- | test/478-checker-clinit-check-pruning/src/Main.java | 53 | ||||
-rw-r--r-- | test/548-checker-inlining-and-dce/src/Main.java | 10 | ||||
-rw-r--r-- | test/609-checker-inline-interface/expected.txt | 0 | ||||
-rw-r--r-- | test/609-checker-inline-interface/info.txt | 2 | ||||
-rw-r--r-- | test/609-checker-inline-interface/src/Main.java | 70 |
7 files changed, 45 insertions, 134 deletions
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index 8ee04dd396..c67b2d5fe9 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -750,35 +750,7 @@ bool HInliner::TryInlinePolymorphicCallToSameTarget(HInvoke* invoke_instruction, 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 @@ bool HInliner::TryBuildAndInlineHelper(HInvoke* invoke_instruction, 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 923ea1a25a..03771aa80e 100644 --- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc @@ -2141,7 +2141,11 @@ extern "C" TwoWordReturn artInvokeInterfaceTrampoline(uint32_t deadbeef ATTRIBUT 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 95ac1ee7ed..6fc12f138c 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 @@ public class Main { 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 @@ public class Main { 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 @@ public class Main { 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 @@ public class Main { 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 @@ public class Main { 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 @@ public class Main { 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 @@ public class Main { 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 @@ public class Main { 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 @@ public class Main { 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 @@ public class Main { 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 @@ public class Main { } 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 @@ public class Main { 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 class Main { } 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 bf64c3bb36..38fdcc0b94 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 e69de29bb2..0000000000 --- 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 35eee08985..0000000000 --- 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 e9b3e87881..0000000000 --- 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(); -} |