summaryrefslogtreecommitdiff
path: root/compiler/optimizing
diff options
context:
space:
mode:
author Vladimir Marko <vmarko@google.com> 2024-04-12 11:00:19 +0000
committer VladimĂ­r Marko <vmarko@google.com> 2024-05-07 18:06:47 +0000
commit488413f47e7552d067edf9cfd5ceda321fc12f88 (patch)
tree7bc33df1846aa6838babe2f1f5b6c60137a7eb71 /compiler/optimizing
parenta463b165408222e3ef6a2052ef31b1560b3afea6 (diff)
Faster `HLoadClass` for app image classes.
Add app image relocations for classes in the app image, similar to the existing relocations for boot image. This new load kind lets the compiled code avoid the null check and slow path. Test: m test-art-host-gtest Test: testrunner.py --host --optimizing --speed-profile Test: run-test.sh Test: testrunner.py --target --optimizing --speed-profile Bug: 38313278 Change-Id: Iffd76fe9ac6b95c37c2781fd6257e1d5cd0790d0
Diffstat (limited to 'compiler/optimizing')
-rw-r--r--compiler/optimizing/code_generator_arm64.cc27
-rw-r--r--compiler/optimizing/code_generator_arm64.h10
-rw-r--r--compiler/optimizing/code_generator_arm_vixl.cc20
-rw-r--r--compiler/optimizing/code_generator_arm_vixl.h3
-rw-r--r--compiler/optimizing/code_generator_riscv64.cc23
-rw-r--r--compiler/optimizing/code_generator_riscv64.h5
-rw-r--r--compiler/optimizing/code_generator_x86.cc22
-rw-r--r--compiler/optimizing/code_generator_x86.h3
-rw-r--r--compiler/optimizing/code_generator_x86_64.cc20
-rw-r--r--compiler/optimizing/code_generator_x86_64.h3
-rw-r--r--compiler/optimizing/nodes.h7
-rw-r--r--compiler/optimizing/sharpening.cc2
12 files changed, 144 insertions, 1 deletions
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc
index cfa28eda25..988809ee48 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -1011,6 +1011,7 @@ CodeGeneratorARM64::CodeGeneratorARM64(HGraph* graph,
boot_image_method_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
method_bss_entry_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
boot_image_type_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
+ app_image_type_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
type_bss_entry_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
public_type_bss_entry_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
package_type_bss_entry_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
@@ -5155,6 +5156,13 @@ vixl::aarch64::Label* CodeGeneratorARM64::NewBootImageTypePatch(
return NewPcRelativePatch(&dex_file, type_index.index_, adrp_label, &boot_image_type_patches_);
}
+vixl::aarch64::Label* CodeGeneratorARM64::NewAppImageTypePatch(
+ const DexFile& dex_file,
+ dex::TypeIndex type_index,
+ vixl::aarch64::Label* adrp_label) {
+ return NewPcRelativePatch(&dex_file, type_index.index_, adrp_label, &app_image_type_patches_);
+}
+
vixl::aarch64::Label* CodeGeneratorARM64::NewBssEntryTypePatch(
HLoadClass* load_class,
vixl::aarch64::Label* adrp_label) {
@@ -5365,6 +5373,7 @@ void CodeGeneratorARM64::EmitLinkerPatches(ArenaVector<linker::LinkerPatch>* lin
boot_image_method_patches_.size() +
method_bss_entry_patches_.size() +
boot_image_type_patches_.size() +
+ app_image_type_patches_.size() +
type_bss_entry_patches_.size() +
public_type_bss_entry_patches_.size() +
package_type_bss_entry_patches_.size() +
@@ -5387,12 +5396,15 @@ void CodeGeneratorARM64::EmitLinkerPatches(ArenaVector<linker::LinkerPatch>* lin
DCHECK(boot_image_type_patches_.empty());
DCHECK(boot_image_string_patches_.empty());
}
+ DCHECK_IMPLIES(!GetCompilerOptions().IsAppImage(), app_image_type_patches_.empty());
if (GetCompilerOptions().IsBootImage()) {
EmitPcRelativeLinkerPatches<NoDexFileAdapter<linker::LinkerPatch::IntrinsicReferencePatch>>(
boot_image_other_patches_, linker_patches);
} else {
EmitPcRelativeLinkerPatches<NoDexFileAdapter<linker::LinkerPatch::BootImageRelRoPatch>>(
boot_image_other_patches_, linker_patches);
+ EmitPcRelativeLinkerPatches<linker::LinkerPatch::TypeAppImageRelRoPatch>(
+ app_image_type_patches_, linker_patches);
}
EmitPcRelativeLinkerPatches<linker::LinkerPatch::MethodBssEntryPatch>(
method_bss_entry_patches_, linker_patches);
@@ -5504,6 +5516,7 @@ HLoadClass::LoadKind CodeGeneratorARM64::GetSupportedLoadClassKind(
break;
case HLoadClass::LoadKind::kBootImageLinkTimePcRelative:
case HLoadClass::LoadKind::kBootImageRelRo:
+ case HLoadClass::LoadKind::kAppImageRelRo:
case HLoadClass::LoadKind::kBssEntry:
case HLoadClass::LoadKind::kBssEntryPublic:
case HLoadClass::LoadKind::kBssEntryPackage:
@@ -5613,6 +5626,20 @@ void InstructionCodeGeneratorARM64::VisitLoadClass(HLoadClass* cls) NO_THREAD_SA
codegen_->LoadBootImageRelRoEntry(out.W(), boot_image_offset);
break;
}
+ case HLoadClass::LoadKind::kAppImageRelRo: {
+ DCHECK(codegen_->GetCompilerOptions().IsAppImage());
+ DCHECK_EQ(read_barrier_option, kWithoutReadBarrier);
+ // Add ADRP with its PC-relative type patch.
+ const DexFile& dex_file = cls->GetDexFile();
+ dex::TypeIndex type_index = cls->GetTypeIndex();
+ vixl::aarch64::Label* adrp_label = codegen_->NewAppImageTypePatch(dex_file, type_index);
+ codegen_->EmitAdrpPlaceholder(adrp_label, out.X());
+ // Add LDR with its PC-relative type patch.
+ vixl::aarch64::Label* ldr_label =
+ codegen_->NewAppImageTypePatch(dex_file, type_index, adrp_label);
+ codegen_->EmitLdrOffsetPlaceholder(ldr_label, out.W(), out.X());
+ break;
+ }
case HLoadClass::LoadKind::kBssEntry:
case HLoadClass::LoadKind::kBssEntryPublic:
case HLoadClass::LoadKind::kBssEntryPackage: {
diff --git a/compiler/optimizing/code_generator_arm64.h b/compiler/optimizing/code_generator_arm64.h
index 32a69a9df7..78049c5675 100644
--- a/compiler/optimizing/code_generator_arm64.h
+++ b/compiler/optimizing/code_generator_arm64.h
@@ -817,6 +817,14 @@ class CodeGeneratorARM64 : public CodeGenerator {
dex::TypeIndex type_index,
vixl::aarch64::Label* adrp_label = nullptr);
+ // Add a new app image type patch for an instruction and return the label
+ // to be bound before the instruction. The instruction will be either the
+ // ADRP (pass `adrp_label = null`) or the LDR (pass `adrp_label` pointing
+ // to the associated ADRP patch label).
+ vixl::aarch64::Label* NewAppImageTypePatch(const DexFile& dex_file,
+ dex::TypeIndex type_index,
+ vixl::aarch64::Label* adrp_label = nullptr);
+
// Add a new .bss entry type patch for an instruction and return the label
// to be bound before the instruction. The instruction will be either the
// ADRP (pass `adrp_label = null`) or the ADD (pass `adrp_label` pointing
@@ -1150,6 +1158,8 @@ class CodeGeneratorARM64 : public CodeGenerator {
ArenaDeque<PcRelativePatchInfo> method_bss_entry_patches_;
// PC-relative type patch info for kBootImageLinkTimePcRelative.
ArenaDeque<PcRelativePatchInfo> boot_image_type_patches_;
+ // PC-relative type patch info for kAppImageRelRo.
+ ArenaDeque<PcRelativePatchInfo> app_image_type_patches_;
// PC-relative type patch info for kBssEntry.
ArenaDeque<PcRelativePatchInfo> type_bss_entry_patches_;
// PC-relative public type patch info for kBssEntryPublic.
diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc
index a7cc5a6d12..7c1a9b21f2 100644
--- a/compiler/optimizing/code_generator_arm_vixl.cc
+++ b/compiler/optimizing/code_generator_arm_vixl.cc
@@ -1946,6 +1946,7 @@ CodeGeneratorARMVIXL::CodeGeneratorARMVIXL(HGraph* graph,
boot_image_method_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
method_bss_entry_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
boot_image_type_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
+ app_image_type_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
type_bss_entry_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
public_type_bss_entry_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
package_type_bss_entry_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
@@ -7657,6 +7658,7 @@ HLoadClass::LoadKind CodeGeneratorARMVIXL::GetSupportedLoadClassKind(
break;
case HLoadClass::LoadKind::kBootImageLinkTimePcRelative:
case HLoadClass::LoadKind::kBootImageRelRo:
+ case HLoadClass::LoadKind::kAppImageRelRo:
case HLoadClass::LoadKind::kBssEntry:
case HLoadClass::LoadKind::kBssEntryPublic:
case HLoadClass::LoadKind::kBssEntryPackage:
@@ -7760,6 +7762,15 @@ void InstructionCodeGeneratorARMVIXL::VisitLoadClass(HLoadClass* cls) NO_THREAD_
codegen_->LoadBootImageRelRoEntry(out, boot_image_offset);
break;
}
+ case HLoadClass::LoadKind::kAppImageRelRo: {
+ DCHECK(codegen_->GetCompilerOptions().IsAppImage());
+ DCHECK_EQ(read_barrier_option, kWithoutReadBarrier);
+ CodeGeneratorARMVIXL::PcRelativePatchInfo* labels =
+ codegen_->NewAppImageTypePatch(cls->GetDexFile(), cls->GetTypeIndex());
+ codegen_->EmitMovwMovtPlaceholder(labels, out);
+ __ Ldr(out, MemOperand(out, /*offset=*/ 0));
+ break;
+ }
case HLoadClass::LoadKind::kBssEntry:
case HLoadClass::LoadKind::kBssEntryPublic:
case HLoadClass::LoadKind::kBssEntryPackage: {
@@ -9691,6 +9702,11 @@ CodeGeneratorARMVIXL::PcRelativePatchInfo* CodeGeneratorARMVIXL::NewBootImageTyp
return NewPcRelativePatch(&dex_file, type_index.index_, &boot_image_type_patches_);
}
+CodeGeneratorARMVIXL::PcRelativePatchInfo* CodeGeneratorARMVIXL::NewAppImageTypePatch(
+ const DexFile& dex_file, dex::TypeIndex type_index) {
+ return NewPcRelativePatch(&dex_file, type_index.index_, &app_image_type_patches_);
+}
+
CodeGeneratorARMVIXL::PcRelativePatchInfo* CodeGeneratorARMVIXL::NewTypeBssEntryPatch(
HLoadClass* load_class) {
const DexFile& dex_file = load_class->GetDexFile();
@@ -9877,6 +9893,7 @@ void CodeGeneratorARMVIXL::EmitLinkerPatches(ArenaVector<linker::LinkerPatch>* l
/* MOVW+MOVT for each entry */ 2u * boot_image_method_patches_.size() +
/* MOVW+MOVT for each entry */ 2u * method_bss_entry_patches_.size() +
/* MOVW+MOVT for each entry */ 2u * boot_image_type_patches_.size() +
+ /* MOVW+MOVT for each entry */ 2u * app_image_type_patches_.size() +
/* MOVW+MOVT for each entry */ 2u * type_bss_entry_patches_.size() +
/* MOVW+MOVT for each entry */ 2u * public_type_bss_entry_patches_.size() +
/* MOVW+MOVT for each entry */ 2u * package_type_bss_entry_patches_.size() +
@@ -9898,12 +9915,15 @@ void CodeGeneratorARMVIXL::EmitLinkerPatches(ArenaVector<linker::LinkerPatch>* l
DCHECK(boot_image_type_patches_.empty());
DCHECK(boot_image_string_patches_.empty());
}
+ DCHECK_IMPLIES(!GetCompilerOptions().IsAppImage(), app_image_type_patches_.empty());
if (GetCompilerOptions().IsBootImage()) {
EmitPcRelativeLinkerPatches<NoDexFileAdapter<linker::LinkerPatch::IntrinsicReferencePatch>>(
boot_image_other_patches_, linker_patches);
} else {
EmitPcRelativeLinkerPatches<NoDexFileAdapter<linker::LinkerPatch::BootImageRelRoPatch>>(
boot_image_other_patches_, linker_patches);
+ EmitPcRelativeLinkerPatches<linker::LinkerPatch::TypeAppImageRelRoPatch>(
+ app_image_type_patches_, linker_patches);
}
EmitPcRelativeLinkerPatches<linker::LinkerPatch::MethodBssEntryPatch>(
method_bss_entry_patches_, linker_patches);
diff --git a/compiler/optimizing/code_generator_arm_vixl.h b/compiler/optimizing/code_generator_arm_vixl.h
index a62097d08f..51bee1cd77 100644
--- a/compiler/optimizing/code_generator_arm_vixl.h
+++ b/compiler/optimizing/code_generator_arm_vixl.h
@@ -709,6 +709,7 @@ class CodeGeneratorARMVIXL : public CodeGenerator {
PcRelativePatchInfo* NewBootImageMethodPatch(MethodReference target_method);
PcRelativePatchInfo* NewMethodBssEntryPatch(MethodReference target_method);
PcRelativePatchInfo* NewBootImageTypePatch(const DexFile& dex_file, dex::TypeIndex type_index);
+ PcRelativePatchInfo* NewAppImageTypePatch(const DexFile& dex_file, dex::TypeIndex type_index);
PcRelativePatchInfo* NewTypeBssEntryPatch(HLoadClass* load_class);
PcRelativePatchInfo* NewBootImageStringPatch(const DexFile& dex_file,
dex::StringIndex string_index);
@@ -1029,6 +1030,8 @@ class CodeGeneratorARMVIXL : public CodeGenerator {
ArenaDeque<PcRelativePatchInfo> method_bss_entry_patches_;
// PC-relative type patch info for kBootImageLinkTimePcRelative.
ArenaDeque<PcRelativePatchInfo> boot_image_type_patches_;
+ // PC-relative type patch info for kAppImageRelRo.
+ ArenaDeque<PcRelativePatchInfo> app_image_type_patches_;
// PC-relative type patch info for kBssEntry.
ArenaDeque<PcRelativePatchInfo> type_bss_entry_patches_;
// PC-relative public type patch info for kBssEntryPublic.
diff --git a/compiler/optimizing/code_generator_riscv64.cc b/compiler/optimizing/code_generator_riscv64.cc
index 29594e94c1..9b499a08a2 100644
--- a/compiler/optimizing/code_generator_riscv64.cc
+++ b/compiler/optimizing/code_generator_riscv64.cc
@@ -4373,6 +4373,18 @@ void InstructionCodeGeneratorRISCV64::VisitLoadClass(HLoadClass* instruction)
codegen_->LoadBootImageRelRoEntry(out, boot_image_offset);
break;
}
+ case HLoadClass::LoadKind::kAppImageRelRo: {
+ DCHECK(codegen_->GetCompilerOptions().IsAppImage());
+ DCHECK_EQ(read_barrier_option, kWithoutReadBarrier);
+ CodeGeneratorRISCV64::PcRelativePatchInfo* info_high =
+ codegen_->NewAppImageTypePatch(instruction->GetDexFile(), instruction->GetTypeIndex());
+ codegen_->EmitPcRelativeAuipcPlaceholder(info_high, out);
+ CodeGeneratorRISCV64::PcRelativePatchInfo* info_low =
+ codegen_->NewAppImageTypePatch(
+ instruction->GetDexFile(), instruction->GetTypeIndex(), info_high);
+ codegen_->EmitPcRelativeLwuPlaceholder(info_low, out, out);
+ break;
+ }
case HLoadClass::LoadKind::kBssEntry:
case HLoadClass::LoadKind::kBssEntryPublic:
case HLoadClass::LoadKind::kBssEntryPackage: {
@@ -5820,6 +5832,7 @@ CodeGeneratorRISCV64::CodeGeneratorRISCV64(HGraph* graph,
boot_image_method_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
method_bss_entry_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
boot_image_type_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
+ app_image_type_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
type_bss_entry_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
public_type_bss_entry_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
package_type_bss_entry_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
@@ -6428,6 +6441,7 @@ HLoadClass::LoadKind CodeGeneratorRISCV64::GetSupportedLoadClassKind(
break;
case HLoadClass::LoadKind::kBootImageLinkTimePcRelative:
case HLoadClass::LoadKind::kBootImageRelRo:
+ case HLoadClass::LoadKind::kAppImageRelRo:
case HLoadClass::LoadKind::kBssEntry:
case HLoadClass::LoadKind::kBssEntryPublic:
case HLoadClass::LoadKind::kBssEntryPackage:
@@ -6479,6 +6493,11 @@ CodeGeneratorRISCV64::PcRelativePatchInfo* CodeGeneratorRISCV64::NewBootImageTyp
return NewPcRelativePatch(&dex_file, type_index.index_, info_high, &boot_image_type_patches_);
}
+CodeGeneratorRISCV64::PcRelativePatchInfo* CodeGeneratorRISCV64::NewAppImageTypePatch(
+ const DexFile& dex_file, dex::TypeIndex type_index, const PcRelativePatchInfo* info_high) {
+ return NewPcRelativePatch(&dex_file, type_index.index_, info_high, &app_image_type_patches_);
+}
+
CodeGeneratorRISCV64::PcRelativePatchInfo* CodeGeneratorRISCV64::NewBootImageJniEntrypointPatch(
MethodReference target_method, const PcRelativePatchInfo* info_high) {
return NewPcRelativePatch(
@@ -6642,6 +6661,7 @@ void CodeGeneratorRISCV64::EmitLinkerPatches(ArenaVector<linker::LinkerPatch>* l
boot_image_method_patches_.size() +
method_bss_entry_patches_.size() +
boot_image_type_patches_.size() +
+ app_image_type_patches_.size() +
type_bss_entry_patches_.size() +
public_type_bss_entry_patches_.size() +
package_type_bss_entry_patches_.size() +
@@ -6662,12 +6682,15 @@ void CodeGeneratorRISCV64::EmitLinkerPatches(ArenaVector<linker::LinkerPatch>* l
DCHECK(boot_image_type_patches_.empty());
DCHECK(boot_image_string_patches_.empty());
}
+ DCHECK_IMPLIES(!GetCompilerOptions().IsAppImage(), app_image_type_patches_.empty());
if (GetCompilerOptions().IsBootImage()) {
EmitPcRelativeLinkerPatches<NoDexFileAdapter<linker::LinkerPatch::IntrinsicReferencePatch>>(
boot_image_other_patches_, linker_patches);
} else {
EmitPcRelativeLinkerPatches<NoDexFileAdapter<linker::LinkerPatch::BootImageRelRoPatch>>(
boot_image_other_patches_, linker_patches);
+ EmitPcRelativeLinkerPatches<linker::LinkerPatch::TypeAppImageRelRoPatch>(
+ app_image_type_patches_, linker_patches);
}
EmitPcRelativeLinkerPatches<linker::LinkerPatch::MethodBssEntryPatch>(
method_bss_entry_patches_, linker_patches);
diff --git a/compiler/optimizing/code_generator_riscv64.h b/compiler/optimizing/code_generator_riscv64.h
index 7f4f352341..227882e7b8 100644
--- a/compiler/optimizing/code_generator_riscv64.h
+++ b/compiler/optimizing/code_generator_riscv64.h
@@ -589,6 +589,9 @@ class CodeGeneratorRISCV64 : public CodeGenerator {
PcRelativePatchInfo* NewBootImageTypePatch(const DexFile& dex_file,
dex::TypeIndex type_index,
const PcRelativePatchInfo* info_high = nullptr);
+ PcRelativePatchInfo* NewAppImageTypePatch(const DexFile& dex_file,
+ dex::TypeIndex type_index,
+ const PcRelativePatchInfo* info_high = nullptr);
PcRelativePatchInfo* NewTypeBssEntryPatch(HLoadClass* load_class,
const PcRelativePatchInfo* info_high = nullptr);
PcRelativePatchInfo* NewBootImageStringPatch(const DexFile& dex_file,
@@ -819,6 +822,8 @@ class CodeGeneratorRISCV64 : public CodeGenerator {
ArenaDeque<PcRelativePatchInfo> method_bss_entry_patches_;
// PC-relative type patch info for kBootImageLinkTimePcRelative.
ArenaDeque<PcRelativePatchInfo> boot_image_type_patches_;
+ // PC-relative type patch info for kAppImageRelRo.
+ ArenaDeque<PcRelativePatchInfo> app_image_type_patches_;
// PC-relative type patch info for kBssEntry.
ArenaDeque<PcRelativePatchInfo> type_bss_entry_patches_;
// PC-relative public type patch info for kBssEntryPublic.
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index 5ad818dd53..4329e40efc 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -1173,6 +1173,7 @@ CodeGeneratorX86::CodeGeneratorX86(HGraph* graph,
boot_image_method_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
method_bss_entry_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
boot_image_type_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
+ app_image_type_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
type_bss_entry_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
public_type_bss_entry_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
package_type_bss_entry_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
@@ -5715,6 +5716,14 @@ void CodeGeneratorX86::RecordBootImageTypePatch(HLoadClass* load_class) {
__ Bind(&boot_image_type_patches_.back().label);
}
+void CodeGeneratorX86::RecordAppImageTypePatch(HLoadClass* load_class) {
+ HX86ComputeBaseMethodAddress* method_address =
+ load_class->InputAt(0)->AsX86ComputeBaseMethodAddress();
+ app_image_type_patches_.emplace_back(
+ method_address, &load_class->GetDexFile(), load_class->GetTypeIndex().index_);
+ __ Bind(&app_image_type_patches_.back().label);
+}
+
Label* CodeGeneratorX86::NewTypeBssEntryPatch(HLoadClass* load_class) {
HX86ComputeBaseMethodAddress* method_address =
load_class->InputAt(0)->AsX86ComputeBaseMethodAddress();
@@ -5844,6 +5853,7 @@ void CodeGeneratorX86::EmitLinkerPatches(ArenaVector<linker::LinkerPatch>* linke
boot_image_method_patches_.size() +
method_bss_entry_patches_.size() +
boot_image_type_patches_.size() +
+ app_image_type_patches_.size() +
type_bss_entry_patches_.size() +
public_type_bss_entry_patches_.size() +
package_type_bss_entry_patches_.size() +
@@ -5864,12 +5874,15 @@ void CodeGeneratorX86::EmitLinkerPatches(ArenaVector<linker::LinkerPatch>* linke
DCHECK(boot_image_type_patches_.empty());
DCHECK(boot_image_string_patches_.empty());
}
+ DCHECK_IMPLIES(!GetCompilerOptions().IsAppImage(), app_image_type_patches_.empty());
if (GetCompilerOptions().IsBootImage()) {
EmitPcRelativeLinkerPatches<NoDexFileAdapter<linker::LinkerPatch::IntrinsicReferencePatch>>(
boot_image_other_patches_, linker_patches);
} else {
EmitPcRelativeLinkerPatches<NoDexFileAdapter<linker::LinkerPatch::BootImageRelRoPatch>>(
boot_image_other_patches_, linker_patches);
+ EmitPcRelativeLinkerPatches<linker::LinkerPatch::TypeAppImageRelRoPatch>(
+ app_image_type_patches_, linker_patches);
}
EmitPcRelativeLinkerPatches<linker::LinkerPatch::MethodBssEntryPatch>(
method_bss_entry_patches_, linker_patches);
@@ -7283,6 +7296,7 @@ HLoadClass::LoadKind CodeGeneratorX86::GetSupportedLoadClassKind(
break;
case HLoadClass::LoadKind::kBootImageLinkTimePcRelative:
case HLoadClass::LoadKind::kBootImageRelRo:
+ case HLoadClass::LoadKind::kAppImageRelRo:
case HLoadClass::LoadKind::kBssEntry:
case HLoadClass::LoadKind::kBssEntryPublic:
case HLoadClass::LoadKind::kBssEntryPackage:
@@ -7396,6 +7410,14 @@ void InstructionCodeGeneratorX86::VisitLoadClass(HLoadClass* cls) NO_THREAD_SAFE
CodeGenerator::GetBootImageOffset(cls));
break;
}
+ case HLoadClass::LoadKind::kAppImageRelRo: {
+ DCHECK(codegen_->GetCompilerOptions().IsAppImage());
+ DCHECK_EQ(read_barrier_option, kWithoutReadBarrier);
+ Register method_address = locations->InAt(0).AsRegister<Register>();
+ __ movl(out, Address(method_address, CodeGeneratorX86::kPlaceholder32BitOffset));
+ codegen_->RecordAppImageTypePatch(cls);
+ break;
+ }
case HLoadClass::LoadKind::kBssEntry:
case HLoadClass::LoadKind::kBssEntryPublic:
case HLoadClass::LoadKind::kBssEntryPackage: {
diff --git a/compiler/optimizing/code_generator_x86.h b/compiler/optimizing/code_generator_x86.h
index ee87947ca0..93f8e6ed9b 100644
--- a/compiler/optimizing/code_generator_x86.h
+++ b/compiler/optimizing/code_generator_x86.h
@@ -539,6 +539,7 @@ class CodeGeneratorX86 : public CodeGenerator {
void RecordBootImageMethodPatch(HInvoke* invoke);
void RecordMethodBssEntryPatch(HInvoke* invoke);
void RecordBootImageTypePatch(HLoadClass* load_class);
+ void RecordAppImageTypePatch(HLoadClass* load_class);
Label* NewTypeBssEntryPatch(HLoadClass* load_class);
void RecordBootImageStringPatch(HLoadString* load_string);
Label* NewStringBssEntryPatch(HLoadString* load_string);
@@ -775,6 +776,8 @@ class CodeGeneratorX86 : public CodeGenerator {
ArenaDeque<X86PcRelativePatchInfo> method_bss_entry_patches_;
// PC-relative type patch info for kBootImageLinkTimePcRelative.
ArenaDeque<X86PcRelativePatchInfo> boot_image_type_patches_;
+ // PC-relative type patch info for kAppImageRelRo.
+ ArenaDeque<X86PcRelativePatchInfo> app_image_type_patches_;
// PC-relative type patch info for kBssEntry.
ArenaDeque<X86PcRelativePatchInfo> type_bss_entry_patches_;
// PC-relative public type patch info for kBssEntryPublic.
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index 4855b086ae..5b4f1b8b25 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -1328,6 +1328,12 @@ void CodeGeneratorX86_64::RecordBootImageTypePatch(const DexFile& dex_file,
__ Bind(&boot_image_type_patches_.back().label);
}
+void CodeGeneratorX86_64::RecordAppImageTypePatch(const DexFile& dex_file,
+ dex::TypeIndex type_index) {
+ app_image_type_patches_.emplace_back(&dex_file, type_index.index_);
+ __ Bind(&app_image_type_patches_.back().label);
+}
+
Label* CodeGeneratorX86_64::NewTypeBssEntryPatch(HLoadClass* load_class) {
ArenaDeque<PatchInfo<Label>>* patches = nullptr;
switch (load_class->GetLoadKind()) {
@@ -1448,6 +1454,7 @@ void CodeGeneratorX86_64::EmitLinkerPatches(ArenaVector<linker::LinkerPatch>* li
boot_image_method_patches_.size() +
method_bss_entry_patches_.size() +
boot_image_type_patches_.size() +
+ app_image_type_patches_.size() +
type_bss_entry_patches_.size() +
public_type_bss_entry_patches_.size() +
package_type_bss_entry_patches_.size() +
@@ -1469,12 +1476,15 @@ void CodeGeneratorX86_64::EmitLinkerPatches(ArenaVector<linker::LinkerPatch>* li
DCHECK(boot_image_type_patches_.empty());
DCHECK(boot_image_string_patches_.empty());
}
+ DCHECK_IMPLIES(!GetCompilerOptions().IsAppImage(), app_image_type_patches_.empty());
if (GetCompilerOptions().IsBootImage()) {
EmitPcRelativeLinkerPatches<NoDexFileAdapter<linker::LinkerPatch::IntrinsicReferencePatch>>(
boot_image_other_patches_, linker_patches);
} else {
EmitPcRelativeLinkerPatches<NoDexFileAdapter<linker::LinkerPatch::BootImageRelRoPatch>>(
boot_image_other_patches_, linker_patches);
+ EmitPcRelativeLinkerPatches<linker::LinkerPatch::TypeAppImageRelRoPatch>(
+ app_image_type_patches_, linker_patches);
}
EmitPcRelativeLinkerPatches<linker::LinkerPatch::MethodBssEntryPatch>(
method_bss_entry_patches_, linker_patches);
@@ -1607,6 +1617,7 @@ CodeGeneratorX86_64::CodeGeneratorX86_64(HGraph* graph,
boot_image_method_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
method_bss_entry_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
boot_image_type_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
+ app_image_type_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
type_bss_entry_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
public_type_bss_entry_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
package_type_bss_entry_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
@@ -6620,6 +6631,7 @@ HLoadClass::LoadKind CodeGeneratorX86_64::GetSupportedLoadClassKind(
break;
case HLoadClass::LoadKind::kBootImageLinkTimePcRelative:
case HLoadClass::LoadKind::kBootImageRelRo:
+ case HLoadClass::LoadKind::kAppImageRelRo:
case HLoadClass::LoadKind::kBssEntry:
case HLoadClass::LoadKind::kBssEntryPublic:
case HLoadClass::LoadKind::kBssEntryPackage:
@@ -6732,6 +6744,14 @@ void InstructionCodeGeneratorX86_64::VisitLoadClass(HLoadClass* cls) NO_THREAD_S
codegen_->RecordBootImageRelRoPatch(CodeGenerator::GetBootImageOffset(cls));
break;
}
+ case HLoadClass::LoadKind::kAppImageRelRo: {
+ DCHECK(codegen_->GetCompilerOptions().IsAppImage());
+ DCHECK_EQ(read_barrier_option, kWithoutReadBarrier);
+ __ movl(out,
+ Address::Absolute(CodeGeneratorX86_64::kPlaceholder32BitOffset, /* no_rip= */ false));
+ codegen_->RecordAppImageTypePatch(cls->GetDexFile(), cls->GetTypeIndex());
+ break;
+ }
case HLoadClass::LoadKind::kBssEntry:
case HLoadClass::LoadKind::kBssEntryPublic:
case HLoadClass::LoadKind::kBssEntryPackage: {
diff --git a/compiler/optimizing/code_generator_x86_64.h b/compiler/optimizing/code_generator_x86_64.h
index b8e2456381..7a5e4aa894 100644
--- a/compiler/optimizing/code_generator_x86_64.h
+++ b/compiler/optimizing/code_generator_x86_64.h
@@ -532,6 +532,7 @@ class CodeGeneratorX86_64 : public CodeGenerator {
void RecordBootImageMethodPatch(HInvoke* invoke);
void RecordMethodBssEntryPatch(HInvoke* invoke);
void RecordBootImageTypePatch(const DexFile& dex_file, dex::TypeIndex type_index);
+ void RecordAppImageTypePatch(const DexFile& dex_file, dex::TypeIndex type_index);
Label* NewTypeBssEntryPatch(HLoadClass* load_class);
void RecordBootImageStringPatch(HLoadString* load_string);
Label* NewStringBssEntryPatch(HLoadString* load_string);
@@ -738,6 +739,8 @@ class CodeGeneratorX86_64 : public CodeGenerator {
ArenaDeque<PatchInfo<Label>> method_bss_entry_patches_;
// PC-relative type patch info for kBootImageLinkTimePcRelative.
ArenaDeque<PatchInfo<Label>> boot_image_type_patches_;
+ // PC-relative type patch info for kAppImageRelRo.
+ ArenaDeque<PatchInfo<Label>> app_image_type_patches_;
// PC-relative type patch info for kBssEntry.
ArenaDeque<PatchInfo<Label>> type_bss_entry_patches_;
// PC-relative public type patch info for kBssEntryPublic.
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 90fc5db02e..33ffc07ba8 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -6743,6 +6743,10 @@ class HLoadClass final : public HInstruction {
// Used for boot image classes referenced by apps in AOT-compiled code.
kBootImageRelRo,
+ // Load from an app image entry in the .data.img.rel.ro using a PC-relative load.
+ // Used for app image classes referenced by apps in AOT-compiled code.
+ kAppImageRelRo,
+
// Load from an entry in the .bss section using a PC-relative load.
// Used for classes outside boot image referenced by AOT-compiled app and boot image code.
kBssEntry,
@@ -6814,6 +6818,7 @@ class HLoadClass final : public HInstruction {
bool HasPcRelativeLoadKind() const {
return GetLoadKind() == LoadKind::kBootImageLinkTimePcRelative ||
GetLoadKind() == LoadKind::kBootImageRelRo ||
+ GetLoadKind() == LoadKind::kAppImageRelRo ||
GetLoadKind() == LoadKind::kBssEntry ||
GetLoadKind() == LoadKind::kBssEntryPublic ||
GetLoadKind() == LoadKind::kBssEntryPackage;
@@ -6933,6 +6938,7 @@ class HLoadClass final : public HInstruction {
static bool HasTypeReference(LoadKind load_kind) {
return load_kind == LoadKind::kReferrersClass ||
load_kind == LoadKind::kBootImageLinkTimePcRelative ||
+ load_kind == LoadKind::kAppImageRelRo ||
load_kind == LoadKind::kBssEntry ||
load_kind == LoadKind::kBssEntryPublic ||
load_kind == LoadKind::kBssEntryPackage ||
@@ -6978,6 +6984,7 @@ inline void HLoadClass::AddSpecialInput(HInstruction* special_input) {
// including literal pool loads, which are PC-relative too.
DCHECK(GetLoadKind() == LoadKind::kBootImageLinkTimePcRelative ||
GetLoadKind() == LoadKind::kBootImageRelRo ||
+ GetLoadKind() == LoadKind::kAppImageRelRo ||
GetLoadKind() == LoadKind::kBssEntry ||
GetLoadKind() == LoadKind::kBssEntryPublic ||
GetLoadKind() == LoadKind::kBssEntryPackage ||
diff --git a/compiler/optimizing/sharpening.cc b/compiler/optimizing/sharpening.cc
index aa75c2464b..cb94491b8e 100644
--- a/compiler/optimizing/sharpening.cc
+++ b/compiler/optimizing/sharpening.cc
@@ -277,7 +277,7 @@ HLoadClass::LoadKind HSharpening::ComputeLoadClassKind(
} else if (compiler_options.IsAppImage() && is_class_in_current_image()) {
// AOT app compilation, app image class.
is_in_image = true;
- desired_load_kind = HLoadClass::LoadKind::kBssEntry;
+ desired_load_kind = HLoadClass::LoadKind::kAppImageRelRo;
} else {
// Not JIT and the klass is not in boot image or app image.
desired_load_kind = HLoadClass::LoadKind::kBssEntry;