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;
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());
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) {}
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(); }
DECLARE_INSTRUCTION(InvokeStaticOrDirect);
private:
+ const InvokeType original_invoke_type_;
const InvokeType invoke_type_;
const bool is_recursive_;
--- /dev/null
+/*
+* 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");
+ }
+ }
+}