diff options
author | Nicolas Geoffray <ngeoffray@google.com> | 2020-02-17 09:40:14 +0000 |
---|---|---|
committer | Nicolas Geoffray <ngeoffray@google.com> | 2020-02-17 14:09:02 +0000 |
commit | 2925311f957f50bbec2b034c98877d22f702ee76 (patch) | |
tree | 31c6bd25134b287622c9998e016606ab2d84607b /compiler/optimizing/instruction_builder.cc | |
parent | f8f51c9697b1f2a41ea750703087e98c46402f08 (diff) |
Prevent entering IMT conflict trampoline with j.l.Object methods.
This ensures that only interface methods enter the trampoline.
Test: 725-imt-conflict-object
Change-Id: Id730d921f213ee0f6d927dea5df69d57be431df0
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); } |