summaryrefslogtreecommitdiff
path: root/compiler/optimizing/instruction_builder.cc
diff options
context:
space:
mode:
authorNicolas Geoffray <ngeoffray@google.com>2020-02-17 09:40:14 +0000
committerNicolas Geoffray <ngeoffray@google.com>2020-02-17 14:09:02 +0000
commit2925311f957f50bbec2b034c98877d22f702ee76 (patch)
tree31c6bd25134b287622c9998e016606ab2d84607b /compiler/optimizing/instruction_builder.cc
parentf8f51c9697b1f2a41ea750703087e98c46402f08 (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.cc19
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);
}