diff options
Diffstat (limited to 'compiler/optimizing/instruction_builder.cc')
-rw-r--r-- | compiler/optimizing/instruction_builder.cc | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc index 4ae94b7b3f..1e7b48e4a5 100644 --- a/compiler/optimizing/instruction_builder.cc +++ b/compiler/optimizing/instruction_builder.cc @@ -1002,14 +1002,27 @@ bool HInstructionBuilder::BuildInvoke(const Instruction& instruction, resolved_method->GetMethodIndex()); } else { DCHECK_EQ(invoke_type, kInterface); - ScopedObjectAccess soa(Thread::Current()); // Needed for the IMT index. - invoke = new (allocator_) HInvokeInterface(allocator_, + ScopedObjectAccess soa(Thread::Current()); // Needed for the IMT index and class check below. + if (resolved_method->GetDeclaringClass()->IsObjectClass()) { + // If the resolved method is from j.l.Object, emit a virtual call instead. + // The IMT conflict stub only handles interface methods. + invoke = new (allocator_) HInvokeVirtual(allocator_, number_of_arguments, return_type, dex_pc, method_idx, resolved_method, - ImTable::GetImtIndex(resolved_method)); + resolved_method->GetMethodIndex()); + } else { + DCHECK(resolved_method->GetDeclaringClass()->IsInterface()); + invoke = new (allocator_) HInvokeInterface(allocator_, + number_of_arguments, + return_type, + dex_pc, + method_idx, + resolved_method, + ImTable::GetImtIndex(resolved_method)); + } } return HandleInvoke(invoke, operands, shorty, /* is_unresolved= */ false, clinit_check); } |