summaryrefslogtreecommitdiff
path: root/compiler/optimizing
diff options
context:
space:
mode:
author Almaz Mingaleev <mingaleev@google.com> 2023-12-15 15:47:22 +0000
committer Treehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com> 2024-01-03 15:29:48 +0000
commit3f0981b56a1b9a415383c552c063b890c840b13e (patch)
tree4f5aae6900d024630a90401761905b5ce4847f08 /compiler/optimizing
parent41c5dde40d1c75d36a7f984c8d72ec65fbff3111 (diff)
Revert^2 "x86_64: Store resolved MethodType-s in .bss."
This reverts commit d014fd019e84471665ac02f2de285541009892cd. Reason for revert: fix codegen to do runtime call in JIT for now. Bug: 297147201 Test: ./art/test/testrunner/testrunner.py --host --64 --optimizing -b Test: ./art/test/testrunner/testrunner.py --jvm -b Test: ./art/test.py --host -b Test: ./art/test/testrunner/testrunner.py --host --64 --jit -b Change-Id: I0f01c8391b09659bb6195955ecd8f88159141872
Diffstat (limited to 'compiler/optimizing')
-rw-r--r--compiler/optimizing/code_generator.cc1
-rw-r--r--compiler/optimizing/code_generator_x86_64.cc88
-rw-r--r--compiler/optimizing/code_generator_x86_64.h3
-rw-r--r--compiler/optimizing/instruction_builder.cc3
-rw-r--r--compiler/optimizing/nodes.h36
5 files changed, 127 insertions, 4 deletions
diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc
index 34400c9d22..b0e07e32ea 100644
--- a/compiler/optimizing/code_generator.cc
+++ b/compiler/optimizing/code_generator.cc
@@ -1682,6 +1682,7 @@ void CodeGenerator::ValidateInvokeRuntimeWithoutRecordingPcInfo(HInstruction* in
instruction->IsArrayGet() ||
instruction->IsArraySet() ||
instruction->IsLoadClass() ||
+ instruction->IsLoadMethodType() ||
instruction->IsLoadString() ||
instruction->IsInstanceOf() ||
instruction->IsCheckCast() ||
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index d43d3dd95f..69fde66b2a 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -270,6 +270,38 @@ class BoundsCheckSlowPathX86_64 : public SlowPathCode {
DISALLOW_COPY_AND_ASSIGN(BoundsCheckSlowPathX86_64);
};
+class LoadMethodTypeSlowPathX86_64: public SlowPathCode {
+ public:
+ explicit LoadMethodTypeSlowPathX86_64(HLoadMethodType* mt) : SlowPathCode(mt) {}
+
+ void EmitNativeCode(CodeGenerator* codegen) override {
+ LocationSummary* locations = instruction_->GetLocations();
+ DCHECK(!locations->GetLiveRegisters()->ContainsCoreRegister(locations->Out().reg()));
+
+ CodeGeneratorX86_64* x86_64_codegen = down_cast<CodeGeneratorX86_64*>(codegen);
+ __ Bind(GetEntryLabel());
+ SaveLiveRegisters(codegen, locations);
+
+ const dex::ProtoIndex proto_index = instruction_->AsLoadMethodType()->GetProtoIndex();
+ // Custom calling convention: RAX serves as both input and output.
+ __ movl(CpuRegister(RAX), Immediate(proto_index.index_));
+ x86_64_codegen->InvokeRuntime(kQuickResolveMethodType,
+ instruction_,
+ instruction_->GetDexPc(),
+ this);
+ CheckEntrypointTypes<kQuickResolveMethodType, void*, uint32_t>();
+ x86_64_codegen->Move(locations->Out(), Location::RegisterLocation(RAX));
+ RestoreLiveRegisters(codegen, locations);
+
+ __ jmp(GetExitLabel());
+ }
+
+ const char* GetDescription() const override { return "LoadMethodTypeSlowPathX86_64"; }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(LoadMethodTypeSlowPathX86_64);
+};
+
class LoadClassSlowPathX86_64 : public SlowPathCode {
public:
LoadClassSlowPathX86_64(HLoadClass* cls, HInstruction* at)
@@ -529,6 +561,7 @@ class ReadBarrierMarkSlowPathX86_64 : public SlowPathCode {
instruction_->IsArrayGet() ||
instruction_->IsArraySet() ||
instruction_->IsLoadClass() ||
+ instruction_->IsLoadMethodType() ||
instruction_->IsLoadString() ||
instruction_->IsInstanceOf() ||
instruction_->IsCheckCast() ||
@@ -1319,6 +1352,12 @@ Label* CodeGeneratorX86_64::NewStringBssEntryPatch(HLoadString* load_string) {
return &string_bss_entry_patches_.back().label;
}
+Label* CodeGeneratorX86_64::NewMethodTypeBssEntryPatch(HLoadMethodType* load_method_type) {
+ method_type_bss_entry_patches_.emplace_back(
+ &load_method_type->GetDexFile(), load_method_type->GetProtoIndex().index_);
+ return &method_type_bss_entry_patches_.back().label;
+}
+
void CodeGeneratorX86_64::RecordBootImageJniEntrypointPatch(HInvokeStaticOrDirect* invoke) {
boot_image_jni_entrypoint_patches_.emplace_back(invoke->GetResolvedMethodReference().dex_file,
invoke->GetResolvedMethodReference().index);
@@ -1406,6 +1445,7 @@ void CodeGeneratorX86_64::EmitLinkerPatches(ArenaVector<linker::LinkerPatch>* li
package_type_bss_entry_patches_.size() +
boot_image_string_patches_.size() +
string_bss_entry_patches_.size() +
+ method_type_bss_entry_patches_.size() +
boot_image_jni_entrypoint_patches_.size() +
boot_image_other_patches_.size();
linker_patches->reserve(size);
@@ -1438,6 +1478,8 @@ void CodeGeneratorX86_64::EmitLinkerPatches(ArenaVector<linker::LinkerPatch>* li
package_type_bss_entry_patches_, linker_patches);
EmitPcRelativeLinkerPatches<linker::LinkerPatch::StringBssEntryPatch>(
string_bss_entry_patches_, linker_patches);
+ EmitPcRelativeLinkerPatches<linker::LinkerPatch::MethodTypeBssEntryPatch>(
+ method_type_bss_entry_patches_, linker_patches);
EmitPcRelativeLinkerPatches<linker::LinkerPatch::RelativeJniEntrypointPatch>(
boot_image_jni_entrypoint_patches_, linker_patches);
DCHECK_EQ(size, linker_patches->size());
@@ -1562,6 +1604,7 @@ CodeGeneratorX86_64::CodeGeneratorX86_64(HGraph* graph,
package_type_bss_entry_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
boot_image_string_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
string_bss_entry_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
+ method_type_bss_entry_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
boot_image_jni_entrypoint_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
boot_image_other_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
jit_string_patches_(graph->GetAllocator()->Adapter(kArenaAllocCodeGenerator)),
@@ -6673,13 +6716,50 @@ void InstructionCodeGeneratorX86_64::VisitLoadMethodHandle(HLoadMethodHandle* lo
}
void LocationsBuilderX86_64::VisitLoadMethodType(HLoadMethodType* load) {
- // Custom calling convention: RAX serves as both input and output.
- Location location = Location::RegisterLocation(RAX);
- CodeGenerator::CreateLoadMethodTypeRuntimeCallLocationSummary(load, location, location);
+ LocationSummary* locations =
+ new (GetGraph()->GetAllocator()) LocationSummary(load, LocationSummary::kCallOnSlowPath);
+ if (load->GetLoadKind() == HLoadMethodType::LoadKind::kRuntimeCall) {
+ Location location = Location::RegisterLocation(RAX);
+ CodeGenerator::CreateLoadMethodTypeRuntimeCallLocationSummary(load, location, location);
+ } else {
+ DCHECK_EQ(load->GetLoadKind(), HLoadMethodType::LoadKind::kBssEntry);
+ locations->SetOut(Location::RequiresRegister());
+ if (codegen_->EmitNonBakerReadBarrier()) {
+ // For non-Baker read barrier we have a temp-clobbering call.
+ } else {
+ // Rely on the pResolveMethodType to save everything.
+ locations->SetCustomSlowPathCallerSaves(OneRegInReferenceOutSaveEverythingCallerSaves());
+ }
+ }
}
void InstructionCodeGeneratorX86_64::VisitLoadMethodType(HLoadMethodType* load) {
- codegen_->GenerateLoadMethodTypeRuntimeCall(load);
+ LocationSummary* locations = load->GetLocations();
+ Location out_loc = locations->Out();
+ CpuRegister out = out_loc.AsRegister<CpuRegister>();
+
+ switch (load->GetLoadKind()) {
+ case HLoadMethodType::LoadKind::kBssEntry: {
+ Address address = Address::Absolute(CodeGeneratorX86_64::kPlaceholder32BitOffset,
+ /* no_rip= */ false);
+ Label* fixup_label = codegen_->NewMethodTypeBssEntryPatch(load);
+ // /* GcRoot<mirror::MethodType> */ out = *address /* PC-relative */
+ GenerateGcRootFieldLoad(
+ load, out_loc, address, fixup_label, codegen_->GetCompilerReadBarrierOption());
+ // No need for memory fence, thanks to the x86-64 memory model.
+ SlowPathCode* slow_path =
+ new (codegen_->GetScopedAllocator()) LoadMethodTypeSlowPathX86_64(load);
+ codegen_->AddSlowPath(slow_path);
+ __ testl(out, out);
+ __ j(kEqual, slow_path->GetEntryLabel());
+ __ Bind(slow_path->GetExitLabel());
+ return;
+ }
+ default:
+ DCHECK_EQ(load->GetLoadKind(), HLoadMethodType::LoadKind::kRuntimeCall);
+ codegen_->GenerateLoadMethodTypeRuntimeCall(load);
+ break;
+ }
}
void InstructionCodeGeneratorX86_64::VisitClinitCheck(HClinitCheck* check) {
diff --git a/compiler/optimizing/code_generator_x86_64.h b/compiler/optimizing/code_generator_x86_64.h
index 7da2e39583..e4d3eac6bc 100644
--- a/compiler/optimizing/code_generator_x86_64.h
+++ b/compiler/optimizing/code_generator_x86_64.h
@@ -523,6 +523,7 @@ class CodeGeneratorX86_64 : public CodeGenerator {
Label* NewTypeBssEntryPatch(HLoadClass* load_class);
void RecordBootImageStringPatch(HLoadString* load_string);
Label* NewStringBssEntryPatch(HLoadString* load_string);
+ Label* NewMethodTypeBssEntryPatch(HLoadMethodType* load_method_type);
void RecordBootImageJniEntrypointPatch(HInvokeStaticOrDirect* invoke);
Label* NewJitRootStringPatch(const DexFile& dex_file,
dex::StringIndex string_index,
@@ -735,6 +736,8 @@ class CodeGeneratorX86_64 : public CodeGenerator {
ArenaDeque<PatchInfo<Label>> boot_image_string_patches_;
// PC-relative String patch info for kBssEntry.
ArenaDeque<PatchInfo<Label>> string_bss_entry_patches_;
+ // PC-relative MethodType patch info for kBssEntry.
+ ArenaDeque<PatchInfo<Label>> method_type_bss_entry_patches_;
// PC-relative method patch info for kBootImageLinkTimePcRelative+kCallCriticalNative.
ArenaDeque<PatchInfo<Label>> boot_image_jni_entrypoint_patches_;
// PC-relative patch info for IntrinsicObjects for the boot image,
diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc
index 281da6f9ec..fe0f3fe319 100644
--- a/compiler/optimizing/instruction_builder.cc
+++ b/compiler/optimizing/instruction_builder.cc
@@ -2699,6 +2699,9 @@ void HInstructionBuilder::BuildLoadMethodType(dex::ProtoIndex proto_index, uint3
const DexFile& dex_file = *dex_compilation_unit_->GetDexFile();
HLoadMethodType* load_method_type =
new (allocator_) HLoadMethodType(graph_->GetCurrentMethod(), proto_index, dex_file, dex_pc);
+ if (!code_generator_->GetCompilerOptions().IsJitCompiler()) {
+ load_method_type->SetLoadKind(HLoadMethodType::LoadKind::kBssEntry);
+ }
AppendInstruction(load_method_type);
}
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index d84ff7be73..0efe8f4335 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -7313,6 +7313,16 @@ class HLoadMethodHandle final : public HInstruction {
class HLoadMethodType final : public HInstruction {
public:
+ // Determines how to load the MethodType.
+ enum class LoadKind {
+ // Load from an entry in the .bss section using a PC-relative load.
+ kBssEntry,
+ // Load using a single runtime call.
+ kRuntimeCall,
+
+ kLast = kRuntimeCall,
+ };
+
HLoadMethodType(HCurrentMethod* current_method,
dex::ProtoIndex proto_index,
const DexFile& dex_file,
@@ -7324,6 +7334,7 @@ class HLoadMethodType final : public HInstruction {
special_input_(HUserRecord<HInstruction*>(current_method)),
proto_index_(proto_index),
dex_file_(dex_file) {
+ SetPackedField<LoadKindField>(LoadKind::kRuntimeCall);
}
using HInstruction::GetInputRecords; // Keep the const version visible.
@@ -7334,6 +7345,12 @@ class HLoadMethodType final : public HInstruction {
bool IsClonable() const override { return true; }
+ void SetLoadKind(LoadKind load_kind);
+
+ LoadKind GetLoadKind() const {
+ return GetPackedField<LoadKindField>();
+ }
+
dex::ProtoIndex GetProtoIndex() const { return proto_index_; }
const DexFile& GetDexFile() const { return dex_file_; }
@@ -7352,6 +7369,14 @@ class HLoadMethodType final : public HInstruction {
DEFAULT_COPY_CONSTRUCTOR(LoadMethodType);
private:
+ static constexpr size_t kFieldLoadKind = kNumberOfGenericPackedBits;
+ static constexpr size_t kFieldLoadKindSize =
+ MinimumBitsToStore(static_cast<size_t>(LoadKind::kLast));
+ static constexpr size_t kNumberOfLoadMethodTypePackedBits = kFieldLoadKind + kFieldLoadKindSize;
+ static_assert(kNumberOfLoadMethodTypePackedBits <= kMaxNumberOfPackedBits,
+ "Too many packed fields.");
+ using LoadKindField = BitField<LoadKind, kFieldLoadKind, kFieldLoadKindSize>;
+
// The special input is the HCurrentMethod for kRuntimeCall.
HUserRecord<HInstruction*> special_input_;
@@ -7359,6 +7384,17 @@ class HLoadMethodType final : public HInstruction {
const DexFile& dex_file_;
};
+std::ostream& operator<<(std::ostream& os, HLoadMethodType::LoadKind rhs);
+
+// Note: defined outside class to see operator<<(., HLoadMethodType::LoadKind).
+inline void HLoadMethodType::SetLoadKind(LoadKind load_kind) {
+ // The load kind should be determined before inserting the instruction to the graph.
+ DCHECK(GetBlock() == nullptr);
+ DCHECK(GetEnvironment() == nullptr);
+ DCHECK_EQ(GetLoadKind(), LoadKind::kRuntimeCall);
+ SetPackedField<LoadKindField>(load_kind);
+}
+
/**
* Performs an initialization check on its Class object input.
*/