summaryrefslogtreecommitdiff
path: root/compiler/optimizing/sharpening.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing/sharpening.cc')
-rw-r--r--compiler/optimizing/sharpening.cc91
1 files changed, 63 insertions, 28 deletions
diff --git a/compiler/optimizing/sharpening.cc b/compiler/optimizing/sharpening.cc
index 8637db13ad..b8471e3721 100644
--- a/compiler/optimizing/sharpening.cc
+++ b/compiler/optimizing/sharpening.cc
@@ -19,6 +19,7 @@
#include "art_method-inl.h"
#include "base/casts.h"
#include "base/enums.h"
+#include "base/logging.h"
#include "class_linker.h"
#include "code_generator.h"
#include "driver/compiler_options.h"
@@ -26,29 +27,29 @@
#include "gc/heap.h"
#include "gc/space/image_space.h"
#include "handle_scope-inl.h"
+#include "jit/jit.h"
#include "mirror/dex_cache.h"
#include "mirror/string.h"
#include "nodes.h"
#include "runtime.h"
#include "scoped_thread_state_change-inl.h"
-#include "utils/dex_cache_arrays_layout-inl.h"
namespace art {
static bool IsInBootImage(ArtMethod* method) {
- const std::vector<gc::space::ImageSpace*>& image_spaces =
- Runtime::Current()->GetHeap()->GetBootImageSpaces();
- for (gc::space::ImageSpace* image_space : image_spaces) {
- const ImageSection& method_section = image_space->GetImageHeader().GetMethodsSection();
- if (method_section.Contains(reinterpret_cast<uint8_t*>(method) - image_space->Begin())) {
- return true;
- }
- }
- return false;
+ gc::Heap* heap = Runtime::Current()->GetHeap();
+ DCHECK_EQ(heap->IsBootImageAddress(method),
+ std::any_of(heap->GetBootImageSpaces().begin(),
+ heap->GetBootImageSpaces().end(),
+ [=](gc::space::ImageSpace* space) REQUIRES_SHARED(Locks::mutator_lock_) {
+ return space->GetImageHeader().GetMethodsSection().Contains(
+ reinterpret_cast<uint8_t*>(method) - space->Begin());
+ }));
+ return heap->IsBootImageAddress(method);
}
static bool BootImageAOTCanEmbedMethod(ArtMethod* method, const CompilerOptions& compiler_options) {
- DCHECK(compiler_options.IsBootImage());
+ DCHECK(compiler_options.IsBootImage() || compiler_options.IsBootImageExtension());
ScopedObjectAccess soa(Thread::Current());
ObjPtr<mirror::Class> klass = method->GetDeclaringClass();
DCHECK(klass != nullptr);
@@ -86,10 +87,13 @@ HInvokeStaticOrDirect::DispatchInfo HSharpening::SharpenInvokeStaticOrDirect(
// Recursive call.
method_load_kind = HInvokeStaticOrDirect::MethodLoadKind::kRecursive;
code_ptr_location = HInvokeStaticOrDirect::CodePtrLocation::kCallSelf;
- } else if (compiler_options.IsBootImage()) {
+ } else if (compiler_options.IsBootImage() || compiler_options.IsBootImageExtension()) {
if (!compiler_options.GetCompilePic()) {
// Test configuration, do not sharpen.
method_load_kind = HInvokeStaticOrDirect::MethodLoadKind::kRuntimeCall;
+ } else if (IsInBootImage(callee)) {
+ DCHECK(compiler_options.IsBootImageExtension());
+ method_load_kind = HInvokeStaticOrDirect::MethodLoadKind::kBootImageRelRo;
} else if (BootImageAOTCanEmbedMethod(callee, compiler_options)) {
method_load_kind = HInvokeStaticOrDirect::MethodLoadKind::kBootImageLinkTimePcRelative;
} else {
@@ -98,11 +102,18 @@ HInvokeStaticOrDirect::DispatchInfo HSharpening::SharpenInvokeStaticOrDirect(
}
code_ptr_location = HInvokeStaticOrDirect::CodePtrLocation::kCallArtMethod;
} else if (Runtime::Current()->UseJitCompilation()) {
- // JIT or on-device AOT compilation referencing a boot image method.
- // Use the method address directly.
- method_load_kind = HInvokeStaticOrDirect::MethodLoadKind::kJitDirectAddress;
- method_load_data = reinterpret_cast<uintptr_t>(callee);
- code_ptr_location = HInvokeStaticOrDirect::CodePtrLocation::kCallArtMethod;
+ ScopedObjectAccess soa(Thread::Current());
+ if (Runtime::Current()->GetJit()->CanEncodeMethod(
+ callee,
+ codegen->GetGraph()->IsCompilingForSharedJitCode())) {
+ method_load_kind = HInvokeStaticOrDirect::MethodLoadKind::kJitDirectAddress;
+ method_load_data = reinterpret_cast<uintptr_t>(callee);
+ code_ptr_location = HInvokeStaticOrDirect::CodePtrLocation::kCallArtMethod;
+ } else {
+ // Do not sharpen.
+ method_load_kind = HInvokeStaticOrDirect::MethodLoadKind::kRuntimeCall;
+ code_ptr_location = HInvokeStaticOrDirect::CodePtrLocation::kCallArtMethod;
+ }
} else if (IsInBootImage(callee)) {
// Use PC-relative access to the .data.bimg.rel.ro methods array.
method_load_kind = HInvokeStaticOrDirect::MethodLoadKind::kBootImageRelRo;
@@ -152,19 +163,22 @@ HLoadClass::LoadKind HSharpening::ComputeLoadClassKind(
HLoadClass::LoadKind desired_load_kind = HLoadClass::LoadKind::kInvalid;
Runtime* runtime = Runtime::Current();
const CompilerOptions& compiler_options = codegen->GetCompilerOptions();
- if (compiler_options.IsBootImage()) {
- // Compiling boot image. Check if the class is a boot image class.
+ if (compiler_options.IsBootImage() || compiler_options.IsBootImageExtension()) {
+ // Compiling boot image or boot image extension. Check if the class is a boot image class.
DCHECK(!runtime->UseJitCompilation());
if (!compiler_options.GetCompilePic()) {
// Test configuration, do not sharpen.
desired_load_kind = HLoadClass::LoadKind::kRuntimeCall;
+ } else if (klass != nullptr && runtime->GetHeap()->ObjectIsInBootImageSpace(klass.Get())) {
+ DCHECK(compiler_options.IsBootImageExtension());
+ is_in_boot_image = true;
+ desired_load_kind = HLoadClass::LoadKind::kBootImageRelRo;
} else if ((klass != nullptr) &&
compiler_options.IsImageClass(dex_file.StringByTypeIdx(type_index))) {
is_in_boot_image = true;
desired_load_kind = HLoadClass::LoadKind::kBootImageLinkTimePcRelative;
} else {
// Not a boot image class.
- DCHECK(ContainsElement(compiler_options.GetDexFilesForOatFile(), &dex_file));
desired_load_kind = HLoadClass::LoadKind::kBssEntry;
}
} else {
@@ -175,7 +189,16 @@ HLoadClass::LoadKind HSharpening::ComputeLoadClassKind(
if (is_in_boot_image) {
desired_load_kind = HLoadClass::LoadKind::kJitBootImageAddress;
} else if (klass != nullptr) {
- desired_load_kind = HLoadClass::LoadKind::kJitTableAddress;
+ if (runtime->GetJit()->CanEncodeClass(
+ klass.Get(),
+ codegen->GetGraph()->IsCompilingForSharedJitCode())) {
+ desired_load_kind = HLoadClass::LoadKind::kJitTableAddress;
+ } else {
+ // Shared JIT code cannot encode a literal that the GC can move.
+ VLOG(jit) << "Unable to encode in shared region class literal: "
+ << klass->PrettyClass();
+ desired_load_kind = HLoadClass::LoadKind::kRuntimeCall;
+ }
} else {
// Class not loaded yet. This happens when the dex code requesting
// this `HLoadClass` hasn't been executed in the interpreter.
@@ -299,12 +322,11 @@ void HSharpening::ProcessLoadString(
ObjPtr<mirror::String> string = nullptr;
const CompilerOptions& compiler_options = codegen->GetCompilerOptions();
- if (compiler_options.IsBootImage()) {
- // Compiling boot image. Resolve the string and allocate it if needed, to ensure
- // the string will be added to the boot image.
+ if (compiler_options.IsBootImage() || compiler_options.IsBootImageExtension()) {
+ // Compiling boot image or boot image extension. Resolve the string and allocate it
+ // if needed, to ensure the string will be added to the boot image.
DCHECK(!runtime->UseJitCompilation());
if (compiler_options.GetCompilePic()) {
- DCHECK(ContainsElement(compiler_options.GetDexFilesForOatFile(), &dex_file));
if (compiler_options.IsForceDeterminism()) {
// Strings for methods we're compiling should be pre-resolved but Strings in inlined
// methods may not be if these inlined methods are not in the boot image profile.
@@ -319,7 +341,12 @@ void HSharpening::ProcessLoadString(
CHECK(string != nullptr);
}
if (string != nullptr) {
- desired_load_kind = HLoadString::LoadKind::kBootImageLinkTimePcRelative;
+ if (runtime->GetHeap()->ObjectIsInBootImageSpace(string)) {
+ DCHECK(compiler_options.IsBootImageExtension());
+ desired_load_kind = HLoadString::LoadKind::kBootImageRelRo;
+ } else {
+ desired_load_kind = HLoadString::LoadKind::kBootImageLinkTimePcRelative;
+ }
} else {
desired_load_kind = HLoadString::LoadKind::kBssEntry;
}
@@ -331,10 +358,18 @@ void HSharpening::ProcessLoadString(
DCHECK(!codegen->GetCompilerOptions().GetCompilePic());
string = class_linker->LookupString(string_index, dex_cache.Get());
if (string != nullptr) {
- if (runtime->GetHeap()->ObjectIsInBootImageSpace(string)) {
+ gc::Heap* heap = runtime->GetHeap();
+ if (heap->ObjectIsInBootImageSpace(string)) {
desired_load_kind = HLoadString::LoadKind::kJitBootImageAddress;
- } else {
+ } else if (runtime->GetJit()->CanEncodeString(
+ string,
+ codegen->GetGraph()->IsCompilingForSharedJitCode())) {
desired_load_kind = HLoadString::LoadKind::kJitTableAddress;
+ } else {
+ // Shared JIT code cannot encode a literal that the GC can move.
+ VLOG(jit) << "Unable to encode in shared region string literal: "
+ << string->ToModifiedUtf8();
+ desired_load_kind = HLoadString::LoadKind::kRuntimeCall;
}
} else {
desired_load_kind = HLoadString::LoadKind::kRuntimeCall;