diff options
author | 2024-10-07 09:41:11 +0200 | |
---|---|---|
committer | 2024-10-07 11:59:00 +0000 | |
commit | d576392c76d75335d8284217f2153bdace62b355 (patch) | |
tree | b625b235b2f64c856546e0b230b07d0dbe8f4f06 | |
parent | c50d67991682a9ae5e6215031a9852bbf018504b (diff) |
Pass ISA to `Context::CalleeSaveAddress()`.
And clean up `QuickArgumentVisitor` implementation.
This is a follow-up to
https://android-review.googlesource.com/2680018 .
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Change-Id: I18c0babd5fffa3d93aa4cb4377ef759424854a49
-rw-r--r-- | runtime/arch/arm/context_arm.cc | 5 | ||||
-rw-r--r-- | runtime/arch/arm64/context_arm64.cc | 5 | ||||
-rw-r--r-- | runtime/arch/context.h | 9 | ||||
-rw-r--r-- | runtime/arch/riscv64/context_riscv64.cc | 7 | ||||
-rw-r--r-- | runtime/arch/x86/context_x86.cc | 7 | ||||
-rw-r--r-- | runtime/arch/x86_64/context_x86_64.cc | 5 | ||||
-rw-r--r-- | runtime/entrypoints/quick/quick_trampoline_entrypoints.cc | 81 |
7 files changed, 49 insertions, 70 deletions
diff --git a/runtime/arch/arm/context_arm.cc b/runtime/arch/arm/context_arm.cc index 50aec3331b..09756f68b6 100644 --- a/runtime/arch/arm/context_arm.cc +++ b/runtime/arch/arm/context_arm.cc @@ -39,20 +39,21 @@ void ArmContext::Reset() { } void ArmContext::FillCalleeSaves(uint8_t* frame, const QuickMethodFrameInfo& frame_info) { + const size_t frame_size = frame_info.FrameSizeInBytes(); int spill_pos = 0; // Core registers come first, from the highest down to the lowest. uint32_t core_regs = frame_info.CoreSpillMask(); DCHECK_EQ(0u, core_regs & (static_cast<uint32_t>(-1) << kNumberOfCoreRegisters)); for (uint32_t core_reg : HighToLowBits(core_regs)) { - gprs_[core_reg] = CalleeSaveAddress(frame, spill_pos, frame_info.FrameSizeInBytes()); + gprs_[core_reg] = CalleeSaveAddress<InstructionSet::kArm>(frame, spill_pos, frame_size); ++spill_pos; } DCHECK_EQ(spill_pos, POPCOUNT(frame_info.CoreSpillMask())); // FP registers come second, from the highest down to the lowest. for (uint32_t fp_reg : HighToLowBits(frame_info.FpSpillMask())) { - fprs_[fp_reg] = CalleeSaveAddress(frame, spill_pos, frame_info.FrameSizeInBytes()); + fprs_[fp_reg] = CalleeSaveAddress<InstructionSet::kArm>(frame, spill_pos, frame_size); ++spill_pos; } DCHECK_EQ(spill_pos, POPCOUNT(frame_info.CoreSpillMask()) + POPCOUNT(frame_info.FpSpillMask())); diff --git a/runtime/arch/arm64/context_arm64.cc b/runtime/arch/arm64/context_arm64.cc index 77009e4932..9b5afb55d2 100644 --- a/runtime/arch/arm64/context_arm64.cc +++ b/runtime/arch/arm64/context_arm64.cc @@ -48,18 +48,19 @@ void Arm64Context::Reset() { } void Arm64Context::FillCalleeSaves(uint8_t* frame, const QuickMethodFrameInfo& frame_info) { + const size_t frame_size = frame_info.FrameSizeInBytes(); int spill_pos = 0; // Core registers come first, from the highest down to the lowest. for (uint32_t core_reg : HighToLowBits(frame_info.CoreSpillMask())) { - gprs_[core_reg] = CalleeSaveAddress(frame, spill_pos, frame_info.FrameSizeInBytes()); + gprs_[core_reg] = CalleeSaveAddress<InstructionSet::kArm64>(frame, spill_pos, frame_size); ++spill_pos; } DCHECK_EQ(spill_pos, POPCOUNT(frame_info.CoreSpillMask())); // FP registers come second, from the highest down to the lowest. for (uint32_t fp_reg : HighToLowBits(frame_info.FpSpillMask())) { - fprs_[fp_reg] = CalleeSaveAddress(frame, spill_pos, frame_info.FrameSizeInBytes()); + fprs_[fp_reg] = CalleeSaveAddress<InstructionSet::kArm64>(frame, spill_pos, frame_size); ++spill_pos; } DCHECK_EQ(spill_pos, POPCOUNT(frame_info.CoreSpillMask()) + POPCOUNT(frame_info.FpSpillMask())); diff --git a/runtime/arch/context.h b/runtime/arch/context.h index 2c442bdb4a..55988d0a6e 100644 --- a/runtime/arch/context.h +++ b/runtime/arch/context.h @@ -40,12 +40,13 @@ class Context { // Re-initializes the registers for context re-use. virtual void Reset() = 0; + template <InstructionSet kIsa> static uintptr_t* CalleeSaveAddress(uint8_t* frame, int num, size_t frame_size) { + static constexpr size_t kPointerSize = static_cast<size_t>(GetInstructionSetPointerSize(kIsa)); // Callee saves are held at the top of the frame - uint8_t* save_addr = frame + frame_size - ((num + 1) * sizeof(void*)); - if (kRuntimeISA == InstructionSet::kX86 || - kRuntimeISA == InstructionSet::kX86_64) { - save_addr -= sizeof(void*); // account for return address + uint8_t* save_addr = frame + frame_size - ((num + 1) * kPointerSize); + if (kIsa == InstructionSet::kX86 || kIsa == InstructionSet::kX86_64) { + save_addr -= kPointerSize; // account for return address } return reinterpret_cast<uintptr_t*>(save_addr); } diff --git a/runtime/arch/riscv64/context_riscv64.cc b/runtime/arch/riscv64/context_riscv64.cc index dceebe1e1f..779bb17e08 100644 --- a/runtime/arch/riscv64/context_riscv64.cc +++ b/runtime/arch/riscv64/context_riscv64.cc @@ -45,19 +45,20 @@ void Riscv64Context::Reset() { void Riscv64Context::FillCalleeSaves(uint8_t* frame, const QuickMethodFrameInfo& frame_info) { // RA is at top of the frame DCHECK_NE(frame_info.CoreSpillMask() & (1u << RA), 0u); - gprs_[RA] = CalleeSaveAddress(frame, 0, frame_info.FrameSizeInBytes()); + const size_t frame_size = frame_info.FrameSizeInBytes(); + gprs_[RA] = CalleeSaveAddress<InstructionSet::kRiscv64>(frame, 0, frame_size); // Core registers come first, from the highest down to the lowest, with the exception of RA/X1. int spill_pos = 1; for (uint32_t core_reg : HighToLowBits(frame_info.CoreSpillMask() & ~(1u << RA))) { - gprs_[core_reg] = CalleeSaveAddress(frame, spill_pos, frame_info.FrameSizeInBytes()); + gprs_[core_reg] = CalleeSaveAddress<InstructionSet::kRiscv64>(frame, spill_pos, frame_size); ++spill_pos; } DCHECK_EQ(spill_pos, POPCOUNT(frame_info.CoreSpillMask())); // FP registers come second, from the highest down to the lowest. for (uint32_t fp_reg : HighToLowBits(frame_info.FpSpillMask())) { - fprs_[fp_reg] = CalleeSaveAddress(frame, spill_pos, frame_info.FrameSizeInBytes()); + fprs_[fp_reg] = CalleeSaveAddress<InstructionSet::kRiscv64>(frame, spill_pos, frame_size); ++spill_pos; } DCHECK_EQ(spill_pos, POPCOUNT(frame_info.CoreSpillMask()) + POPCOUNT(frame_info.FpSpillMask())); diff --git a/runtime/arch/x86/context_x86.cc b/runtime/arch/x86/context_x86.cc index 40f1a4aa8d..cb915b190e 100644 --- a/runtime/arch/x86/context_x86.cc +++ b/runtime/arch/x86/context_x86.cc @@ -38,6 +38,7 @@ void X86Context::Reset() { } void X86Context::FillCalleeSaves(uint8_t* frame, const QuickMethodFrameInfo& frame_info) { + const size_t frame_size = frame_info.FrameSizeInBytes(); int spill_pos = 0; // Core registers come first, from the highest down to the lowest. @@ -45,7 +46,7 @@ void X86Context::FillCalleeSaves(uint8_t* frame, const QuickMethodFrameInfo& fra frame_info.CoreSpillMask() & ~(static_cast<uint32_t>(-1) << kNumberOfCpuRegisters); DCHECK_EQ(1, POPCOUNT(frame_info.CoreSpillMask() & ~core_regs)); // Return address spill. for (uint32_t core_reg : HighToLowBits(core_regs)) { - gprs_[core_reg] = CalleeSaveAddress(frame, spill_pos, frame_info.FrameSizeInBytes()); + gprs_[core_reg] = CalleeSaveAddress<InstructionSet::kX86>(frame, spill_pos, frame_size); ++spill_pos; } DCHECK_EQ(spill_pos, POPCOUNT(frame_info.CoreSpillMask()) - 1); @@ -56,9 +57,9 @@ void X86Context::FillCalleeSaves(uint8_t* frame, const QuickMethodFrameInfo& fra for (uint32_t fp_reg : HighToLowBits(fp_regs)) { // Two void* per XMM register. fprs_[2 * fp_reg] = reinterpret_cast<uint32_t*>( - CalleeSaveAddress(frame, spill_pos + 1, frame_info.FrameSizeInBytes())); + CalleeSaveAddress<InstructionSet::kX86>(frame, spill_pos + 1, frame_size)); fprs_[2 * fp_reg + 1] = reinterpret_cast<uint32_t*>( - CalleeSaveAddress(frame, spill_pos, frame_info.FrameSizeInBytes())); + CalleeSaveAddress<InstructionSet::kX86>(frame, spill_pos, frame_size)); spill_pos += 2; } DCHECK_EQ(spill_pos, diff --git a/runtime/arch/x86_64/context_x86_64.cc b/runtime/arch/x86_64/context_x86_64.cc index d40395bc8b..f6a3720d55 100644 --- a/runtime/arch/x86_64/context_x86_64.cc +++ b/runtime/arch/x86_64/context_x86_64.cc @@ -37,6 +37,7 @@ void X86_64Context::Reset() { } void X86_64Context::FillCalleeSaves(uint8_t* frame, const QuickMethodFrameInfo& frame_info) { + const size_t frame_size = frame_info.FrameSizeInBytes(); int spill_pos = 0; // Core registers come first, from the highest down to the lowest. @@ -44,7 +45,7 @@ void X86_64Context::FillCalleeSaves(uint8_t* frame, const QuickMethodFrameInfo& frame_info.CoreSpillMask() & ~(static_cast<uint32_t>(-1) << kNumberOfCpuRegisters); DCHECK_EQ(1, POPCOUNT(frame_info.CoreSpillMask() & ~core_regs)); // Return address spill. for (uint32_t core_reg : HighToLowBits(core_regs)) { - gprs_[core_reg] = CalleeSaveAddress(frame, spill_pos, frame_info.FrameSizeInBytes()); + gprs_[core_reg] = CalleeSaveAddress<InstructionSet::kX86_64>(frame, spill_pos, frame_size); ++spill_pos; } DCHECK_EQ(spill_pos, POPCOUNT(frame_info.CoreSpillMask()) - 1); @@ -54,7 +55,7 @@ void X86_64Context::FillCalleeSaves(uint8_t* frame, const QuickMethodFrameInfo& DCHECK_EQ(0u, fp_regs & (static_cast<uint32_t>(-1) << kNumberOfFloatRegisters)); for (uint32_t fp_reg : HighToLowBits(fp_regs)) { fprs_[fp_reg] = reinterpret_cast<uint64_t*>( - CalleeSaveAddress(frame, spill_pos, frame_info.FrameSizeInBytes())); + CalleeSaveAddress<InstructionSet::kX86_64>(frame, spill_pos, frame_size)); ++spill_pos; } DCHECK_EQ(spill_pos, diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc index 06cc82077a..fc97e6c1d3 100644 --- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc @@ -67,8 +67,8 @@ namespace art HIDDEN { // Visits the arguments as saved to the stack by a CalleeSaveType::kRefAndArgs callee save frame. -template <typename Derived> -class QuickArgumentVisitorBase { +template <typename FrameInfo> +class QuickArgumentVisitorImpl { // Number of bytes for each out register in the caller method's frame. static constexpr size_t kBytesStackArgLocation = 4; // Frame size in bytes of a callee-save frame for RefsAndArgs. @@ -85,23 +85,23 @@ class QuickArgumentVisitorBase { RuntimeCalleeSaveFrame::GetReturnPcOffset(CalleeSaveType::kSaveRefsAndArgs); static size_t GprIndexToGprOffset(uint32_t gpr_index) { - return Derived::GprIndexToGprOffsetImpl(gpr_index); + return FrameInfo::GprIndexToGprOffsetImpl(gpr_index); } static constexpr bool kSplitPairAcrossRegisterAndStack = - Derived::kSplitPairAcrossRegisterAndStack; - static constexpr bool kAlignPairRegister = Derived::kAlignPairRegister; - static constexpr bool kQuickSoftFloatAbi = Derived::kQuickSoftFloatAbi; + FrameInfo::kSplitPairAcrossRegisterAndStack; + static constexpr bool kAlignPairRegister = FrameInfo::kAlignPairRegister; + static constexpr bool kQuickSoftFloatAbi = FrameInfo::kQuickSoftFloatAbi; static constexpr bool kQuickDoubleRegAlignedFloatBackFilled = - Derived::kQuickDoubleRegAlignedFloatBackFilled; - static constexpr bool kQuickSkipOddFpRegisters = Derived::kQuickSkipOddFpRegisters; - static constexpr size_t kNumQuickGprArgs = Derived::kNumQuickGprArgs; - static constexpr size_t kNumQuickFprArgs = Derived::kNumQuickFprArgs; - static constexpr bool kGprFprLockstep = Derived::kGprFprLockstep; - static constexpr bool kNaNBoxing = Derived::kNanBoxing; + FrameInfo::kQuickDoubleRegAlignedFloatBackFilled; + static constexpr bool kQuickSkipOddFpRegisters = FrameInfo::kQuickSkipOddFpRegisters; + static constexpr size_t kNumQuickGprArgs = FrameInfo::kNumQuickGprArgs; + static constexpr size_t kNumQuickFprArgs = FrameInfo::kNumQuickFprArgs; + static constexpr bool kGprFprLockstep = FrameInfo::kGprFprLockstep; + static constexpr bool kNaNBoxing = FrameInfo::kNanBoxing; public: - static constexpr bool NaNBoxing() { return Derived::kNaNBoxing; } + static constexpr bool NaNBoxing() { return FrameInfo::kNaNBoxing; } static StackReference<mirror::Object>* GetThisObjectReference(ArtMethod** sp) REQUIRES_SHARED(Locks::mutator_lock_) { @@ -143,7 +143,7 @@ class QuickArgumentVisitorBase { return *reinterpret_cast<uintptr_t*>(GetCallingPcAddr(sp)); } - QuickArgumentVisitorBase(ArtMethod** sp, bool is_static, std::string_view shorty) + QuickArgumentVisitorImpl(ArtMethod** sp, bool is_static, std::string_view shorty) REQUIRES_SHARED(Locks::mutator_lock_) : is_static_(is_static), shorty_(shorty), @@ -168,7 +168,7 @@ class QuickArgumentVisitorBase { DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), kRuntimePointerSize); } - virtual ~QuickArgumentVisitorBase() {} + virtual ~QuickArgumentVisitorImpl() {} virtual void Visit() = 0; @@ -384,7 +384,7 @@ class QuickArgumentVisitorBase { bool is_split_long_or_double_; }; -class QuickArgumentFrameInfoARM : public QuickArgumentVisitorBase<QuickArgumentFrameInfoARM> { +class QuickArgumentFrameInfoARM { public: // The callee save frame is pointed to by SP. // | argN | | @@ -416,14 +416,9 @@ class QuickArgumentFrameInfoARM : public QuickArgumentVisitorBase<QuickArgumentF static size_t GprIndexToGprOffsetImpl(uint32_t gpr_index) { return gpr_index * GetBytesPerGprSpillLocation(kRuntimeISA); } - - QuickArgumentFrameInfoARM(ArtMethod** sp, - bool is_static, - std::string_view shorty) REQUIRES_SHARED(Locks::mutator_lock_) - : QuickArgumentVisitorBase(sp, is_static, shorty) {} }; -class QuickArgumentFrameInfoARM64 : public QuickArgumentVisitorBase<QuickArgumentFrameInfoARM64> { +class QuickArgumentFrameInfoARM64 { public: // The callee save frame is pointed to by SP. // | argN | | @@ -457,15 +452,9 @@ class QuickArgumentFrameInfoARM64 : public QuickArgumentVisitorBase<QuickArgumen static size_t GprIndexToGprOffsetImpl(uint32_t gpr_index) { return gpr_index * GetBytesPerGprSpillLocation(kRuntimeISA); } - - QuickArgumentFrameInfoARM64(ArtMethod** sp, - bool is_static, - std::string_view shorty) REQUIRES_SHARED(Locks::mutator_lock_) - : QuickArgumentVisitorBase(sp, is_static, shorty) {} }; -class QuickArgumentFrameInfoRISCV64 : - public QuickArgumentVisitorBase<QuickArgumentFrameInfoRISCV64> { +class QuickArgumentFrameInfoRISCV64 { public: // The callee save frame is pointed to by SP. // | argN | | @@ -512,14 +501,9 @@ class QuickArgumentFrameInfoRISCV64 : static size_t GprIndexToGprOffsetImpl(uint32_t gpr_index) { return (gpr_index + 1) * GetBytesPerGprSpillLocation(kRuntimeISA); // skip S0/X8/FP } - - QuickArgumentFrameInfoRISCV64(ArtMethod** sp, - bool is_static, - std::string_view shorty) REQUIRES_SHARED(Locks::mutator_lock_) - : QuickArgumentVisitorBase(sp, is_static, shorty) {} }; -class QuickArgumentFrameInfoX86 : public QuickArgumentVisitorBase<QuickArgumentFrameInfoX86> { +class QuickArgumentFrameInfoX86 { public: // The callee save frame is pointed to by SP. // | argN | | @@ -551,15 +535,9 @@ class QuickArgumentFrameInfoX86 : public QuickArgumentVisitorBase<QuickArgumentF static size_t GprIndexToGprOffsetImpl(uint32_t gpr_index) { return gpr_index * GetBytesPerGprSpillLocation(kRuntimeISA); } - - QuickArgumentFrameInfoX86(ArtMethod** sp, - bool is_static, - std::string_view shorty) REQUIRES_SHARED(Locks::mutator_lock_) - : QuickArgumentVisitorBase(sp, is_static, shorty) {} }; -class QuickArgumentFrameInfoX86_64 : - public QuickArgumentVisitorBase<QuickArgumentFrameInfoX86_64> { +class QuickArgumentFrameInfoX86_64 { public: // The callee save frame is pointed to by SP. // | argN | | @@ -613,33 +591,28 @@ class QuickArgumentFrameInfoX86_64 : UNREACHABLE(); } } - - QuickArgumentFrameInfoX86_64(ArtMethod** sp, - bool is_static, - std::string_view shorty) REQUIRES_SHARED(Locks::mutator_lock_) - : QuickArgumentVisitorBase(sp, is_static, shorty) {} }; namespace detail { template <InstructionSet> -struct QAVSelector; +struct QAFISelector; template <> -struct QAVSelector<InstructionSet::kArm> { using type = QuickArgumentFrameInfoARM; }; +struct QAFISelector<InstructionSet::kArm> { using type = QuickArgumentFrameInfoARM; }; template <> -struct QAVSelector<InstructionSet::kArm64> { using type = QuickArgumentFrameInfoARM64; }; +struct QAFISelector<InstructionSet::kArm64> { using type = QuickArgumentFrameInfoARM64; }; template <> -struct QAVSelector<InstructionSet::kRiscv64> { using type = QuickArgumentFrameInfoRISCV64; }; +struct QAFISelector<InstructionSet::kRiscv64> { using type = QuickArgumentFrameInfoRISCV64; }; template <> -struct QAVSelector<InstructionSet::kX86> { using type = QuickArgumentFrameInfoX86; }; +struct QAFISelector<InstructionSet::kX86> { using type = QuickArgumentFrameInfoX86; }; template <> -struct QAVSelector<InstructionSet::kX86_64> { using type = QuickArgumentFrameInfoX86_64; }; +struct QAFISelector<InstructionSet::kX86_64> { using type = QuickArgumentFrameInfoX86_64; }; } // namespace detail // TODO(Simulator): Use the quick code ISA instead of kRuntimeISA. -using QuickArgumentVisitor = detail::QAVSelector<kRuntimeISA>::type; +using QuickArgumentVisitor = QuickArgumentVisitorImpl<detail::QAFISelector<kRuntimeISA>::type>; // Returns the 'this' object of a proxy method. This function is only used by StackVisitor. It // allows to use the QuickArgumentVisitor constants without moving all the code in its own module. |