Avoid VarHandle checks for boot image field VarHandles.
And use the field offset as seen at compile time.
Implemented for x86-64, arm and arm64 but not for x86
with incomplete set of `VarHandle` intrinsics.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Test: run-gtests.sh
Test: testrunner.py --target --optimizing
Bug: 191765508
Change-Id: If68b0287c8823e69c493dcefb7e61dc34d69fb4f
diff --git a/compiler/optimizing/sharpening.cc b/compiler/optimizing/sharpening.cc
index 8794d5a..17cf3d3 100644
--- a/compiler/optimizing/sharpening.cc
+++ b/compiler/optimizing/sharpening.cc
@@ -171,6 +171,11 @@
dex::TypeIndex type_index = load_class->GetTypeIndex();
const CompilerOptions& compiler_options = codegen->GetCompilerOptions();
+ auto is_class_in_current_boot_image = [&]() {
+ return (compiler_options.IsBootImage() || compiler_options.IsBootImageExtension()) &&
+ compiler_options.IsImageClass(dex_file.StringByTypeIdx(type_index));
+ };
+
bool is_in_boot_image = false;
HLoadClass::LoadKind desired_load_kind = HLoadClass::LoadKind::kInvalid;
@@ -181,12 +186,17 @@
// locations of target classes. The additional register pressure
// for using the ArtMethod* should be considered.
desired_load_kind = HLoadClass::LoadKind::kReferrersClass;
+ // Determine whether the referrer's class is in the boot image.
+ is_in_boot_image = is_class_in_current_boot_image();
} else if (load_class->NeedsAccessCheck()) {
DCHECK_EQ(load_class->GetLoadKind(), HLoadClass::LoadKind::kRuntimeCall);
if (klass != nullptr) {
// Resolved class that needs access check must be really inaccessible
// and the access check is bound to fail. Just emit the runtime call.
desired_load_kind = HLoadClass::LoadKind::kRuntimeCall;
+ // Determine whether the class is in the boot image.
+ is_in_boot_image = Runtime::Current()->GetHeap()->ObjectIsInBootImageSpace(klass.Get()) ||
+ is_class_in_current_boot_image();
} else if (compiler_options.IsJitCompiler()) {
// Unresolved class while JITting means that either we never hit this
// instruction or it failed. Either way, just emit the runtime call.
@@ -222,6 +232,9 @@
if (!compiler_options.GetCompilePic()) {
// Test configuration, do not sharpen.
desired_load_kind = HLoadClass::LoadKind::kRuntimeCall;
+ // Determine whether the class is in the boot image.
+ is_in_boot_image = Runtime::Current()->GetHeap()->ObjectIsInBootImageSpace(klass.Get()) ||
+ is_class_in_current_boot_image();
} else if (klass != nullptr && runtime->GetHeap()->ObjectIsInBootImageSpace(klass.Get())) {
DCHECK(compiler_options.IsBootImageExtension());
is_in_boot_image = true;