summaryrefslogtreecommitdiff
path: root/compiler/optimizing/instruction_builder.cc
diff options
context:
space:
mode:
authorNicolas Geoffray <ngeoffray@google.com>2020-09-09 13:57:17 +0100
committerNicolas Geoffray <ngeoffray@google.com>2020-09-11 13:20:58 +0000
commit1fef877c66f066f01653ea98bfefe29304198193 (patch)
tree65561c8b15844cabe32728b61d1e5d586976acf3 /compiler/optimizing/instruction_builder.cc
parenta41ea2708d143b5982f1969864513b62706d11d4 (diff)
Handle more cases of super calls in the compiler.
Add support for calling super methods that are not referenced within the compiling dex file. Test: 808-checker-invoke-super Test: 809-checker-invoke-super-bss Change-Id: Ib103f818ac8b612a79b6b18cc8eda81131bb3149
Diffstat (limited to 'compiler/optimizing/instruction_builder.cc')
-rw-r--r--compiler/optimizing/instruction_builder.cc32
1 files changed, 18 insertions, 14 deletions
diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc
index 3401e65163..9fb9c4e7fe 100644
--- a/compiler/optimizing/instruction_builder.cc
+++ b/compiler/optimizing/instruction_builder.cc
@@ -957,18 +957,6 @@ static ArtMethod* ResolveMethod(uint16_t method_idx,
actual_method = compiling_class->GetSuperClass()->GetVTableEntry(
vtable_index, class_linker->GetImagePointerSize());
}
- if (actual_method != resolved_method &&
- !IsSameDexFile(*actual_method->GetDexFile(), *dex_compilation_unit.GetDexFile())) {
- // The back-end code generator relies on this check in order to ensure that it will not
- // attempt to read the dex_cache with a dex_method_index that is not from the correct
- // dex_file. If we didn't do this check then the dex_method_index will not be updated in the
- // builder, which means that the code-generator (and sharpening and inliner, maybe)
- // might invoke an incorrect method.
- // TODO: The actual method could still be referenced in the current dex file, so we
- // could try locating it.
- // TODO: Remove the dex_file restriction.
- return nullptr;
- }
if (!actual_method->IsInvokable()) {
// Fail if the actual method cannot be invoked. Otherwise, the runtime resolution stub
// could resolve the callee to the wrong method.
@@ -1092,15 +1080,31 @@ bool HInstructionBuilder::BuildInvoke(const Instruction& instruction,
HInvoke* invoke = nullptr;
if (invoke_type == kDirect || invoke_type == kStatic || invoke_type == kSuper) {
+ // For sharpening, we create another MethodReference, to account for the
+ // kSuper case below where we cannot find a dex method index.
+ bool has_method_id = true;
if (invoke_type == kSuper) {
+ uint32_t dex_method_index = method_reference.index;
if (IsSameDexFile(*method_info.dex_file, *dex_compilation_unit_->GetDexFile())) {
// Update the method index to the one resolved. Note that this may be a no-op if
// we resolved to the method referenced by the instruction.
- method_reference.index = method_info.index;
+ dex_method_index = method_info.index;
+ } else {
+ // Try to find a dex method index in this caller's dex file.
+ ScopedObjectAccess soa(Thread::Current());
+ dex_method_index = resolved_method->FindDexMethodIndexInOtherDexFile(
+ *dex_compilation_unit_->GetDexFile(), method_idx);
+ }
+ if (dex_method_index == dex::kDexNoIndex) {
+ has_method_id = false;
+ } else {
+ method_reference.index = dex_method_index;
}
}
HInvokeStaticOrDirect::DispatchInfo dispatch_info =
- HSharpening::SharpenInvokeStaticOrDirect(resolved_method, code_generator_);
+ HSharpening::SharpenInvokeStaticOrDirect(resolved_method,
+ has_method_id,
+ code_generator_);
if (dispatch_info.code_ptr_location ==
HInvokeStaticOrDirect::CodePtrLocation::kCallCriticalNative) {
graph_->SetHasDirectCriticalNativeCall(true);