diff options
author | 2020-10-27 13:41:40 +0000 | |
---|---|---|
committer | 2020-10-29 15:42:52 +0000 | |
commit | de91ca90389e4b41ed27b320a6c43ff56a6d75ff (patch) | |
tree | 2e18ff33d30fce88d578ea68b8b1037755aececc /compiler/optimizing | |
parent | 9ca92fb4646eccff9f972f6a2a21709676b65460 (diff) |
Refactor Integer.valueOf() intrinsic implementation.
Prepare for Reference.getReferent() intrinsic implementation
by a refactoring to separate the retrieval of an intrinsic
method's declaring class to its own helper function, rather
than being a part of a larger one.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing --jit
Test: aosp_blueline-userdebug boots.
Test: run-gtests.sh
Test: testrunner.py --target --optimizing --jit
Bug: 170286013
Change-Id: Ib6c0e55d0c6fcc932999428f21c51afe32ab7ef2
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/code_generator.cc | 15 | ||||
-rw-r--r-- | compiler/optimizing/code_generator.h | 9 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm64.cc | 21 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm64.h | 2 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm_vixl.cc | 19 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm_vixl.h | 2 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 19 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86.h | 2 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86_64.cc | 19 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86_64.h | 2 | ||||
-rw-r--r-- | compiler/optimizing/intrinsics.cc | 32 | ||||
-rw-r--r-- | compiler/optimizing/intrinsics.h | 3 | ||||
-rw-r--r-- | compiler/optimizing/intrinsics_arm64.cc | 18 | ||||
-rw-r--r-- | compiler/optimizing/intrinsics_arm_vixl.cc | 18 | ||||
-rw-r--r-- | compiler/optimizing/intrinsics_x86.cc | 13 | ||||
-rw-r--r-- | compiler/optimizing/intrinsics_x86_64.cc | 11 |
16 files changed, 100 insertions, 105 deletions
diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc index c2ae0e0632..23ac91b024 100644 --- a/compiler/optimizing/code_generator.cc +++ b/compiler/optimizing/code_generator.cc @@ -891,7 +891,6 @@ void CodeGenerator::GenerateLoadMethodTypeRuntimeCall(HLoadMethodType* method_ty static uint32_t GetBootImageOffsetImpl(const void* object, ImageHeader::ImageSections section) { Runtime* runtime = Runtime::Current(); - DCHECK(runtime->IsAotCompiler()); const std::vector<gc::space::ImageSpace*>& boot_image_spaces = runtime->GetHeap()->GetBootImageSpaces(); // Check that the `object` is in the expected section of one of the boot image files. @@ -907,6 +906,10 @@ static uint32_t GetBootImageOffsetImpl(const void* object, ImageHeader::ImageSec return dchecked_integral_cast<uint32_t>(offset); } +uint32_t CodeGenerator::GetBootImageOffset(ObjPtr<mirror::Object> object) { + return GetBootImageOffsetImpl(object.Ptr(), ImageHeader::kSectionObjects); +} + // NO_THREAD_SAFETY_ANALYSIS: Avoid taking the mutator lock, boot image classes are non-moveable. uint32_t CodeGenerator::GetBootImageOffset(HLoadClass* load_class) NO_THREAD_SAFETY_ANALYSIS { DCHECK_EQ(load_class->GetLoadKind(), HLoadClass::LoadKind::kBootImageRelRo); @@ -929,6 +932,16 @@ uint32_t CodeGenerator::GetBootImageOffset(HInvoke* invoke) { return GetBootImageOffsetImpl(method, ImageHeader::kSectionArtMethods); } +// NO_THREAD_SAFETY_ANALYSIS: Avoid taking the mutator lock, boot image classes are non-moveable. +uint32_t CodeGenerator::GetBootImageOffsetOfIntrinsicDeclaringClass(HInvoke* invoke) + NO_THREAD_SAFETY_ANALYSIS { + DCHECK_NE(invoke->GetIntrinsic(), Intrinsics::kNone); + ArtMethod* method = invoke->GetResolvedMethod(); + DCHECK(method != nullptr); + ObjPtr<mirror::Class> declaring_class = method->GetDeclaringClass<kWithoutReadBarrier>(); + return GetBootImageOffsetImpl(declaring_class.Ptr(), ImageHeader::kSectionObjects); +} + void CodeGenerator::BlockIfInRegister(Location location, bool is_out) const { // The DCHECKS below check that a register is not specified twice in // the summary. The out location can overlap with an input, so we need diff --git a/compiler/optimizing/code_generator.h b/compiler/optimizing/code_generator.h index 22804a992f..bd5483cc09 100644 --- a/compiler/optimizing/code_generator.h +++ b/compiler/optimizing/code_generator.h @@ -630,9 +630,12 @@ class CodeGenerator : public DeletableArenaObject<kArenaAllocCodeGenerator> { Location runtime_return_location); void GenerateLoadMethodTypeRuntimeCall(HLoadMethodType* method_type); - uint32_t GetBootImageOffset(HLoadClass* load_class); - uint32_t GetBootImageOffset(HLoadString* load_string); - uint32_t GetBootImageOffset(HInvoke* invoke); + static uint32_t GetBootImageOffset(ObjPtr<mirror::Object> object) + REQUIRES_SHARED(Locks::mutator_lock_); + static uint32_t GetBootImageOffset(HLoadClass* load_class); + static uint32_t GetBootImageOffset(HLoadString* load_string); + static uint32_t GetBootImageOffset(HInvoke* invoke); + static uint32_t GetBootImageOffsetOfIntrinsicDeclaringClass(HInvoke* invoke); static void CreateSystemArrayCopyLocationSummary(HInvoke* invoke); diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc index 5920a48586..2c7cf851b7 100644 --- a/compiler/optimizing/code_generator_arm64.cc +++ b/compiler/optimizing/code_generator_arm64.cc @@ -4956,28 +4956,23 @@ void CodeGeneratorARM64::LoadBootImageAddress(vixl::aarch64::Register reg, } } -void CodeGeneratorARM64::AllocateInstanceForIntrinsic(HInvokeStaticOrDirect* invoke, - uint32_t boot_image_offset) { - DCHECK(invoke->IsStatic()); - InvokeRuntimeCallingConvention calling_convention; - Register argument = calling_convention.GetRegisterAt(0); +void CodeGeneratorARM64::LoadIntrinsicDeclaringClass(vixl::aarch64::Register reg, HInvoke* invoke) { + DCHECK_NE(invoke->GetIntrinsic(), Intrinsics::kNone); if (GetCompilerOptions().IsBootImage()) { - DCHECK_EQ(boot_image_offset, IntrinsicVisitor::IntegerValueOfInfo::kInvalidReference); // Load the class the same way as for HLoadClass::LoadKind::kBootImageLinkTimePcRelative. MethodReference target_method = invoke->GetResolvedMethodReference(); dex::TypeIndex type_idx = target_method.dex_file->GetMethodId(target_method.index).class_idx_; // Add ADRP with its PC-relative type patch. vixl::aarch64::Label* adrp_label = NewBootImageTypePatch(*target_method.dex_file, type_idx); - EmitAdrpPlaceholder(adrp_label, argument.X()); + EmitAdrpPlaceholder(adrp_label, reg.X()); // Add ADD with its PC-relative type patch. vixl::aarch64::Label* add_label = NewBootImageTypePatch(*target_method.dex_file, type_idx, adrp_label); - EmitAddPlaceholder(add_label, argument.X(), argument.X()); + EmitAddPlaceholder(add_label, reg.X(), reg.X()); } else { - LoadBootImageAddress(argument, boot_image_offset); + uint32_t boot_image_offset = GetBootImageOffsetOfIntrinsicDeclaringClass(invoke); + LoadBootImageAddress(reg, boot_image_offset); } - InvokeRuntime(kQuickAllocObjectInitialized, invoke, invoke->GetDexPc()); - CheckEntrypointTypes<kQuickAllocObjectWithChecks, void*, mirror::Class*>(); } template <linker::LinkerPatch (*Factory)(size_t, const DexFile*, uint32_t, uint32_t)> @@ -5267,7 +5262,7 @@ void InstructionCodeGeneratorARM64::VisitLoadClass(HLoadClass* cls) NO_THREAD_SA } case HLoadClass::LoadKind::kBootImageRelRo: { DCHECK(!codegen_->GetCompilerOptions().IsBootImage()); - uint32_t boot_image_offset = codegen_->GetBootImageOffset(cls); + uint32_t boot_image_offset = CodeGenerator::GetBootImageOffset(cls); // Add ADRP with its PC-relative .data.bimg.rel.ro patch. vixl::aarch64::Label* adrp_label = codegen_->NewBootImageRelRoPatch(boot_image_offset); codegen_->EmitAdrpPlaceholder(adrp_label, out.X()); @@ -5443,7 +5438,7 @@ void InstructionCodeGeneratorARM64::VisitLoadString(HLoadString* load) NO_THREAD case HLoadString::LoadKind::kBootImageRelRo: { DCHECK(!codegen_->GetCompilerOptions().IsBootImage()); // Add ADRP with its PC-relative .data.bimg.rel.ro patch. - uint32_t boot_image_offset = codegen_->GetBootImageOffset(load); + uint32_t boot_image_offset = CodeGenerator::GetBootImageOffset(load); vixl::aarch64::Label* adrp_label = codegen_->NewBootImageRelRoPatch(boot_image_offset); codegen_->EmitAdrpPlaceholder(adrp_label, out.X()); // Add LDR with its PC-relative .data.bimg.rel.ro patch. diff --git a/compiler/optimizing/code_generator_arm64.h b/compiler/optimizing/code_generator_arm64.h index bebf762e68..eb374b5a54 100644 --- a/compiler/optimizing/code_generator_arm64.h +++ b/compiler/optimizing/code_generator_arm64.h @@ -787,7 +787,7 @@ class CodeGeneratorARM64 : public CodeGenerator { vixl::aarch64::Register base); void LoadBootImageAddress(vixl::aarch64::Register reg, uint32_t boot_image_reference); - void AllocateInstanceForIntrinsic(HInvokeStaticOrDirect* invoke, uint32_t boot_image_offset); + void LoadIntrinsicDeclaringClass(vixl::aarch64::Register reg, HInvoke* invoke); void EmitLinkerPatches(ArenaVector<linker::LinkerPatch>* linker_patches) override; bool NeedsThunkCode(const linker::LinkerPatch& patch) const override; diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc index 76b8be1a56..00b258685c 100644 --- a/compiler/optimizing/code_generator_arm_vixl.cc +++ b/compiler/optimizing/code_generator_arm_vixl.cc @@ -7415,7 +7415,7 @@ void InstructionCodeGeneratorARMVIXL::VisitLoadClass(HLoadClass* cls) NO_THREAD_ case HLoadClass::LoadKind::kBootImageRelRo: { DCHECK(!codegen_->GetCompilerOptions().IsBootImage()); CodeGeneratorARMVIXL::PcRelativePatchInfo* labels = - codegen_->NewBootImageRelRoPatch(codegen_->GetBootImageOffset(cls)); + codegen_->NewBootImageRelRoPatch(CodeGenerator::GetBootImageOffset(cls)); codegen_->EmitMovwMovtPlaceholder(labels, out); __ Ldr(out, MemOperand(out, /* offset= */ 0)); break; @@ -7640,7 +7640,7 @@ void InstructionCodeGeneratorARMVIXL::VisitLoadString(HLoadString* load) NO_THRE case HLoadString::LoadKind::kBootImageRelRo: { DCHECK(!codegen_->GetCompilerOptions().IsBootImage()); CodeGeneratorARMVIXL::PcRelativePatchInfo* labels = - codegen_->NewBootImageRelRoPatch(codegen_->GetBootImageOffset(load)); + codegen_->NewBootImageRelRoPatch(CodeGenerator::GetBootImageOffset(load)); codegen_->EmitMovwMovtPlaceholder(labels, out); __ Ldr(out, MemOperand(out, /* offset= */ 0)); return; @@ -9410,23 +9410,18 @@ void CodeGeneratorARMVIXL::LoadBootImageAddress(vixl32::Register reg, } } -void CodeGeneratorARMVIXL::AllocateInstanceForIntrinsic(HInvokeStaticOrDirect* invoke, - uint32_t boot_image_offset) { - DCHECK(invoke->IsStatic()); - InvokeRuntimeCallingConventionARMVIXL calling_convention; - vixl32::Register argument = calling_convention.GetRegisterAt(0); +void CodeGeneratorARMVIXL::LoadIntrinsicDeclaringClass(vixl32::Register reg, HInvoke* invoke) { + DCHECK_NE(invoke->GetIntrinsic(), Intrinsics::kNone); if (GetCompilerOptions().IsBootImage()) { - DCHECK_EQ(boot_image_offset, IntrinsicVisitor::IntegerValueOfInfo::kInvalidReference); // Load the class the same way as for HLoadClass::LoadKind::kBootImageLinkTimePcRelative. MethodReference target_method = invoke->GetResolvedMethodReference(); dex::TypeIndex type_idx = target_method.dex_file->GetMethodId(target_method.index).class_idx_; PcRelativePatchInfo* labels = NewBootImageTypePatch(*target_method.dex_file, type_idx); - EmitMovwMovtPlaceholder(labels, argument); + EmitMovwMovtPlaceholder(labels, reg); } else { - LoadBootImageAddress(argument, boot_image_offset); + uint32_t boot_image_offset = GetBootImageOffsetOfIntrinsicDeclaringClass(invoke); + LoadBootImageAddress(reg, boot_image_offset); } - InvokeRuntime(kQuickAllocObjectInitialized, invoke, invoke->GetDexPc()); - CheckEntrypointTypes<kQuickAllocObjectWithChecks, void*, mirror::Class*>(); } template <linker::LinkerPatch (*Factory)(size_t, const DexFile*, uint32_t, uint32_t)> diff --git a/compiler/optimizing/code_generator_arm_vixl.h b/compiler/optimizing/code_generator_arm_vixl.h index 12594ed7c0..8f3d41cbf2 100644 --- a/compiler/optimizing/code_generator_arm_vixl.h +++ b/compiler/optimizing/code_generator_arm_vixl.h @@ -638,7 +638,7 @@ class CodeGeneratorARMVIXL : public CodeGenerator { Handle<mirror::Class> handle); void LoadBootImageAddress(vixl::aarch32::Register reg, uint32_t boot_image_reference); - void AllocateInstanceForIntrinsic(HInvokeStaticOrDirect* invoke, uint32_t boot_image_offset); + void LoadIntrinsicDeclaringClass(vixl::aarch32::Register reg, HInvoke* invoke); void EmitLinkerPatches(ArenaVector<linker::LinkerPatch>* linker_patches) override; bool NeedsThunkCode(const linker::LinkerPatch& patch) const override; diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index 0f68f3fae8..916f223378 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -5506,29 +5506,24 @@ void CodeGeneratorX86::LoadBootImageAddress(Register reg, } } -void CodeGeneratorX86::AllocateInstanceForIntrinsic(HInvokeStaticOrDirect* invoke, - uint32_t boot_image_offset) { - DCHECK(invoke->IsStatic()); - InvokeRuntimeCallingConvention calling_convention; - Register argument = calling_convention.GetRegisterAt(0); +void CodeGeneratorX86::LoadIntrinsicDeclaringClass(Register reg, HInvokeStaticOrDirect* invoke) { + DCHECK_NE(invoke->GetIntrinsic(), Intrinsics::kNone); if (GetCompilerOptions().IsBootImage()) { - DCHECK_EQ(boot_image_offset, IntrinsicVisitor::IntegerValueOfInfo::kInvalidReference); // Load the class the same way as for HLoadClass::LoadKind::kBootImageLinkTimePcRelative. HX86ComputeBaseMethodAddress* method_address = invoke->InputAt(invoke->GetSpecialInputIndex())->AsX86ComputeBaseMethodAddress(); DCHECK(method_address != nullptr); Register method_address_reg = invoke->GetLocations()->InAt(invoke->GetSpecialInputIndex()).AsRegister<Register>(); - __ leal(argument, Address(method_address_reg, CodeGeneratorX86::kPlaceholder32BitOffset)); + __ leal(reg, Address(method_address_reg, CodeGeneratorX86::kPlaceholder32BitOffset)); MethodReference target_method = invoke->GetResolvedMethodReference(); dex::TypeIndex type_idx = target_method.dex_file->GetMethodId(target_method.index).class_idx_; boot_image_type_patches_.emplace_back(method_address, target_method.dex_file, type_idx.index_); __ Bind(&boot_image_type_patches_.back().label); } else { - LoadBootImageAddress(argument, boot_image_offset, invoke); + uint32_t boot_image_offset = GetBootImageOffsetOfIntrinsicDeclaringClass(invoke); + LoadBootImageAddress(reg, boot_image_offset, invoke); } - InvokeRuntime(kQuickAllocObjectInitialized, invoke, invoke->GetDexPc()); - CheckEntrypointTypes<kQuickAllocObjectWithChecks, void*, mirror::Class*>(); } // The label points to the end of the "movl" or another instruction but the literal offset @@ -7147,7 +7142,7 @@ void InstructionCodeGeneratorX86::VisitLoadClass(HLoadClass* cls) NO_THREAD_SAFE Register method_address = locations->InAt(0).AsRegister<Register>(); __ movl(out, Address(method_address, CodeGeneratorX86::kPlaceholder32BitOffset)); codegen_->RecordBootImageRelRoPatch(cls->InputAt(0)->AsX86ComputeBaseMethodAddress(), - codegen_->GetBootImageOffset(cls)); + CodeGenerator::GetBootImageOffset(cls)); break; } case HLoadClass::LoadKind::kBssEntry: @@ -7346,7 +7341,7 @@ void InstructionCodeGeneratorX86::VisitLoadString(HLoadString* load) NO_THREAD_S Register method_address = locations->InAt(0).AsRegister<Register>(); __ movl(out, Address(method_address, CodeGeneratorX86::kPlaceholder32BitOffset)); codegen_->RecordBootImageRelRoPatch(load->InputAt(0)->AsX86ComputeBaseMethodAddress(), - codegen_->GetBootImageOffset(load)); + CodeGenerator::GetBootImageOffset(load)); return; } case HLoadString::LoadKind::kBssEntry: { diff --git a/compiler/optimizing/code_generator_x86.h b/compiler/optimizing/code_generator_x86.h index 119494c7c6..b024eebe59 100644 --- a/compiler/optimizing/code_generator_x86.h +++ b/compiler/optimizing/code_generator_x86.h @@ -495,7 +495,7 @@ class CodeGeneratorX86 : public CodeGenerator { void LoadBootImageAddress(Register reg, uint32_t boot_image_reference, HInvokeStaticOrDirect* invoke); - void AllocateInstanceForIntrinsic(HInvokeStaticOrDirect* invoke, uint32_t boot_image_offset); + void LoadIntrinsicDeclaringClass(Register reg, HInvokeStaticOrDirect* invoke); Label* NewJitRootStringPatch(const DexFile& dex_file, dex::StringIndex string_index, diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc index dac04a5f34..b8496dbc3d 100644 --- a/compiler/optimizing/code_generator_x86_64.cc +++ b/compiler/optimizing/code_generator_x86_64.cc @@ -1254,25 +1254,20 @@ void CodeGeneratorX86_64::LoadBootImageAddress(CpuRegister reg, uint32_t boot_im } } -void CodeGeneratorX86_64::AllocateInstanceForIntrinsic(HInvokeStaticOrDirect* invoke, - uint32_t boot_image_offset) { - DCHECK(invoke->IsStatic()); - InvokeRuntimeCallingConvention calling_convention; - CpuRegister argument = CpuRegister(calling_convention.GetRegisterAt(0)); +void CodeGeneratorX86_64::LoadIntrinsicDeclaringClass(CpuRegister reg, HInvoke* invoke) { + DCHECK_NE(invoke->GetIntrinsic(), Intrinsics::kNone); if (GetCompilerOptions().IsBootImage()) { - DCHECK_EQ(boot_image_offset, IntrinsicVisitor::IntegerValueOfInfo::kInvalidReference); // Load the class the same way as for HLoadClass::LoadKind::kBootImageLinkTimePcRelative. - __ leal(argument, + __ leal(reg, Address::Absolute(CodeGeneratorX86_64::kPlaceholder32BitOffset, /* no_rip= */ false)); MethodReference target_method = invoke->GetResolvedMethodReference(); dex::TypeIndex type_idx = target_method.dex_file->GetMethodId(target_method.index).class_idx_; boot_image_type_patches_.emplace_back(target_method.dex_file, type_idx.index_); __ Bind(&boot_image_type_patches_.back().label); } else { - LoadBootImageAddress(argument, boot_image_offset); + uint32_t boot_image_offset = GetBootImageOffsetOfIntrinsicDeclaringClass(invoke); + LoadBootImageAddress(reg, boot_image_offset); } - InvokeRuntime(kQuickAllocObjectInitialized, invoke, invoke->GetDexPc()); - CheckEntrypointTypes<kQuickAllocObjectWithChecks, void*, mirror::Class*>(); } // The label points to the end of the "movl" or another instruction but the literal offset @@ -6274,7 +6269,7 @@ void InstructionCodeGeneratorX86_64::VisitLoadClass(HLoadClass* cls) NO_THREAD_S DCHECK(!codegen_->GetCompilerOptions().IsBootImage()); __ movl(out, Address::Absolute(CodeGeneratorX86_64::kPlaceholder32BitOffset, /* no_rip= */ false)); - codegen_->RecordBootImageRelRoPatch(codegen_->GetBootImageOffset(cls)); + codegen_->RecordBootImageRelRoPatch(CodeGenerator::GetBootImageOffset(cls)); break; } case HLoadClass::LoadKind::kBssEntry: @@ -6433,7 +6428,7 @@ void InstructionCodeGeneratorX86_64::VisitLoadString(HLoadString* load) NO_THREA DCHECK(!codegen_->GetCompilerOptions().IsBootImage()); __ movl(out, Address::Absolute(CodeGeneratorX86_64::kPlaceholder32BitOffset, /* no_rip= */ false)); - codegen_->RecordBootImageRelRoPatch(codegen_->GetBootImageOffset(load)); + codegen_->RecordBootImageRelRoPatch(CodeGenerator::GetBootImageOffset(load)); return; } case HLoadString::LoadKind::kBssEntry: { diff --git a/compiler/optimizing/code_generator_x86_64.h b/compiler/optimizing/code_generator_x86_64.h index 2c93f1865d..6038223403 100644 --- a/compiler/optimizing/code_generator_x86_64.h +++ b/compiler/optimizing/code_generator_x86_64.h @@ -475,7 +475,7 @@ class CodeGeneratorX86_64 : public CodeGenerator { Handle<mirror::Class> handle); void LoadBootImageAddress(CpuRegister reg, uint32_t boot_image_reference); - void AllocateInstanceForIntrinsic(HInvokeStaticOrDirect* invoke, uint32_t boot_image_offset); + void LoadIntrinsicDeclaringClass(CpuRegister reg, HInvoke* invoke); void EmitLinkerPatches(ArenaVector<linker::LinkerPatch>* linker_patches) override; diff --git a/compiler/optimizing/intrinsics.cc b/compiler/optimizing/intrinsics.cc index 653d92a020..1663ee91b4 100644 --- a/compiler/optimizing/intrinsics.cc +++ b/compiler/optimizing/intrinsics.cc @@ -21,6 +21,7 @@ #include "base/utils.h" #include "class_linker.h" #include "class_root-inl.h" +#include "code_generator.h" #include "dex/invoke_type.h" #include "driver/compiler_options.h" #include "gc/space/image_space.h" @@ -152,13 +153,14 @@ void IntrinsicVisitor::ComputeIntegerValueOfLocations(HInvoke* invoke, // The intrinsic will call if it needs to allocate a j.l.Integer. LocationSummary::CallKind call_kind = LocationSummary::kCallOnMainOnly; const CompilerOptions& compiler_options = codegen->GetCompilerOptions(); + // Piggyback on the method load kind to determine whether we can use PC-relative addressing + // for AOT. This should cover both the testing config (non-PIC boot image) and codegens that + // reject PC-relative load kinds and fall back to the runtime call. + if (compiler_options.IsAotCompiler() && + !invoke->AsInvokeStaticOrDirect()->HasPcRelativeMethodLoadKind()) { + return; + } if (compiler_options.IsBootImage()) { - // Piggyback on the method load kind to determine whether we can use PC-relative addressing. - // This should cover both the testing config (non-PIC boot image) and codegens that reject - // PC-relative load kinds and fall back to the runtime call. - if (!invoke->AsInvokeStaticOrDirect()->HasPcRelativeMethodLoadKind()) { - return; - } if (!compiler_options.IsImageClass(kIntegerCacheDescriptor) || !compiler_options.IsImageClass(kIntegerDescriptor)) { return; @@ -261,18 +263,10 @@ static int32_t GetIntegerCacheLowFromIntegerCache(Thread* self, ClassLinker* cla return GetIntegerCacheField(cache_class, kLowFieldName); } -static uint32_t CalculateBootImageOffset(ObjPtr<mirror::Object> object) - REQUIRES_SHARED(Locks::mutator_lock_) { - gc::Heap* heap = Runtime::Current()->GetHeap(); - DCHECK(heap->ObjectIsInBootImageSpace(object)); - return reinterpret_cast<const uint8_t*>(object.Ptr()) - heap->GetBootImageSpaces()[0]->Begin(); -} - inline IntrinsicVisitor::IntegerValueOfInfo::IntegerValueOfInfo() : value_offset(0), low(0), length(0u), - integer_boot_image_offset(kInvalidReference), value_boot_image_reference(kInvalidReference) {} IntrinsicVisitor::IntegerValueOfInfo IntrinsicVisitor::ComputeIntegerValueOfInfo( @@ -293,8 +287,8 @@ IntrinsicVisitor::IntegerValueOfInfo IntrinsicVisitor::ComputeIntegerValueOfInfo IntegerValueOfInfo info; if (compiler_options.IsBootImage()) { - ObjPtr<mirror::Class> integer_class = - LookupInitializedClass(self, class_linker, kIntegerDescriptor); + ObjPtr<mirror::Class> integer_class = invoke->GetResolvedMethod()->GetDeclaringClass(); + DCHECK(integer_class->DescriptorEquals(kIntegerDescriptor)); ArtField* value_field = integer_class->FindDeclaredInstanceField(kValueFieldName, "I"); DCHECK(value_field != nullptr); info.value_offset = value_field->GetOffset().Uint32Value(); @@ -304,7 +298,6 @@ IntrinsicVisitor::IntegerValueOfInfo IntrinsicVisitor::ComputeIntegerValueOfInfo int32_t high = GetIntegerCacheField(cache_class, kHighFieldName); info.length = dchecked_integral_cast<uint32_t>(high - info.low + 1); - info.integer_boot_image_offset = IntegerValueOfInfo::kInvalidReference; if (invoke->InputAt(0)->IsIntConstant()) { int32_t input_value = invoke->InputAt(0)->AsIntConstant()->GetValue(); uint32_t index = static_cast<uint32_t>(input_value) - static_cast<uint32_t>(info.low); @@ -340,21 +333,20 @@ IntrinsicVisitor::IntegerValueOfInfo IntrinsicVisitor::ComputeIntegerValueOfInfo info.length = dchecked_integral_cast<uint32_t>( IntrinsicObjects::GetIntegerValueOfCache(boot_image_live_objects)->GetLength()); - info.integer_boot_image_offset = CalculateBootImageOffset(integer_class); if (invoke->InputAt(0)->IsIntConstant()) { int32_t input_value = invoke->InputAt(0)->AsIntConstant()->GetValue(); uint32_t index = static_cast<uint32_t>(input_value) - static_cast<uint32_t>(info.low); if (index < static_cast<uint32_t>(info.length)) { ObjPtr<mirror::Object> integer = IntrinsicObjects::GetIntegerValueOfObject(boot_image_live_objects, index); - info.value_boot_image_reference = CalculateBootImageOffset(integer); + info.value_boot_image_reference = CodeGenerator::GetBootImageOffset(integer); } else { // Not in the cache. info.value_boot_image_reference = IntegerValueOfInfo::kInvalidReference; } } else { info.array_data_boot_image_reference = - CalculateBootImageOffset(boot_image_live_objects) + + CodeGenerator::GetBootImageOffset(boot_image_live_objects) + IntrinsicObjects::GetIntegerValueOfArrayDataOffset(boot_image_live_objects).Uint32Value(); } } diff --git a/compiler/optimizing/intrinsics.h b/compiler/optimizing/intrinsics.h index f3c6d8b4c2..cc26e41067 100644 --- a/compiler/optimizing/intrinsics.h +++ b/compiler/optimizing/intrinsics.h @@ -117,9 +117,6 @@ class IntrinsicVisitor : public ValueObject { // The length of the cache array. uint32_t length; - // Boot image offset of java.lang.Integer for allocating an instance. - uint32_t integer_boot_image_offset; // Set to kInvalidReference when compiling the boot image. - // This union contains references to the boot image. For app AOT or JIT compilation, // these are the boot image offsets of the target. For boot image compilation, the // location shall be known only at link time, so we encode a symbolic reference using diff --git a/compiler/optimizing/intrinsics_arm64.cc b/compiler/optimizing/intrinsics_arm64.cc index c38f5d6748..a7d5b31820 100644 --- a/compiler/optimizing/intrinsics_arm64.cc +++ b/compiler/optimizing/intrinsics_arm64.cc @@ -2825,6 +2825,12 @@ void IntrinsicCodeGeneratorARM64::VisitIntegerValueOf(HInvoke* invoke) { Register out = RegisterFrom(locations->Out(), DataType::Type::kReference); UseScratchRegisterScope temps(masm); Register temp = temps.AcquireW(); + auto allocate_instance = [&]() { + DCHECK(out.X().Is(InvokeRuntimeCallingConvention().GetRegisterAt(0))); + codegen_->LoadIntrinsicDeclaringClass(out, invoke); + codegen_->InvokeRuntime(kQuickAllocObjectInitialized, invoke, invoke->GetDexPc()); + CheckEntrypointTypes<kQuickAllocObjectWithChecks, void*, mirror::Class*>(); + }; if (invoke->InputAt(0)->IsConstant()) { int32_t value = invoke->InputAt(0)->AsIntConstant()->GetValue(); if (static_cast<uint32_t>(value - info.low) < info.length) { @@ -2836,12 +2842,10 @@ void IntrinsicCodeGeneratorARM64::VisitIntegerValueOf(HInvoke* invoke) { // Allocate and initialize a new j.l.Integer. // TODO: If we JIT, we could allocate the j.l.Integer now, and store it in the // JIT object table. - codegen_->AllocateInstanceForIntrinsic(invoke->AsInvokeStaticOrDirect(), - info.integer_boot_image_offset); + allocate_instance(); __ Mov(temp.W(), value); __ Str(temp.W(), HeapOperand(out.W(), info.value_offset)); - // `value` is a final field :-( Ideally, we'd merge this memory barrier with the allocation - // one. + // `value` is a final field, emit the barrier after we have stored it. codegen_->GenerateMemoryBarrier(MemBarrierKind::kStoreStore); } } else { @@ -2861,11 +2865,9 @@ void IntrinsicCodeGeneratorARM64::VisitIntegerValueOf(HInvoke* invoke) { __ B(&done); __ Bind(&allocate); // Otherwise allocate and initialize a new j.l.Integer. - codegen_->AllocateInstanceForIntrinsic(invoke->AsInvokeStaticOrDirect(), - info.integer_boot_image_offset); + allocate_instance(); __ Str(in.W(), HeapOperand(out.W(), info.value_offset)); - // `value` is a final field :-( Ideally, we'd merge this memory barrier with the allocation - // one. + // `value` is a final field, emit the barrier after we have stored it. codegen_->GenerateMemoryBarrier(MemBarrierKind::kStoreStore); __ Bind(&done); } diff --git a/compiler/optimizing/intrinsics_arm_vixl.cc b/compiler/optimizing/intrinsics_arm_vixl.cc index fdef006bdc..2901c472bc 100644 --- a/compiler/optimizing/intrinsics_arm_vixl.cc +++ b/compiler/optimizing/intrinsics_arm_vixl.cc @@ -2945,6 +2945,12 @@ void IntrinsicCodeGeneratorARMVIXL::VisitIntegerValueOf(HInvoke* invoke) { vixl32::Register out = RegisterFrom(locations->Out()); UseScratchRegisterScope temps(assembler->GetVIXLAssembler()); vixl32::Register temp = temps.Acquire(); + auto allocate_instance = [&]() { + DCHECK(out.Is(InvokeRuntimeCallingConventionARMVIXL().GetRegisterAt(0))); + codegen_->LoadIntrinsicDeclaringClass(out, invoke); + codegen_->InvokeRuntime(kQuickAllocObjectInitialized, invoke, invoke->GetDexPc()); + CheckEntrypointTypes<kQuickAllocObjectWithChecks, void*, mirror::Class*>(); + }; if (invoke->InputAt(0)->IsConstant()) { int32_t value = invoke->InputAt(0)->AsIntConstant()->GetValue(); if (static_cast<uint32_t>(value - info.low) < info.length) { @@ -2956,12 +2962,10 @@ void IntrinsicCodeGeneratorARMVIXL::VisitIntegerValueOf(HInvoke* invoke) { // Allocate and initialize a new j.l.Integer. // TODO: If we JIT, we could allocate the j.l.Integer now, and store it in the // JIT object table. - codegen_->AllocateInstanceForIntrinsic(invoke->AsInvokeStaticOrDirect(), - info.integer_boot_image_offset); + allocate_instance(); __ Mov(temp, value); assembler->StoreToOffset(kStoreWord, temp, out, info.value_offset); - // `value` is a final field :-( Ideally, we'd merge this memory barrier with the allocation - // one. + // `value` is a final field, emit the barrier after we have stored it. codegen_->GenerateMemoryBarrier(MemBarrierKind::kStoreStore); } } else { @@ -2979,11 +2983,9 @@ void IntrinsicCodeGeneratorARMVIXL::VisitIntegerValueOf(HInvoke* invoke) { __ B(&done); __ Bind(&allocate); // Otherwise allocate and initialize a new j.l.Integer. - codegen_->AllocateInstanceForIntrinsic(invoke->AsInvokeStaticOrDirect(), - info.integer_boot_image_offset); + allocate_instance(); assembler->StoreToOffset(kStoreWord, in, out, info.value_offset); - // `value` is a final field :-( Ideally, we'd merge this memory barrier with the allocation - // one. + // `value` is a final field, emit the barrier after we have stored it. codegen_->GenerateMemoryBarrier(MemBarrierKind::kStoreStore); __ Bind(&done); } diff --git a/compiler/optimizing/intrinsics_x86.cc b/compiler/optimizing/intrinsics_x86.cc index 045cacd8c7..4095259f38 100644 --- a/compiler/optimizing/intrinsics_x86.cc +++ b/compiler/optimizing/intrinsics_x86.cc @@ -3043,7 +3043,12 @@ void IntrinsicCodeGeneratorX86::VisitIntegerValueOf(HInvoke* invoke) { X86Assembler* assembler = GetAssembler(); Register out = locations->Out().AsRegister<Register>(); - InvokeRuntimeCallingConvention calling_convention; + auto allocate_instance = [&]() { + DCHECK_EQ(out, InvokeRuntimeCallingConvention().GetRegisterAt(0)); + codegen_->LoadIntrinsicDeclaringClass(out, invoke->AsInvokeStaticOrDirect()); + codegen_->InvokeRuntime(kQuickAllocObjectInitialized, invoke, invoke->GetDexPc()); + CheckEntrypointTypes<kQuickAllocObjectWithChecks, void*, mirror::Class*>(); + }; if (invoke->InputAt(0)->IsConstant()) { int32_t value = invoke->InputAt(0)->AsIntConstant()->GetValue(); if (static_cast<uint32_t>(value - info.low) < info.length) { @@ -3056,8 +3061,7 @@ void IntrinsicCodeGeneratorX86::VisitIntegerValueOf(HInvoke* invoke) { // Allocate and initialize a new j.l.Integer. // TODO: If we JIT, we could allocate the j.l.Integer now, and store it in the // JIT object table. - codegen_->AllocateInstanceForIntrinsic(invoke->AsInvokeStaticOrDirect(), - info.integer_boot_image_offset); + allocate_instance(); __ movl(Address(out, info.value_offset), Immediate(value)); } } else { @@ -3097,8 +3101,7 @@ void IntrinsicCodeGeneratorX86::VisitIntegerValueOf(HInvoke* invoke) { __ jmp(&done); __ Bind(&allocate); // Otherwise allocate and initialize a new j.l.Integer. - codegen_->AllocateInstanceForIntrinsic(invoke->AsInvokeStaticOrDirect(), - info.integer_boot_image_offset); + allocate_instance(); __ movl(Address(out, info.value_offset), in); __ Bind(&done); } diff --git a/compiler/optimizing/intrinsics_x86_64.cc b/compiler/optimizing/intrinsics_x86_64.cc index 7ebc632f2b..985f09590c 100644 --- a/compiler/optimizing/intrinsics_x86_64.cc +++ b/compiler/optimizing/intrinsics_x86_64.cc @@ -2616,6 +2616,11 @@ void IntrinsicCodeGeneratorX86_64::VisitIntegerValueOf(HInvoke* invoke) { CpuRegister out = locations->Out().AsRegister<CpuRegister>(); InvokeRuntimeCallingConvention calling_convention; CpuRegister argument = CpuRegister(calling_convention.GetRegisterAt(0)); + auto allocate_instance = [&]() { + codegen_->LoadIntrinsicDeclaringClass(argument, invoke); + codegen_->InvokeRuntime(kQuickAllocObjectInitialized, invoke, invoke->GetDexPc()); + CheckEntrypointTypes<kQuickAllocObjectWithChecks, void*, mirror::Class*>(); + }; if (invoke->InputAt(0)->IsIntConstant()) { int32_t value = invoke->InputAt(0)->AsIntConstant()->GetValue(); if (static_cast<uint32_t>(value - info.low) < info.length) { @@ -2627,8 +2632,7 @@ void IntrinsicCodeGeneratorX86_64::VisitIntegerValueOf(HInvoke* invoke) { // Allocate and initialize a new j.l.Integer. // TODO: If we JIT, we could allocate the j.l.Integer now, and store it in the // JIT object table. - codegen_->AllocateInstanceForIntrinsic(invoke->AsInvokeStaticOrDirect(), - info.integer_boot_image_offset); + allocate_instance(); __ movl(Address(out, info.value_offset), Immediate(value)); } } else { @@ -2649,8 +2653,7 @@ void IntrinsicCodeGeneratorX86_64::VisitIntegerValueOf(HInvoke* invoke) { __ jmp(&done); __ Bind(&allocate); // Otherwise allocate and initialize a new j.l.Integer. - codegen_->AllocateInstanceForIntrinsic(invoke->AsInvokeStaticOrDirect(), - info.integer_boot_image_offset); + allocate_instance(); __ movl(Address(out, info.value_offset), in); __ Bind(&done); } |