diff options
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/instruction_builder.cc | 32 | ||||
-rw-r--r-- | compiler/optimizing/instruction_simplifier.cc | 3 | ||||
-rw-r--r-- | compiler/optimizing/sharpening.cc | 7 | ||||
-rw-r--r-- | compiler/optimizing/sharpening.h | 2 |
4 files changed, 27 insertions, 17 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); diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc index d586306a2c..d616912b9f 100644 --- a/compiler/optimizing/instruction_simplifier.cc +++ b/compiler/optimizing/instruction_simplifier.cc @@ -2310,7 +2310,8 @@ void InstructionSimplifierVisitor::SimplifySystemArrayCopy(HInvoke* instruction) // the invoke, as we would need to look it up in the current dex file, and it // is unlikely that it exists. The most usual situation for such typed // arraycopy methods is a direct pointer to the boot image. - invoke->SetDispatchInfo(HSharpening::SharpenInvokeStaticOrDirect(method, codegen_)); + invoke->SetDispatchInfo( + HSharpening::SharpenInvokeStaticOrDirect(method, /* has_method_id= */ true, codegen_)); } } } diff --git a/compiler/optimizing/sharpening.cc b/compiler/optimizing/sharpening.cc index 04a8eab530..f658f8ad07 100644 --- a/compiler/optimizing/sharpening.cc +++ b/compiler/optimizing/sharpening.cc @@ -58,7 +58,7 @@ static bool BootImageAOTCanEmbedMethod(ArtMethod* method, const CompilerOptions& } HInvokeStaticOrDirect::DispatchInfo HSharpening::SharpenInvokeStaticOrDirect( - ArtMethod* callee, CodeGenerator* codegen) { + ArtMethod* callee, bool has_method_id, CodeGenerator* codegen) { if (kIsDebugBuild) { ScopedObjectAccess soa(Thread::Current()); // Required for GetDeclaringClass below. DCHECK(callee != nullptr); @@ -96,6 +96,8 @@ HInvokeStaticOrDirect::DispatchInfo HSharpening::SharpenInvokeStaticOrDirect( method_load_kind = HInvokeStaticOrDirect::MethodLoadKind::kBootImageRelRo; } else if (BootImageAOTCanEmbedMethod(callee, compiler_options)) { method_load_kind = HInvokeStaticOrDirect::MethodLoadKind::kBootImageLinkTimePcRelative; + } else if (!has_method_id) { + method_load_kind = HInvokeStaticOrDirect::MethodLoadKind::kRuntimeCall; } else { // Use PC-relative access to the .bss methods array. method_load_kind = HInvokeStaticOrDirect::MethodLoadKind::kBssEntry; @@ -118,6 +120,9 @@ HInvokeStaticOrDirect::DispatchInfo HSharpening::SharpenInvokeStaticOrDirect( // Use PC-relative access to the .data.bimg.rel.ro methods array. method_load_kind = HInvokeStaticOrDirect::MethodLoadKind::kBootImageRelRo; code_ptr_location = HInvokeStaticOrDirect::CodePtrLocation::kCallArtMethod; + } else if (!has_method_id) { + method_load_kind = HInvokeStaticOrDirect::MethodLoadKind::kRuntimeCall; + code_ptr_location = HInvokeStaticOrDirect::CodePtrLocation::kCallArtMethod; } else { // Use PC-relative access to the .bss methods array. method_load_kind = HInvokeStaticOrDirect::MethodLoadKind::kBssEntry; diff --git a/compiler/optimizing/sharpening.h b/compiler/optimizing/sharpening.h index b81867201f..b48cd4b9b3 100644 --- a/compiler/optimizing/sharpening.h +++ b/compiler/optimizing/sharpening.h @@ -31,7 +31,7 @@ class HSharpening { public: // Used by the builder and InstructionSimplifier. static HInvokeStaticOrDirect::DispatchInfo SharpenInvokeStaticOrDirect( - ArtMethod* callee, CodeGenerator* codegen); + ArtMethod* callee, bool has_method_id, CodeGenerator* codegen); // Used by the builder and the inliner. static HLoadClass::LoadKind ComputeLoadClassKind(HLoadClass* load_class, |