diff options
-rw-r--r-- | compiler/optimizing/builder.cc | 2 | ||||
-rw-r--r-- | compiler/optimizing/inliner.cc | 4 | ||||
-rw-r--r-- | compiler/optimizing/nodes.h | 4 | ||||
-rw-r--r-- | test/464-checker-inline-sharpen-calls/expected.txt | 0 | ||||
-rw-r--r-- | test/464-checker-inline-sharpen-calls/info.txt | 1 | ||||
-rw-r--r-- | test/464-checker-inline-sharpen-calls/src/Main.java | 54 |
6 files changed, 63 insertions, 2 deletions
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc index 8786ed4..f81935a 100644 --- a/compiler/optimizing/builder.cc +++ b/compiler/optimizing/builder.cc @@ -620,7 +620,7 @@ bool HGraphBuilder::BuildInvoke(const Instruction& instruction, DCHECK(!is_recursive || (target_method.dex_file == dex_compilation_unit_->GetDexFile())); invoke = new (arena_) HInvokeStaticOrDirect( arena_, number_of_arguments, return_type, dex_pc, target_method.dex_method_index, - is_recursive, optimized_invoke_type); + is_recursive, invoke_type, optimized_invoke_type); } size_t start_index = 0; diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index 256e85b..4b990f1 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -50,7 +50,9 @@ void HInliner::Run() { HInstruction* next = instruction->GetNext(); HInvokeStaticOrDirect* call = instruction->AsInvokeStaticOrDirect(); if (call != nullptr) { - if (!TryInline(call, call->GetDexMethodIndex(), call->GetInvokeType())) { + // We use the original invoke type to ensure the resolution of the called method + // works properly. + if (!TryInline(call, call->GetDexMethodIndex(), call->GetOriginalInvokeType())) { if (kIsDebugBuild) { std::string callee_name = PrettyMethod(call->GetDexMethodIndex(), *outer_compilation_unit_.GetDexFile()); diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 08b16d9..9c751fb 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -2131,8 +2131,10 @@ class HInvokeStaticOrDirect : public HInvoke { uint32_t dex_pc, uint32_t dex_method_index, bool is_recursive, + InvokeType original_invoke_type, InvokeType invoke_type) : HInvoke(arena, number_of_arguments, return_type, dex_pc, dex_method_index), + original_invoke_type_(original_invoke_type), invoke_type_(invoke_type), is_recursive_(is_recursive) {} @@ -2142,6 +2144,7 @@ class HInvokeStaticOrDirect : public HInvoke { return false; } + InvokeType GetOriginalInvokeType() const { return original_invoke_type_; } InvokeType GetInvokeType() const { return invoke_type_; } bool IsRecursive() const { return is_recursive_; } bool NeedsDexCache() const OVERRIDE { return !IsRecursive(); } @@ -2149,6 +2152,7 @@ class HInvokeStaticOrDirect : public HInvoke { DECLARE_INSTRUCTION(InvokeStaticOrDirect); private: + const InvokeType original_invoke_type_; const InvokeType invoke_type_; const bool is_recursive_; diff --git a/test/464-checker-inline-sharpen-calls/expected.txt b/test/464-checker-inline-sharpen-calls/expected.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/464-checker-inline-sharpen-calls/expected.txt diff --git a/test/464-checker-inline-sharpen-calls/info.txt b/test/464-checker-inline-sharpen-calls/info.txt new file mode 100644 index 0000000..9e56030 --- /dev/null +++ b/test/464-checker-inline-sharpen-calls/info.txt @@ -0,0 +1 @@ +Check that we inline sharpen calls. diff --git a/test/464-checker-inline-sharpen-calls/src/Main.java b/test/464-checker-inline-sharpen-calls/src/Main.java new file mode 100644 index 0000000..1b25b42 --- /dev/null +++ b/test/464-checker-inline-sharpen-calls/src/Main.java @@ -0,0 +1,54 @@ +/* +* Copyright (C) 2015 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 { + + public void invokeVirtual() { + } + + // CHECK-START: void Main.inlineSharpenInvokeVirtual(Main) inliner (before) + // CHECK-DAG: [[Invoke:v\d+]] InvokeStaticOrDirect + // CHECK-DAG: ReturnVoid + + // CHECK-START: void Main.inlineSharpenInvokeVirtual(Main) inliner (after) + // CHECK-NOT: InvokeStaticOrDirect + + public static void inlineSharpenInvokeVirtual(Main m) { + m.invokeVirtual(); + } + + // CHECK-START: int Main.inlineSharpenStringInvoke() inliner (before) + // CHECK-DAG: [[Invoke:i\d+]] InvokeStaticOrDirect + // CHECK-DAG: Return [ [[Invoke]] ] + + // CHECK-START: int Main.inlineSharpenStringInvoke() inliner (after) + // CHECK-NOT: InvokeStaticOrDirect + + // CHECK-START: int Main.inlineSharpenStringInvoke() inliner (after) + // CHECK-DAG: [[Field:i\d+]] InstanceFieldGet + // CHECK-DAG: Return [ [[Field]] ] + + public static int inlineSharpenStringInvoke() { + return "Foo".length(); + } + + public static void main(String[] args) { + inlineSharpenInvokeVirtual(new Main()); + if (inlineSharpenStringInvoke() != 3) { + throw new Error("Expected 3"); + } + } +} |