diff options
21 files changed, 469 insertions, 542 deletions
diff --git a/compiler/optimizing/code_generator_arm64.h b/compiler/optimizing/code_generator_arm64.h index aa343b1185..e7fe5b71b7 100644 --- a/compiler/optimizing/code_generator_arm64.h +++ b/compiler/optimizing/code_generator_arm64.h @@ -17,7 +17,6 @@ #ifndef ART_COMPILER_OPTIMIZING_CODE_GENERATOR_ARM64_H_ #define ART_COMPILER_OPTIMIZING_CODE_GENERATOR_ARM64_H_ -#include "arch/arm64/quick_method_frame_info_arm64.h" #include "base/bit_field.h" #include "code_generator.h" #include "common_arm64.h" diff --git a/compiler/utils/x86/constants_x86.h b/compiler/utils/x86/constants_x86.h index 73ef028075..a782b16c6b 100644 --- a/compiler/utils/x86/constants_x86.h +++ b/compiler/utils/x86/constants_x86.h @@ -40,21 +40,6 @@ enum ByteRegister { kNoByteRegister = -1 // Signals an illegal register. }; - -enum XmmRegister { - XMM0 = 0, - XMM1 = 1, - XMM2 = 2, - XMM3 = 3, - XMM4 = 4, - XMM5 = 5, - XMM6 = 6, - XMM7 = 7, - kNumberOfXmmRegisters = 8, - kNoXmmRegister = -1 // Signals an illegal register. -}; -std::ostream& operator<<(std::ostream& os, const XmmRegister& reg); - enum X87Register { ST0 = 0, ST1 = 1, diff --git a/runtime/arch/arch_test.cc b/runtime/arch/arch_test.cc index 1ba4070056..d4ceede07a 100644 --- a/runtime/arch/arch_test.cc +++ b/runtime/arch/arch_test.cc @@ -18,6 +18,7 @@ #include "art_method-inl.h" #include "base/callee_save_type.h" +#include "entrypoints/quick/callee_save_frame.h" #include "common_runtime_test.h" #include "quick/quick_method_frame_info.h" @@ -57,21 +58,6 @@ class ArchTest : public CommonRuntimeTest { void FinalizeSetup() OVERRIDE { ASSERT_EQ(InstructionSet::kX86_64, Runtime::Current()->GetInstructionSet()); } - - static void CheckFrameSize(InstructionSet isa, CalleeSaveType type, uint32_t save_size) - NO_THREAD_SAFETY_ANALYSIS { - Runtime* const runtime = Runtime::Current(); - Thread* const self = Thread::Current(); - ScopedObjectAccess soa(self); // So we can create callee-save methods. - - runtime->SetInstructionSet(isa); - ArtMethod* save_method = runtime->CreateCalleeSaveMethod(); - runtime->SetCalleeSaveMethod(save_method, type); - QuickMethodFrameInfo frame_info = runtime->GetRuntimeMethodFrameInfo(save_method); - EXPECT_EQ(frame_info.FrameSizeInBytes(), save_size) << "Expected and real size differs for " - << type << " core spills=" << std::hex << frame_info.CoreSpillMask() << " fp spills=" - << frame_info.FpSpillMask() << std::dec; - } }; TEST_F(ArchTest, CheckCommonOffsetsAndSizes) { @@ -205,26 +191,20 @@ static constexpr size_t kFrameSizeSaveEverything = FRAME_SIZE_SAVE_EVERYTHING; } // namespace x86_64 // Check architecture specific constants are sound. -#define TEST_ARCH(Arch, arch) \ - TEST_F(ArchTest, Arch) { \ - CheckFrameSize(InstructionSet::k##Arch, \ - CalleeSaveType::kSaveAllCalleeSaves, \ - arch::kFrameSizeSaveAllCalleeSaves); \ - CheckFrameSize(InstructionSet::k##Arch, \ - CalleeSaveType::kSaveRefsOnly, \ - arch::kFrameSizeSaveRefsOnly); \ - CheckFrameSize(InstructionSet::k##Arch, \ - CalleeSaveType::kSaveRefsAndArgs, \ - arch::kFrameSizeSaveRefsAndArgs); \ - CheckFrameSize(InstructionSet::k##Arch, \ - CalleeSaveType::kSaveEverything, \ - arch::kFrameSizeSaveEverything); \ - CheckFrameSize(InstructionSet::k##Arch, \ - CalleeSaveType::kSaveEverythingForClinit, \ - arch::kFrameSizeSaveEverythingForClinit); \ - CheckFrameSize(InstructionSet::k##Arch, \ - CalleeSaveType::kSaveEverythingForSuspendCheck, \ - arch::kFrameSizeSaveEverythingForSuspendCheck); \ +// We expect the return PC to be stored at the highest address slot in the frame. +#define TEST_ARCH_TYPE(Arch, arch, type) \ + EXPECT_EQ(arch::Arch##CalleeSaveFrame::GetFrameSize(CalleeSaveType::k##type), \ + arch::kFrameSize##type); \ + EXPECT_EQ(arch::Arch##CalleeSaveFrame::GetReturnPcOffset(CalleeSaveType::k##type), \ + arch::kFrameSize##type - static_cast<size_t>(k##Arch##PointerSize)) +#define TEST_ARCH(Arch, arch) \ + TEST_F(ArchTest, Arch) { \ + TEST_ARCH_TYPE(Arch, arch, SaveAllCalleeSaves); \ + TEST_ARCH_TYPE(Arch, arch, SaveRefsOnly); \ + TEST_ARCH_TYPE(Arch, arch, SaveRefsAndArgs); \ + TEST_ARCH_TYPE(Arch, arch, SaveEverything); \ + TEST_ARCH_TYPE(Arch, arch, SaveEverythingForClinit); \ + TEST_ARCH_TYPE(Arch, arch, SaveEverythingForSuspendCheck); \ } TEST_ARCH(Arm, arm) TEST_ARCH(Arm64, arm64) diff --git a/runtime/arch/arm/quick_method_frame_info_arm.h b/runtime/arch/arm/callee_save_frame_arm.h index 5c5b81baae..11eefb9283 100644 --- a/runtime/arch/arm/quick_method_frame_info_arm.h +++ b/runtime/arch/arm/callee_save_frame_arm.h @@ -14,13 +14,14 @@ * limitations under the License. */ -#ifndef ART_RUNTIME_ARCH_ARM_QUICK_METHOD_FRAME_INFO_ARM_H_ -#define ART_RUNTIME_ARCH_ARM_QUICK_METHOD_FRAME_INFO_ARM_H_ +#ifndef ART_RUNTIME_ARCH_ARM_CALLEE_SAVE_FRAME_ARM_H_ +#define ART_RUNTIME_ARCH_ARM_CALLEE_SAVE_FRAME_ARM_H_ #include "arch/instruction_set.h" #include "base/bit_utils.h" #include "base/callee_save_type.h" #include "base/enums.h" +#include "base/globals.h" #include "quick/quick_method_frame_info.h" #include "registers_arm.h" @@ -55,56 +56,56 @@ static constexpr uint32_t kArmCalleeSaveFpAllSpills = static constexpr uint32_t kArmCalleeSaveFpEverythingSpills = kArmCalleeSaveFpArgSpills | kArmCalleeSaveFpAllSpills; -constexpr uint32_t ArmCalleeSaveCoreSpills(CalleeSaveType type) { - type = GetCanonicalCalleeSaveType(type); - return kArmCalleeSaveAlwaysSpills | kArmCalleeSaveRefSpills | - (type == CalleeSaveType::kSaveRefsAndArgs ? kArmCalleeSaveArgSpills : 0) | - (type == CalleeSaveType::kSaveAllCalleeSaves ? kArmCalleeSaveAllSpills : 0) | - (type == CalleeSaveType::kSaveEverything ? kArmCalleeSaveEverythingSpills : 0); -} +class ArmCalleeSaveFrame { + public: + static constexpr uint32_t GetCoreSpills(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return kArmCalleeSaveAlwaysSpills | kArmCalleeSaveRefSpills | + (type == CalleeSaveType::kSaveRefsAndArgs ? kArmCalleeSaveArgSpills : 0) | + (type == CalleeSaveType::kSaveAllCalleeSaves ? kArmCalleeSaveAllSpills : 0) | + (type == CalleeSaveType::kSaveEverything ? kArmCalleeSaveEverythingSpills : 0); + } -constexpr uint32_t ArmCalleeSaveFpSpills(CalleeSaveType type) { - type = GetCanonicalCalleeSaveType(type); - return kArmCalleeSaveFpAlwaysSpills | kArmCalleeSaveFpRefSpills | - (type == CalleeSaveType::kSaveRefsAndArgs ? kArmCalleeSaveFpArgSpills : 0) | - (type == CalleeSaveType::kSaveAllCalleeSaves ? kArmCalleeSaveFpAllSpills : 0) | - (type == CalleeSaveType::kSaveEverything ? kArmCalleeSaveFpEverythingSpills : 0); -} + static constexpr uint32_t GetFpSpills(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return kArmCalleeSaveFpAlwaysSpills | kArmCalleeSaveFpRefSpills | + (type == CalleeSaveType::kSaveRefsAndArgs ? kArmCalleeSaveFpArgSpills : 0) | + (type == CalleeSaveType::kSaveAllCalleeSaves ? kArmCalleeSaveFpAllSpills : 0) | + (type == CalleeSaveType::kSaveEverything ? kArmCalleeSaveFpEverythingSpills : 0); + } -constexpr uint32_t ArmCalleeSaveFrameSize(CalleeSaveType type) { - type = GetCanonicalCalleeSaveType(type); - return RoundUp((POPCOUNT(ArmCalleeSaveCoreSpills(type)) /* gprs */ + - POPCOUNT(ArmCalleeSaveFpSpills(type)) /* fprs */ + - 1 /* Method* */) * static_cast<size_t>(kArmPointerSize), kStackAlignment); -} + static constexpr uint32_t GetFrameSize(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return RoundUp((POPCOUNT(GetCoreSpills(type)) /* gprs */ + + POPCOUNT(GetFpSpills(type)) /* fprs */ + + 1 /* Method* */) * static_cast<size_t>(kArmPointerSize), kStackAlignment); + } -constexpr QuickMethodFrameInfo ArmCalleeSaveMethodFrameInfo(CalleeSaveType type) { - type = GetCanonicalCalleeSaveType(type); - return QuickMethodFrameInfo(ArmCalleeSaveFrameSize(type), - ArmCalleeSaveCoreSpills(type), - ArmCalleeSaveFpSpills(type)); -} + static constexpr QuickMethodFrameInfo GetMethodFrameInfo(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return QuickMethodFrameInfo(GetFrameSize(type), GetCoreSpills(type), GetFpSpills(type)); + } -constexpr size_t ArmCalleeSaveFpr1Offset(CalleeSaveType type) { - type = GetCanonicalCalleeSaveType(type); - return ArmCalleeSaveFrameSize(type) - - (POPCOUNT(ArmCalleeSaveCoreSpills(type)) + - POPCOUNT(ArmCalleeSaveFpSpills(type))) * static_cast<size_t>(kArmPointerSize); -} + static constexpr size_t GetFpr1Offset(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return GetFrameSize(type) - + (POPCOUNT(GetCoreSpills(type)) + + POPCOUNT(GetFpSpills(type))) * static_cast<size_t>(kArmPointerSize); + } -constexpr size_t ArmCalleeSaveGpr1Offset(CalleeSaveType type) { - type = GetCanonicalCalleeSaveType(type); - return ArmCalleeSaveFrameSize(type) - - POPCOUNT(ArmCalleeSaveCoreSpills(type)) * static_cast<size_t>(kArmPointerSize); -} + static constexpr size_t GetGpr1Offset(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return GetFrameSize(type) - + POPCOUNT(GetCoreSpills(type)) * static_cast<size_t>(kArmPointerSize); + } -constexpr size_t ArmCalleeSaveLrOffset(CalleeSaveType type) { - type = GetCanonicalCalleeSaveType(type); - return ArmCalleeSaveFrameSize(type) - - POPCOUNT(ArmCalleeSaveCoreSpills(type) & (-(1 << LR))) * static_cast<size_t>(kArmPointerSize); -} + static constexpr size_t GetReturnPcOffset(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return GetFrameSize(type) - static_cast<size_t>(kArmPointerSize); + } +}; } // namespace arm } // namespace art -#endif // ART_RUNTIME_ARCH_ARM_QUICK_METHOD_FRAME_INFO_ARM_H_ +#endif // ART_RUNTIME_ARCH_ARM_CALLEE_SAVE_FRAME_ARM_H_ diff --git a/runtime/arch/arm64/quick_method_frame_info_arm64.h b/runtime/arch/arm64/callee_save_frame_arm64.h index 2d2b500ae9..bc36bfabec 100644 --- a/runtime/arch/arm64/quick_method_frame_info_arm64.h +++ b/runtime/arch/arm64/callee_save_frame_arm64.h @@ -14,8 +14,8 @@ * limitations under the License. */ -#ifndef ART_RUNTIME_ARCH_ARM64_QUICK_METHOD_FRAME_INFO_ARM64_H_ -#define ART_RUNTIME_ARCH_ARM64_QUICK_METHOD_FRAME_INFO_ARM64_H_ +#ifndef ART_RUNTIME_ARCH_ARM64_CALLEE_SAVE_FRAME_ARM64_H_ +#define ART_RUNTIME_ARCH_ARM64_CALLEE_SAVE_FRAME_ARM64_H_ #include "arch/instruction_set.h" #include "base/bit_utils.h" @@ -79,57 +79,56 @@ static constexpr uint32_t kArm64CalleeSaveFpEverythingSpills = (1 << art::arm64::D27) | (1 << art::arm64::D28) | (1 << art::arm64::D29) | (1 << art::arm64::D30) | (1 << art::arm64::D31); -constexpr uint32_t Arm64CalleeSaveCoreSpills(CalleeSaveType type) { - type = GetCanonicalCalleeSaveType(type); - return kArm64CalleeSaveAlwaysSpills | kArm64CalleeSaveRefSpills | - (type == CalleeSaveType::kSaveRefsAndArgs ? kArm64CalleeSaveArgSpills : 0) | - (type == CalleeSaveType::kSaveAllCalleeSaves ? kArm64CalleeSaveAllSpills : 0) | - (type == CalleeSaveType::kSaveEverything ? kArm64CalleeSaveEverythingSpills : 0); -} +class Arm64CalleeSaveFrame { + public: + static constexpr uint32_t GetCoreSpills(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return kArm64CalleeSaveAlwaysSpills | kArm64CalleeSaveRefSpills | + (type == CalleeSaveType::kSaveRefsAndArgs ? kArm64CalleeSaveArgSpills : 0) | + (type == CalleeSaveType::kSaveAllCalleeSaves ? kArm64CalleeSaveAllSpills : 0) | + (type == CalleeSaveType::kSaveEverything ? kArm64CalleeSaveEverythingSpills : 0); + } -constexpr uint32_t Arm64CalleeSaveFpSpills(CalleeSaveType type) { - type = GetCanonicalCalleeSaveType(type); - return kArm64CalleeSaveFpAlwaysSpills | kArm64CalleeSaveFpRefSpills | - (type == CalleeSaveType::kSaveRefsAndArgs ? kArm64CalleeSaveFpArgSpills : 0) | - (type == CalleeSaveType::kSaveAllCalleeSaves ? kArm64CalleeSaveFpAllSpills : 0) | - (type == CalleeSaveType::kSaveEverything ? kArm64CalleeSaveFpEverythingSpills : 0); -} + static constexpr uint32_t GetFpSpills(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return kArm64CalleeSaveFpAlwaysSpills | kArm64CalleeSaveFpRefSpills | + (type == CalleeSaveType::kSaveRefsAndArgs ? kArm64CalleeSaveFpArgSpills : 0) | + (type == CalleeSaveType::kSaveAllCalleeSaves ? kArm64CalleeSaveFpAllSpills : 0) | + (type == CalleeSaveType::kSaveEverything ? kArm64CalleeSaveFpEverythingSpills : 0); + } -constexpr uint32_t Arm64CalleeSaveFrameSize(CalleeSaveType type) { - type = GetCanonicalCalleeSaveType(type); - return RoundUp((POPCOUNT(Arm64CalleeSaveCoreSpills(type)) /* gprs */ + - POPCOUNT(Arm64CalleeSaveFpSpills(type)) /* fprs */ + - 1 /* Method* */) * static_cast<size_t>(kArm64PointerSize), kStackAlignment); -} + static constexpr uint32_t GetFrameSize(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return RoundUp((POPCOUNT(GetCoreSpills(type)) /* gprs */ + + POPCOUNT(GetFpSpills(type)) /* fprs */ + + 1 /* Method* */) * static_cast<size_t>(kArm64PointerSize), kStackAlignment); + } -constexpr QuickMethodFrameInfo Arm64CalleeSaveMethodFrameInfo(CalleeSaveType type) { - type = GetCanonicalCalleeSaveType(type); - return QuickMethodFrameInfo(Arm64CalleeSaveFrameSize(type), - Arm64CalleeSaveCoreSpills(type), - Arm64CalleeSaveFpSpills(type)); -} + static constexpr QuickMethodFrameInfo GetMethodFrameInfo(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return QuickMethodFrameInfo(GetFrameSize(type), GetCoreSpills(type), GetFpSpills(type)); + } -constexpr size_t Arm64CalleeSaveFpr1Offset(CalleeSaveType type) { - type = GetCanonicalCalleeSaveType(type); - return Arm64CalleeSaveFrameSize(type) - - (POPCOUNT(Arm64CalleeSaveCoreSpills(type)) + - POPCOUNT(Arm64CalleeSaveFpSpills(type))) * static_cast<size_t>(kArm64PointerSize); -} + static constexpr size_t GetFpr1Offset(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return GetFrameSize(type) - + (POPCOUNT(GetCoreSpills(type)) + + POPCOUNT(GetFpSpills(type))) * static_cast<size_t>(kArm64PointerSize); + } -constexpr size_t Arm64CalleeSaveGpr1Offset(CalleeSaveType type) { - type = GetCanonicalCalleeSaveType(type); - return Arm64CalleeSaveFrameSize(type) - - POPCOUNT(Arm64CalleeSaveCoreSpills(type)) * static_cast<size_t>(kArm64PointerSize); -} + static constexpr size_t GetGpr1Offset(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return GetFrameSize(type) - + POPCOUNT(GetCoreSpills(type)) * static_cast<size_t>(kArm64PointerSize); + } -constexpr size_t Arm64CalleeSaveLrOffset(CalleeSaveType type) { - type = GetCanonicalCalleeSaveType(type); - return Arm64CalleeSaveFrameSize(type) - - POPCOUNT(Arm64CalleeSaveCoreSpills(type) & (-(1 << LR))) * - static_cast<size_t>(kArm64PointerSize); -} + static constexpr size_t GetReturnPcOffset(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return GetFrameSize(type) - static_cast<size_t>(kArm64PointerSize); + } +}; } // namespace arm64 } // namespace art -#endif // ART_RUNTIME_ARCH_ARM64_QUICK_METHOD_FRAME_INFO_ARM64_H_ +#endif // ART_RUNTIME_ARCH_ARM64_CALLEE_SAVE_FRAME_ARM64_H_ diff --git a/runtime/arch/mips/quick_method_frame_info_mips.h b/runtime/arch/mips/callee_save_frame_mips.h index 8c86252152..6e88d08432 100644 --- a/runtime/arch/mips/quick_method_frame_info_mips.h +++ b/runtime/arch/mips/callee_save_frame_mips.h @@ -14,13 +14,14 @@ * limitations under the License. */ -#ifndef ART_RUNTIME_ARCH_MIPS_QUICK_METHOD_FRAME_INFO_MIPS_H_ -#define ART_RUNTIME_ARCH_MIPS_QUICK_METHOD_FRAME_INFO_MIPS_H_ +#ifndef ART_RUNTIME_ARCH_MIPS_CALLEE_SAVE_FRAME_MIPS_H_ +#define ART_RUNTIME_ARCH_MIPS_CALLEE_SAVE_FRAME_MIPS_H_ #include "arch/instruction_set.h" #include "base/bit_utils.h" #include "base/callee_save_type.h" #include "base/enums.h" +#include "base/globals.h" #include "quick/quick_method_frame_info.h" #include "registers_mips.h" @@ -80,37 +81,56 @@ static constexpr uint32_t kMipsCalleeSaveFpEverythingSpills = (1 << art::mips::F24) | (1 << art::mips::F25) | (1 << art::mips::F26) | (1 << art::mips::F27) | (1 << art::mips::F28) | (1 << art::mips::F29) | (1 << art::mips::F30) | (1u << art::mips::F31); -constexpr uint32_t MipsCalleeSaveCoreSpills(CalleeSaveType type) { - type = GetCanonicalCalleeSaveType(type); - return kMipsCalleeSaveAlwaysSpills | kMipsCalleeSaveRefSpills | - (type == CalleeSaveType::kSaveRefsAndArgs ? kMipsCalleeSaveArgSpills : 0) | - (type == CalleeSaveType::kSaveAllCalleeSaves ? kMipsCalleeSaveAllSpills : 0) | - (type == CalleeSaveType::kSaveEverything ? kMipsCalleeSaveEverythingSpills : 0); -} +class MipsCalleeSaveFrame { + public: + static constexpr uint32_t GetCoreSpills(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return kMipsCalleeSaveAlwaysSpills | kMipsCalleeSaveRefSpills | + (type == CalleeSaveType::kSaveRefsAndArgs ? kMipsCalleeSaveArgSpills : 0) | + (type == CalleeSaveType::kSaveAllCalleeSaves ? kMipsCalleeSaveAllSpills : 0) | + (type == CalleeSaveType::kSaveEverything ? kMipsCalleeSaveEverythingSpills : 0); + } -constexpr uint32_t MipsCalleeSaveFPSpills(CalleeSaveType type) { - type = GetCanonicalCalleeSaveType(type); - return kMipsCalleeSaveFpAlwaysSpills | kMipsCalleeSaveFpRefSpills | - (type == CalleeSaveType::kSaveRefsAndArgs ? kMipsCalleeSaveFpArgSpills : 0) | - (type == CalleeSaveType::kSaveAllCalleeSaves ? kMipsCalleeSaveAllFPSpills : 0) | - (type == CalleeSaveType::kSaveEverything ? kMipsCalleeSaveFpEverythingSpills : 0); -} + static constexpr uint32_t GetFpSpills(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return kMipsCalleeSaveFpAlwaysSpills | kMipsCalleeSaveFpRefSpills | + (type == CalleeSaveType::kSaveRefsAndArgs ? kMipsCalleeSaveFpArgSpills : 0) | + (type == CalleeSaveType::kSaveAllCalleeSaves ? kMipsCalleeSaveAllFPSpills : 0) | + (type == CalleeSaveType::kSaveEverything ? kMipsCalleeSaveFpEverythingSpills : 0); + } -constexpr uint32_t MipsCalleeSaveFrameSize(CalleeSaveType type) { - type = GetCanonicalCalleeSaveType(type); - return RoundUp((POPCOUNT(MipsCalleeSaveCoreSpills(type)) /* gprs */ + - POPCOUNT(MipsCalleeSaveFPSpills(type)) /* fprs */ + - 1 /* Method* */) * static_cast<size_t>(kMipsPointerSize), kStackAlignment); -} + static constexpr uint32_t GetFrameSize(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return RoundUp((POPCOUNT(GetCoreSpills(type)) /* gprs */ + + POPCOUNT(GetFpSpills(type)) /* fprs */ + + 1 /* Method* */) * static_cast<size_t>(kMipsPointerSize), kStackAlignment); + } -constexpr QuickMethodFrameInfo MipsCalleeSaveMethodFrameInfo(CalleeSaveType type) { - type = GetCanonicalCalleeSaveType(type); - return QuickMethodFrameInfo(MipsCalleeSaveFrameSize(type), - MipsCalleeSaveCoreSpills(type), - MipsCalleeSaveFPSpills(type)); -} + static constexpr QuickMethodFrameInfo GetMethodFrameInfo(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return QuickMethodFrameInfo(GetFrameSize(type), GetCoreSpills(type), GetFpSpills(type)); + } + + static constexpr size_t GetFpr1Offset(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return GetFrameSize(type) - + (POPCOUNT(GetCoreSpills(type)) + + POPCOUNT(GetFpSpills(type))) * static_cast<size_t>(kMipsPointerSize); + } + + static constexpr size_t GetGpr1Offset(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return GetFrameSize(type) - + POPCOUNT(GetCoreSpills(type)) * static_cast<size_t>(kMipsPointerSize); + } + + static constexpr size_t GetReturnPcOffset(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return GetFrameSize(type) - static_cast<size_t>(kMipsPointerSize); + } +}; } // namespace mips } // namespace art -#endif // ART_RUNTIME_ARCH_MIPS_QUICK_METHOD_FRAME_INFO_MIPS_H_ +#endif // ART_RUNTIME_ARCH_MIPS_CALLEE_SAVE_FRAME_MIPS_H_ diff --git a/runtime/arch/mips/fault_handler_mips.cc b/runtime/arch/mips/fault_handler_mips.cc index d5a9b1589e..7c8ac288c3 100644 --- a/runtime/arch/mips/fault_handler_mips.cc +++ b/runtime/arch/mips/fault_handler_mips.cc @@ -17,13 +17,13 @@ #include <sys/ucontext.h> #include "fault_handler.h" +#include "arch/mips/callee_save_frame_mips.h" #include "art_method.h" #include "base/callee_save_type.h" #include "base/globals.h" #include "base/hex_dump.h" #include "base/logging.h" // For VLOG. #include "base/macros.h" -#include "quick_method_frame_info_mips.h" #include "registers_mips.h" #include "thread-current-inl.h" diff --git a/runtime/arch/mips64/quick_method_frame_info_mips64.h b/runtime/arch/mips64/callee_save_frame_mips64.h index 520f6319d5..59529a0c7b 100644 --- a/runtime/arch/mips64/quick_method_frame_info_mips64.h +++ b/runtime/arch/mips64/callee_save_frame_mips64.h @@ -14,13 +14,14 @@ * limitations under the License. */ -#ifndef ART_RUNTIME_ARCH_MIPS64_QUICK_METHOD_FRAME_INFO_MIPS64_H_ -#define ART_RUNTIME_ARCH_MIPS64_QUICK_METHOD_FRAME_INFO_MIPS64_H_ +#ifndef ART_RUNTIME_ARCH_MIPS64_CALLEE_SAVE_FRAME_MIPS64_H_ +#define ART_RUNTIME_ARCH_MIPS64_CALLEE_SAVE_FRAME_MIPS64_H_ #include "arch/instruction_set.h" #include "base/bit_utils.h" #include "base/callee_save_type.h" #include "base/enums.h" +#include "base/globals.h" #include "quick/quick_method_frame_info.h" #include "registers_mips64.h" @@ -71,37 +72,56 @@ static constexpr uint32_t kMips64CalleeSaveFpEverythingSpills = (1 << art::mips64::F27) | (1 << art::mips64::F28) | (1 << art::mips64::F29) | (1 << art::mips64::F30) | (1 << art::mips64::F31); -constexpr uint32_t Mips64CalleeSaveCoreSpills(CalleeSaveType type) { - type = GetCanonicalCalleeSaveType(type); - return kMips64CalleeSaveAlwaysSpills | kMips64CalleeSaveRefSpills | - (type == CalleeSaveType::kSaveRefsAndArgs ? kMips64CalleeSaveArgSpills : 0) | - (type == CalleeSaveType::kSaveAllCalleeSaves ? kMips64CalleeSaveAllSpills : 0) | - (type == CalleeSaveType::kSaveEverything ? kMips64CalleeSaveEverythingSpills : 0); -} +class Mips64CalleeSaveFrame { + public: + static constexpr uint32_t GetCoreSpills(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return kMips64CalleeSaveAlwaysSpills | kMips64CalleeSaveRefSpills | + (type == CalleeSaveType::kSaveRefsAndArgs ? kMips64CalleeSaveArgSpills : 0) | + (type == CalleeSaveType::kSaveAllCalleeSaves ? kMips64CalleeSaveAllSpills : 0) | + (type == CalleeSaveType::kSaveEverything ? kMips64CalleeSaveEverythingSpills : 0); + } -constexpr uint32_t Mips64CalleeSaveFpSpills(CalleeSaveType type) { - type = GetCanonicalCalleeSaveType(type); - return kMips64CalleeSaveFpRefSpills | - (type == CalleeSaveType::kSaveRefsAndArgs ? kMips64CalleeSaveFpArgSpills : 0) | - (type == CalleeSaveType::kSaveAllCalleeSaves ? kMips64CalleeSaveFpAllSpills : 0) | - (type == CalleeSaveType::kSaveEverything ? kMips64CalleeSaveFpEverythingSpills : 0); -} + static constexpr uint32_t GetFpSpills(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return kMips64CalleeSaveFpRefSpills | + (type == CalleeSaveType::kSaveRefsAndArgs ? kMips64CalleeSaveFpArgSpills : 0) | + (type == CalleeSaveType::kSaveAllCalleeSaves ? kMips64CalleeSaveFpAllSpills : 0) | + (type == CalleeSaveType::kSaveEverything ? kMips64CalleeSaveFpEverythingSpills : 0); + } -constexpr uint32_t Mips64CalleeSaveFrameSize(CalleeSaveType type) { - type = GetCanonicalCalleeSaveType(type); - return RoundUp((POPCOUNT(Mips64CalleeSaveCoreSpills(type)) /* gprs */ + - POPCOUNT(Mips64CalleeSaveFpSpills(type)) /* fprs */ + - + 1 /* Method* */) * static_cast<size_t>(kMips64PointerSize), kStackAlignment); -} + static constexpr uint32_t GetFrameSize(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return RoundUp((POPCOUNT(GetCoreSpills(type)) /* gprs */ + + POPCOUNT(GetFpSpills(type)) /* fprs */ + + + 1 /* Method* */) * static_cast<size_t>(kMips64PointerSize), kStackAlignment); + } -constexpr QuickMethodFrameInfo Mips64CalleeSaveMethodFrameInfo(CalleeSaveType type) { - type = GetCanonicalCalleeSaveType(type); - return QuickMethodFrameInfo(Mips64CalleeSaveFrameSize(type), - Mips64CalleeSaveCoreSpills(type), - Mips64CalleeSaveFpSpills(type)); -} + static constexpr QuickMethodFrameInfo GetMethodFrameInfo(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return QuickMethodFrameInfo(GetFrameSize(type), GetCoreSpills(type), GetFpSpills(type)); + } + + static constexpr size_t GetFpr1Offset(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return GetFrameSize(type) - + (POPCOUNT(GetCoreSpills(type)) + + POPCOUNT(GetFpSpills(type))) * static_cast<size_t>(kMips64PointerSize); + } + + static constexpr size_t GetGpr1Offset(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return GetFrameSize(type) - + POPCOUNT(GetCoreSpills(type)) * static_cast<size_t>(kMips64PointerSize); + } + + static constexpr size_t GetReturnPcOffset(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return GetFrameSize(type) - static_cast<size_t>(kMips64PointerSize); + } +}; } // namespace mips64 } // namespace art -#endif // ART_RUNTIME_ARCH_MIPS64_QUICK_METHOD_FRAME_INFO_MIPS64_H_ +#endif // ART_RUNTIME_ARCH_MIPS64_CALLEE_SAVE_FRAME_MIPS64_H_ diff --git a/runtime/arch/mips64/fault_handler_mips64.cc b/runtime/arch/mips64/fault_handler_mips64.cc index 695da4794b..85f3528ec4 100644 --- a/runtime/arch/mips64/fault_handler_mips64.cc +++ b/runtime/arch/mips64/fault_handler_mips64.cc @@ -18,13 +18,13 @@ #include <sys/ucontext.h> +#include "arch/mips64/callee_save_frame_mips64.h" #include "art_method.h" #include "base/callee_save_type.h" #include "base/globals.h" #include "base/hex_dump.h" #include "base/logging.h" // For VLOG. #include "base/macros.h" -#include "quick_method_frame_info_mips64.h" #include "registers_mips64.h" #include "thread-current-inl.h" diff --git a/runtime/arch/x86/callee_save_frame_x86.h b/runtime/arch/x86/callee_save_frame_x86.h new file mode 100644 index 0000000000..f336f43aa3 --- /dev/null +++ b/runtime/arch/x86/callee_save_frame_x86.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_RUNTIME_ARCH_X86_CALLEE_SAVE_FRAME_X86_H_ +#define ART_RUNTIME_ARCH_X86_CALLEE_SAVE_FRAME_X86_H_ + +#include "arch/instruction_set.h" +#include "base/bit_utils.h" +#include "base/callee_save_type.h" +#include "base/enums.h" +#include "base/globals.h" +#include "quick/quick_method_frame_info.h" +#include "registers_x86.h" + +namespace art { +namespace x86 { + +static constexpr uint32_t kX86CalleeSaveAlwaysSpills = + (1 << art::x86::kNumberOfCpuRegisters); // Fake return address callee save. +static constexpr uint32_t kX86CalleeSaveRefSpills = + (1 << art::x86::EBP) | (1 << art::x86::ESI) | (1 << art::x86::EDI); +static constexpr uint32_t kX86CalleeSaveArgSpills = + (1 << art::x86::ECX) | (1 << art::x86::EDX) | (1 << art::x86::EBX); +static constexpr uint32_t kX86CalleeSaveEverythingSpills = + (1 << art::x86::EAX) | (1 << art::x86::ECX) | (1 << art::x86::EDX) | (1 << art::x86::EBX); + +static constexpr uint32_t kX86CalleeSaveFpArgSpills = + (1 << art::x86::XMM0) | (1 << art::x86::XMM1) | + (1 << art::x86::XMM2) | (1 << art::x86::XMM3); +static constexpr uint32_t kX86CalleeSaveFpEverythingSpills = + (1 << art::x86::XMM0) | (1 << art::x86::XMM1) | + (1 << art::x86::XMM2) | (1 << art::x86::XMM3) | + (1 << art::x86::XMM4) | (1 << art::x86::XMM5) | + (1 << art::x86::XMM6) | (1 << art::x86::XMM7); + +class X86CalleeSaveFrame { + public: + static constexpr uint32_t GetCoreSpills(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return kX86CalleeSaveAlwaysSpills | kX86CalleeSaveRefSpills | + (type == CalleeSaveType::kSaveRefsAndArgs ? kX86CalleeSaveArgSpills : 0) | + (type == CalleeSaveType::kSaveEverything ? kX86CalleeSaveEverythingSpills : 0); + } + + static constexpr uint32_t GetFpSpills(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return (type == CalleeSaveType::kSaveRefsAndArgs ? kX86CalleeSaveFpArgSpills : 0) | + (type == CalleeSaveType::kSaveEverything ? kX86CalleeSaveFpEverythingSpills : 0); + } + + static constexpr uint32_t GetFrameSize(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return RoundUp((POPCOUNT(GetCoreSpills(type)) /* gprs */ + + 2 * POPCOUNT(GetFpSpills(type)) /* fprs */ + + 1 /* Method* */) * static_cast<size_t>(kX86PointerSize), kStackAlignment); + } + + static constexpr QuickMethodFrameInfo GetMethodFrameInfo(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return QuickMethodFrameInfo(GetFrameSize(type), GetCoreSpills(type), GetFpSpills(type)); + } + + static constexpr size_t GetFpr1Offset(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return GetFrameSize(type) - + (POPCOUNT(GetCoreSpills(type)) + + 2 * POPCOUNT(GetFpSpills(type))) * static_cast<size_t>(kX86PointerSize); + } + + static constexpr size_t GetGpr1Offset(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return GetFrameSize(type) - + POPCOUNT(GetCoreSpills(type)) * static_cast<size_t>(kX86PointerSize); + } + + static constexpr size_t GetReturnPcOffset(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return GetFrameSize(type) - static_cast<size_t>(kX86PointerSize); + } +}; + +} // namespace x86 +} // namespace art + +#endif // ART_RUNTIME_ARCH_X86_CALLEE_SAVE_FRAME_X86_H_ diff --git a/runtime/arch/x86/quick_method_frame_info_x86.h b/runtime/arch/x86/quick_method_frame_info_x86.h deleted file mode 100644 index 9a6633365c..0000000000 --- a/runtime/arch/x86/quick_method_frame_info_x86.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ART_RUNTIME_ARCH_X86_QUICK_METHOD_FRAME_INFO_X86_H_ -#define ART_RUNTIME_ARCH_X86_QUICK_METHOD_FRAME_INFO_X86_H_ - -#include "arch/instruction_set.h" -#include "base/bit_utils.h" -#include "base/callee_save_type.h" -#include "base/enums.h" -#include "quick/quick_method_frame_info.h" -#include "registers_x86.h" - -namespace art { -namespace x86 { - -enum XMM { - XMM0 = 0, - XMM1 = 1, - XMM2 = 2, - XMM3 = 3, - XMM4 = 4, - XMM5 = 5, - XMM6 = 6, - XMM7 = 7, -}; - -static constexpr uint32_t kX86CalleeSaveAlwaysSpills = - (1 << art::x86::kNumberOfCpuRegisters); // Fake return address callee save. -static constexpr uint32_t kX86CalleeSaveRefSpills = - (1 << art::x86::EBP) | (1 << art::x86::ESI) | (1 << art::x86::EDI); -static constexpr uint32_t kX86CalleeSaveArgSpills = - (1 << art::x86::ECX) | (1 << art::x86::EDX) | (1 << art::x86::EBX); -static constexpr uint32_t kX86CalleeSaveEverythingSpills = - (1 << art::x86::EAX) | (1 << art::x86::ECX) | (1 << art::x86::EDX) | (1 << art::x86::EBX); - -static constexpr uint32_t kX86CalleeSaveFpArgSpills = - (1 << art::x86::XMM0) | (1 << art::x86::XMM1) | - (1 << art::x86::XMM2) | (1 << art::x86::XMM3); -static constexpr uint32_t kX86CalleeSaveFpEverythingSpills = - (1 << art::x86::XMM0) | (1 << art::x86::XMM1) | - (1 << art::x86::XMM2) | (1 << art::x86::XMM3) | - (1 << art::x86::XMM4) | (1 << art::x86::XMM5) | - (1 << art::x86::XMM6) | (1 << art::x86::XMM7); - -constexpr uint32_t X86CalleeSaveCoreSpills(CalleeSaveType type) { - type = GetCanonicalCalleeSaveType(type); - return kX86CalleeSaveAlwaysSpills | kX86CalleeSaveRefSpills | - (type == CalleeSaveType::kSaveRefsAndArgs ? kX86CalleeSaveArgSpills : 0) | - (type == CalleeSaveType::kSaveEverything ? kX86CalleeSaveEverythingSpills : 0); -} - -constexpr uint32_t X86CalleeSaveFpSpills(CalleeSaveType type) { - type = GetCanonicalCalleeSaveType(type); - return (type == CalleeSaveType::kSaveRefsAndArgs ? kX86CalleeSaveFpArgSpills : 0) | - (type == CalleeSaveType::kSaveEverything ? kX86CalleeSaveFpEverythingSpills : 0); -} - -constexpr uint32_t X86CalleeSaveFrameSize(CalleeSaveType type) { - type = GetCanonicalCalleeSaveType(type); - return RoundUp((POPCOUNT(X86CalleeSaveCoreSpills(type)) /* gprs */ + - 2 * POPCOUNT(X86CalleeSaveFpSpills(type)) /* fprs */ + - 1 /* Method* */) * static_cast<size_t>(kX86PointerSize), kStackAlignment); -} - -constexpr QuickMethodFrameInfo X86CalleeSaveMethodFrameInfo(CalleeSaveType type) { - type = GetCanonicalCalleeSaveType(type); - return QuickMethodFrameInfo(X86CalleeSaveFrameSize(type), - X86CalleeSaveCoreSpills(type), - X86CalleeSaveFpSpills(type)); -} - -} // namespace x86 -} // namespace art - -#endif // ART_RUNTIME_ARCH_X86_QUICK_METHOD_FRAME_INFO_X86_H_ diff --git a/runtime/arch/x86/registers_x86.h b/runtime/arch/x86/registers_x86.h index 5a5d226319..d3b959fc53 100644 --- a/runtime/arch/x86/registers_x86.h +++ b/runtime/arch/x86/registers_x86.h @@ -42,6 +42,20 @@ enum Register { }; std::ostream& operator<<(std::ostream& os, const Register& rhs); +enum XmmRegister { + XMM0 = 0, + XMM1 = 1, + XMM2 = 2, + XMM3 = 3, + XMM4 = 4, + XMM5 = 5, + XMM6 = 6, + XMM7 = 7, + kNumberOfXmmRegisters = 8, + kNoXmmRegister = -1 // Signals an illegal register. +}; +std::ostream& operator<<(std::ostream& os, const XmmRegister& reg); + } // namespace x86 } // namespace art diff --git a/runtime/arch/x86_64/quick_method_frame_info_x86_64.h b/runtime/arch/x86_64/callee_save_frame_x86_64.h index ebf976ef71..228a902d38 100644 --- a/runtime/arch/x86_64/quick_method_frame_info_x86_64.h +++ b/runtime/arch/x86_64/callee_save_frame_x86_64.h @@ -14,13 +14,14 @@ * limitations under the License. */ -#ifndef ART_RUNTIME_ARCH_X86_64_QUICK_METHOD_FRAME_INFO_X86_64_H_ -#define ART_RUNTIME_ARCH_X86_64_QUICK_METHOD_FRAME_INFO_X86_64_H_ +#ifndef ART_RUNTIME_ARCH_X86_64_CALLEE_SAVE_FRAME_X86_64_H_ +#define ART_RUNTIME_ARCH_X86_64_CALLEE_SAVE_FRAME_X86_64_H_ #include "arch/instruction_set.h" #include "base/bit_utils.h" #include "base/callee_save_type.h" #include "base/enums.h" +#include "base/globals.h" #include "quick/quick_method_frame_info.h" #include "registers_x86_64.h" @@ -55,35 +56,54 @@ static constexpr uint32_t kX86_64CalleeSaveFpEverythingSpills = (1 << art::x86_64::XMM8) | (1 << art::x86_64::XMM9) | (1 << art::x86_64::XMM10) | (1 << art::x86_64::XMM11); -constexpr uint32_t X86_64CalleeSaveCoreSpills(CalleeSaveType type) { - type = GetCanonicalCalleeSaveType(type); - return kX86_64CalleeSaveAlwaysSpills | kX86_64CalleeSaveRefSpills | - (type == CalleeSaveType::kSaveRefsAndArgs ? kX86_64CalleeSaveArgSpills : 0) | - (type == CalleeSaveType::kSaveEverything ? kX86_64CalleeSaveEverythingSpills : 0); -} +class X86_64CalleeSaveFrame { + public: + static constexpr uint32_t GetCoreSpills(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return kX86_64CalleeSaveAlwaysSpills | kX86_64CalleeSaveRefSpills | + (type == CalleeSaveType::kSaveRefsAndArgs ? kX86_64CalleeSaveArgSpills : 0) | + (type == CalleeSaveType::kSaveEverything ? kX86_64CalleeSaveEverythingSpills : 0); + } -constexpr uint32_t X86_64CalleeSaveFpSpills(CalleeSaveType type) { - type = GetCanonicalCalleeSaveType(type); - return kX86_64CalleeSaveFpSpills | - (type == CalleeSaveType::kSaveRefsAndArgs ? kX86_64CalleeSaveFpArgSpills : 0) | - (type == CalleeSaveType::kSaveEverything ? kX86_64CalleeSaveFpEverythingSpills : 0); -} + static constexpr uint32_t GetFpSpills(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return kX86_64CalleeSaveFpSpills | + (type == CalleeSaveType::kSaveRefsAndArgs ? kX86_64CalleeSaveFpArgSpills : 0) | + (type == CalleeSaveType::kSaveEverything ? kX86_64CalleeSaveFpEverythingSpills : 0); + } -constexpr uint32_t X86_64CalleeSaveFrameSize(CalleeSaveType type) { - type = GetCanonicalCalleeSaveType(type); - return RoundUp((POPCOUNT(X86_64CalleeSaveCoreSpills(type)) /* gprs */ + - POPCOUNT(X86_64CalleeSaveFpSpills(type)) /* fprs */ + - 1 /* Method* */) * static_cast<size_t>(kX86_64PointerSize), kStackAlignment); -} + static constexpr uint32_t GetFrameSize(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return RoundUp((POPCOUNT(GetCoreSpills(type)) /* gprs */ + + POPCOUNT(GetFpSpills(type)) /* fprs */ + + 1 /* Method* */) * static_cast<size_t>(kX86_64PointerSize), kStackAlignment); + } -constexpr QuickMethodFrameInfo X86_64CalleeSaveMethodFrameInfo(CalleeSaveType type) { - type = GetCanonicalCalleeSaveType(type); - return QuickMethodFrameInfo(X86_64CalleeSaveFrameSize(type), - X86_64CalleeSaveCoreSpills(type), - X86_64CalleeSaveFpSpills(type)); -} + static constexpr QuickMethodFrameInfo GetMethodFrameInfo(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return QuickMethodFrameInfo(GetFrameSize(type), GetCoreSpills(type), GetFpSpills(type)); + } + + static constexpr size_t GetFpr1Offset(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return GetFrameSize(type) - + (POPCOUNT(GetCoreSpills(type)) + + POPCOUNT(GetFpSpills(type))) * static_cast<size_t>(kX86_64PointerSize); + } + + static constexpr size_t GetGpr1Offset(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return GetFrameSize(type) - + POPCOUNT(GetCoreSpills(type)) * static_cast<size_t>(kX86_64PointerSize); + } + + static constexpr size_t GetReturnPcOffset(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); + return GetFrameSize(type) - static_cast<size_t>(kX86_64PointerSize); + } +}; } // namespace x86_64 } // namespace art -#endif // ART_RUNTIME_ARCH_X86_64_QUICK_METHOD_FRAME_INFO_X86_64_H_ +#endif // ART_RUNTIME_ARCH_X86_64_CALLEE_SAVE_FRAME_X86_64_H_ diff --git a/runtime/entrypoints/entrypoint_utils.cc b/runtime/entrypoints/entrypoint_utils.cc index a58946ae66..7536910cee 100644 --- a/runtime/entrypoints/entrypoint_utils.cc +++ b/runtime/entrypoints/entrypoint_utils.cc @@ -180,10 +180,10 @@ static inline std::pair<ArtMethod*, uintptr_t> DoGetCalleeSaveMethodOuterCallerA ArtMethod** sp, CalleeSaveType type) REQUIRES_SHARED(Locks::mutator_lock_) { DCHECK_EQ(*sp, Runtime::Current()->GetCalleeSaveMethod(type)); - const size_t callee_frame_size = GetCalleeSaveFrameSize(kRuntimeISA, type); + const size_t callee_frame_size = RuntimeCalleeSaveFrame::GetFrameSize(type); auto** caller_sp = reinterpret_cast<ArtMethod**>( reinterpret_cast<uintptr_t>(sp) + callee_frame_size); - const size_t callee_return_pc_offset = GetCalleeSaveReturnPcOffset(kRuntimeISA, type); + const size_t callee_return_pc_offset = RuntimeCalleeSaveFrame::GetReturnPcOffset(type); uintptr_t caller_pc = *reinterpret_cast<uintptr_t*>( (reinterpret_cast<uint8_t*>(sp) + callee_return_pc_offset)); ArtMethod* outer_method = *caller_sp; diff --git a/runtime/entrypoints/quick/callee_save_frame.h b/runtime/entrypoints/quick/callee_save_frame.h index ef27ca325c..6f1bbaa093 100644 --- a/runtime/entrypoints/quick/callee_save_frame.h +++ b/runtime/entrypoints/quick/callee_save_frame.h @@ -21,16 +21,17 @@ #include "base/callee_save_type.h" #include "base/enums.h" #include "base/mutex.h" +#include "quick/quick_method_frame_info.h" #include "thread-inl.h" // Specific frame size code is in architecture-specific files. We include this to compile-time // specialize the code. -#include "arch/arm/quick_method_frame_info_arm.h" -#include "arch/arm64/quick_method_frame_info_arm64.h" -#include "arch/mips/quick_method_frame_info_mips.h" -#include "arch/mips64/quick_method_frame_info_mips64.h" -#include "arch/x86/quick_method_frame_info_x86.h" -#include "arch/x86_64/quick_method_frame_info_x86_64.h" +#include "arch/arm/callee_save_frame_arm.h" +#include "arch/arm64/callee_save_frame_arm64.h" +#include "arch/mips/callee_save_frame_mips.h" +#include "arch/mips64/callee_save_frame_mips64.h" +#include "arch/x86/callee_save_frame_x86.h" +#include "arch/x86_64/callee_save_frame_x86_64.h" namespace art { class ArtMethod; @@ -67,57 +68,28 @@ class ScopedQuickEntrypointChecks { bool exit_check_; }; -static constexpr size_t GetCalleeSaveFrameSize(InstructionSet isa, CalleeSaveType type) { - switch (isa) { - case InstructionSet::kArm: - case InstructionSet::kThumb2: - return arm::ArmCalleeSaveFrameSize(type); - case InstructionSet::kArm64: - return arm64::Arm64CalleeSaveFrameSize(type); - case InstructionSet::kMips: - return mips::MipsCalleeSaveFrameSize(type); - case InstructionSet::kMips64: - return mips64::Mips64CalleeSaveFrameSize(type); - case InstructionSet::kX86: - return x86::X86CalleeSaveFrameSize(type); - case InstructionSet::kX86_64: - return x86_64::X86_64CalleeSaveFrameSize(type); - case InstructionSet::kNone: - LOG(FATAL) << "kNone has no frame size"; - UNREACHABLE(); - } - LOG(FATAL) << "Unknown ISA " << isa; - UNREACHABLE(); -} - -// Note: this specialized statement is sanity-checked in the quick-trampoline gtest. -static constexpr PointerSize GetConstExprPointerSize(InstructionSet isa) { - switch (isa) { - case InstructionSet::kArm: - case InstructionSet::kThumb2: - return kArmPointerSize; - case InstructionSet::kArm64: - return kArm64PointerSize; - case InstructionSet::kMips: - return kMipsPointerSize; - case InstructionSet::kMips64: - return kMips64PointerSize; - case InstructionSet::kX86: - return kX86PointerSize; - case InstructionSet::kX86_64: - return kX86_64PointerSize; - case InstructionSet::kNone: - LOG(FATAL) << "kNone has no pointer size"; - UNREACHABLE(); - } - LOG(FATAL) << "Unknown ISA " << isa; - UNREACHABLE(); -} - -// Note: this specialized statement is sanity-checked in the quick-trampoline gtest. -static constexpr size_t GetCalleeSaveReturnPcOffset(InstructionSet isa, CalleeSaveType type) { - return GetCalleeSaveFrameSize(isa, type) - static_cast<size_t>(GetConstExprPointerSize(isa)); -} +namespace detail_ { + +template <InstructionSet> +struct CSFSelector; // No definition for unspecialized callee save frame selector. + +// Note: kThumb2 is never the kRuntimeISA. +template <> +struct CSFSelector<InstructionSet::kArm> { using type = arm::ArmCalleeSaveFrame; }; +template <> +struct CSFSelector<InstructionSet::kArm64> { using type = arm64::Arm64CalleeSaveFrame; }; +template <> +struct CSFSelector<InstructionSet::kMips> { using type = mips::MipsCalleeSaveFrame; }; +template <> +struct CSFSelector<InstructionSet::kMips64> { using type = mips64::Mips64CalleeSaveFrame; }; +template <> +struct CSFSelector<InstructionSet::kX86> { using type = x86::X86CalleeSaveFrame; }; +template <> +struct CSFSelector<InstructionSet::kX86_64> { using type = x86_64::X86_64CalleeSaveFrame; }; + +} // namespace detail_ + +using RuntimeCalleeSaveFrame = detail_::CSFSelector<kRuntimeISA>::type; } // namespace art diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc index 39429c5b41..d0aec0309d 100644 --- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc @@ -26,6 +26,7 @@ #include "dex/dex_instruction-inl.h" #include "dex/method_reference.h" #include "entrypoints/entrypoint_utils-inl.h" +#include "entrypoints/quick/callee_save_frame.h" #include "entrypoints/runtime_asm_entrypoints.h" #include "gc/accounting/card_table-inl.h" #include "imt_conflict_table.h" @@ -59,7 +60,16 @@ class QuickArgumentVisitor { static constexpr size_t kBytesStackArgLocation = 4; // Frame size in bytes of a callee-save frame for RefsAndArgs. static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_FrameSize = - GetCalleeSaveFrameSize(kRuntimeISA, CalleeSaveType::kSaveRefsAndArgs); + RuntimeCalleeSaveFrame::GetFrameSize(CalleeSaveType::kSaveRefsAndArgs); + // Offset of first GPR arg. + static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_Gpr1Offset = + RuntimeCalleeSaveFrame::GetGpr1Offset(CalleeSaveType::kSaveRefsAndArgs); + // Offset of first FPR arg. + static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_Fpr1Offset = + RuntimeCalleeSaveFrame::GetFpr1Offset(CalleeSaveType::kSaveRefsAndArgs); + // Offset of return address. + static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_ReturnPcOffset = + RuntimeCalleeSaveFrame::GetReturnPcOffset(CalleeSaveType::kSaveRefsAndArgs); #if defined(__arm__) // The callee save frame is pointed to by SP. // | argN | | @@ -87,12 +97,6 @@ class QuickArgumentVisitor { static constexpr size_t kNumQuickGprArgs = 3; static constexpr size_t kNumQuickFprArgs = 16; static constexpr bool kGprFprLockstep = false; - static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_Fpr1Offset = - arm::ArmCalleeSaveFpr1Offset(CalleeSaveType::kSaveRefsAndArgs); // Offset of first FPR arg. - static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_Gpr1Offset = - arm::ArmCalleeSaveGpr1Offset(CalleeSaveType::kSaveRefsAndArgs); // Offset of first GPR arg. - static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_LrOffset = - arm::ArmCalleeSaveLrOffset(CalleeSaveType::kSaveRefsAndArgs); // Offset of return address. static size_t GprIndexToGprOffset(uint32_t gpr_index) { return gpr_index * GetBytesPerGprSpillLocation(kRuntimeISA); } @@ -125,15 +129,6 @@ class QuickArgumentVisitor { static constexpr size_t kNumQuickGprArgs = 7; // 7 arguments passed in GPRs. static constexpr size_t kNumQuickFprArgs = 8; // 8 arguments passed in FPRs. static constexpr bool kGprFprLockstep = false; - // Offset of first FPR arg. - static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_Fpr1Offset = - arm64::Arm64CalleeSaveFpr1Offset(CalleeSaveType::kSaveRefsAndArgs); - // Offset of first GPR arg. - static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_Gpr1Offset = - arm64::Arm64CalleeSaveGpr1Offset(CalleeSaveType::kSaveRefsAndArgs); - // Offset of return address. - static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_LrOffset = - arm64::Arm64CalleeSaveLrOffset(CalleeSaveType::kSaveRefsAndArgs); static size_t GprIndexToGprOffset(uint32_t gpr_index) { return gpr_index * GetBytesPerGprSpillLocation(kRuntimeISA); } @@ -177,9 +172,6 @@ class QuickArgumentVisitor { // passed only in even numbered registers and each // double occupies two registers. static constexpr bool kGprFprLockstep = false; - static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_Fpr1Offset = 8; // Offset of first FPR arg. - static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_Gpr1Offset = 56; // Offset of first GPR arg. - static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_LrOffset = 108; // Offset of return address. static size_t GprIndexToGprOffset(uint32_t gpr_index) { return gpr_index * GetBytesPerGprSpillLocation(kRuntimeISA); } @@ -221,9 +213,6 @@ class QuickArgumentVisitor { static constexpr size_t kNumQuickFprArgs = 7; // 7 arguments passed in FPRs. static constexpr bool kGprFprLockstep = true; - static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_Fpr1Offset = 24; // Offset of first FPR arg (F13). - static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_Gpr1Offset = 80; // Offset of first GPR arg (A1). - static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_LrOffset = 200; // Offset of return address. static size_t GprIndexToGprOffset(uint32_t gpr_index) { return gpr_index * GetBytesPerGprSpillLocation(kRuntimeISA); } @@ -254,9 +243,6 @@ class QuickArgumentVisitor { static constexpr size_t kNumQuickGprArgs = 3; // 3 arguments passed in GPRs. static constexpr size_t kNumQuickFprArgs = 4; // 4 arguments passed in FPRs. static constexpr bool kGprFprLockstep = false; - static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_Fpr1Offset = 4; // Offset of first FPR arg. - static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_Gpr1Offset = 4 + 4*8; // Offset of first GPR arg. - static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_LrOffset = 28 + 4*8; // Offset of return address. static size_t GprIndexToGprOffset(uint32_t gpr_index) { return gpr_index * GetBytesPerGprSpillLocation(kRuntimeISA); } @@ -296,9 +282,6 @@ class QuickArgumentVisitor { static constexpr size_t kNumQuickGprArgs = 5; // 5 arguments passed in GPRs. static constexpr size_t kNumQuickFprArgs = 8; // 8 arguments passed in FPRs. static constexpr bool kGprFprLockstep = false; - static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_Fpr1Offset = 16; // Offset of first FPR arg. - static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_Gpr1Offset = 80 + 4*8; // Offset of first GPR arg. - static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_LrOffset = 168 + 4*8; // Offset of return address. static size_t GprIndexToGprOffset(uint32_t gpr_index) { switch (gpr_index) { case 0: return (4 * GetBytesPerGprSpillLocation(kRuntimeISA)); @@ -345,8 +328,8 @@ class QuickArgumentVisitor { static uint32_t GetCallingDexPc(ArtMethod** sp) REQUIRES_SHARED(Locks::mutator_lock_) { DCHECK((*sp)->IsCalleeSaveMethod()); - const size_t callee_frame_size = GetCalleeSaveFrameSize(kRuntimeISA, - CalleeSaveType::kSaveRefsAndArgs); + constexpr size_t callee_frame_size = + RuntimeCalleeSaveFrame::GetFrameSize(CalleeSaveType::kSaveRefsAndArgs); ArtMethod** caller_sp = reinterpret_cast<ArtMethod**>( reinterpret_cast<uintptr_t>(sp) + callee_frame_size); uintptr_t outer_pc = QuickArgumentVisitor::GetCallingPc(sp); @@ -373,8 +356,8 @@ class QuickArgumentVisitor { static bool GetInvokeType(ArtMethod** sp, InvokeType* invoke_type, uint32_t* dex_method_index) REQUIRES_SHARED(Locks::mutator_lock_) { DCHECK((*sp)->IsCalleeSaveMethod()); - const size_t callee_frame_size = GetCalleeSaveFrameSize(kRuntimeISA, - CalleeSaveType::kSaveRefsAndArgs); + constexpr size_t callee_frame_size = + RuntimeCalleeSaveFrame::GetFrameSize(CalleeSaveType::kSaveRefsAndArgs); ArtMethod** caller_sp = reinterpret_cast<ArtMethod**>( reinterpret_cast<uintptr_t>(sp) + callee_frame_size); uintptr_t outer_pc = QuickArgumentVisitor::GetCallingPc(sp); @@ -398,8 +381,9 @@ class QuickArgumentVisitor { // For the given quick ref and args quick frame, return the caller's PC. static uintptr_t GetCallingPc(ArtMethod** sp) REQUIRES_SHARED(Locks::mutator_lock_) { DCHECK((*sp)->IsCalleeSaveMethod()); - uint8_t* lr = reinterpret_cast<uint8_t*>(sp) + kQuickCalleeSaveFrame_RefAndArgs_LrOffset; - return *reinterpret_cast<uintptr_t*>(lr); + uint8_t* return_adress_spill = + reinterpret_cast<uint8_t*>(sp) + kQuickCalleeSaveFrame_RefAndArgs_ReturnPcOffset; + return *reinterpret_cast<uintptr_t*>(return_adress_spill); } QuickArgumentVisitor(ArtMethod** sp, bool is_static, const char* shorty, @@ -1157,8 +1141,8 @@ extern "C" TwoWordReturn artInstrumentationMethodExitFromCode(Thread* self, CHECK(!self->IsExceptionPending()) << "Enter instrumentation exit stub with pending exception " << self->GetException()->Dump(); // Compute address of return PC and sanity check that it currently holds 0. - size_t return_pc_offset = GetCalleeSaveReturnPcOffset(kRuntimeISA, - CalleeSaveType::kSaveEverything); + constexpr size_t return_pc_offset = + RuntimeCalleeSaveFrame::GetReturnPcOffset(CalleeSaveType::kSaveEverything); uintptr_t* return_pc = reinterpret_cast<uintptr_t*>(reinterpret_cast<uint8_t*>(sp) + return_pc_offset); CHECK_EQ(*return_pc, 0U); @@ -1210,10 +1194,10 @@ static void DumpB74410240DebugData(ArtMethod** sp) REQUIRES_SHARED(Locks::mutato constexpr CalleeSaveType type = CalleeSaveType::kSaveRefsAndArgs; CHECK_EQ(*sp, Runtime::Current()->GetCalleeSaveMethod(type)); - const size_t callee_frame_size = GetCalleeSaveFrameSize(kRuntimeISA, type); + constexpr size_t callee_frame_size = RuntimeCalleeSaveFrame::GetFrameSize(type); auto** caller_sp = reinterpret_cast<ArtMethod**>( reinterpret_cast<uintptr_t>(sp) + callee_frame_size); - const size_t callee_return_pc_offset = GetCalleeSaveReturnPcOffset(kRuntimeISA, type); + constexpr size_t callee_return_pc_offset = RuntimeCalleeSaveFrame::GetReturnPcOffset(type); uintptr_t caller_pc = *reinterpret_cast<uintptr_t*>( (reinterpret_cast<uint8_t*>(sp) + callee_return_pc_offset)); ArtMethod* outer_method = *caller_sp; diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints_test.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints_test.cc index 77b3132bdc..89694e351a 100644 --- a/runtime/entrypoints/quick/quick_trampoline_entrypoints_test.cc +++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints_test.cc @@ -54,15 +54,6 @@ class QuickTrampolineEntrypointsTest : public CommonRuntimeTest { return save_method; } - static void CheckFrameSize(InstructionSet isa, CalleeSaveType type, uint32_t save_size) - NO_THREAD_SAFETY_ANALYSIS { - ArtMethod* save_method = CreateCalleeSaveMethod(isa, type); - QuickMethodFrameInfo frame_info = Runtime::Current()->GetRuntimeMethodFrameInfo(save_method); - EXPECT_EQ(frame_info.FrameSizeInBytes(), save_size) << "Expected and real size differs for " - << type << " core spills=" << std::hex << frame_info.CoreSpillMask() << " fp spills=" - << frame_info.FpSpillMask() << std::dec << " ISA " << isa; - } - static void CheckPCOffset(InstructionSet isa, CalleeSaveType type, size_t pc_offset) NO_THREAD_SAFETY_ANALYSIS { ArtMethod* save_method = CreateCalleeSaveMethod(isa, type); @@ -74,79 +65,36 @@ class QuickTrampolineEntrypointsTest : public CommonRuntimeTest { } }; -// Note: these tests are all runtime tests. They let the Runtime create the corresponding ArtMethod -// and check against it. Technically we know and expect certain values, but the Runtime code is -// not constexpr, so we cannot make this compile-time checks (and I want the Runtime code tested). - -// This test ensures that kQuickCalleeSaveFrame_RefAndArgs_FrameSize is correct. -TEST_F(QuickTrampolineEntrypointsTest, FrameSize) { - // We have to use a define here as the callee_save_frame.h functions are constexpr. -#define CHECK_FRAME_SIZE(isa) \ - CheckFrameSize(isa, \ - CalleeSaveType::kSaveRefsAndArgs, \ - GetCalleeSaveFrameSize(isa, CalleeSaveType::kSaveRefsAndArgs)); \ - CheckFrameSize(isa, \ - CalleeSaveType::kSaveRefsOnly, \ - GetCalleeSaveFrameSize(isa, CalleeSaveType::kSaveRefsOnly)); \ - CheckFrameSize(isa, \ - CalleeSaveType::kSaveAllCalleeSaves, \ - GetCalleeSaveFrameSize(isa, CalleeSaveType::kSaveAllCalleeSaves)); \ - CheckFrameSize(isa, \ - CalleeSaveType::kSaveEverything, \ - GetCalleeSaveFrameSize(isa, CalleeSaveType::kSaveEverything)); \ - CheckFrameSize(isa, \ - CalleeSaveType::kSaveEverythingForClinit, \ - GetCalleeSaveFrameSize(isa, \ - CalleeSaveType::kSaveEverythingForClinit)); \ - CheckFrameSize(isa, \ - CalleeSaveType::kSaveEverythingForSuspendCheck, \ - GetCalleeSaveFrameSize( \ - isa, CalleeSaveType::kSaveEverythingForSuspendCheck)) - - CHECK_FRAME_SIZE(InstructionSet::kArm); - CHECK_FRAME_SIZE(InstructionSet::kArm64); - CHECK_FRAME_SIZE(InstructionSet::kMips); - CHECK_FRAME_SIZE(InstructionSet::kMips64); - CHECK_FRAME_SIZE(InstructionSet::kX86); - CHECK_FRAME_SIZE(InstructionSet::kX86_64); -} - -// This test ensures that GetConstExprPointerSize is correct with respect to -// GetInstructionSetPointerSize. -TEST_F(QuickTrampolineEntrypointsTest, PointerSize) { - EXPECT_EQ(GetInstructionSetPointerSize(InstructionSet::kArm), - GetConstExprPointerSize(InstructionSet::kArm)); - EXPECT_EQ(GetInstructionSetPointerSize(InstructionSet::kArm64), - GetConstExprPointerSize(InstructionSet::kArm64)); - EXPECT_EQ(GetInstructionSetPointerSize(InstructionSet::kMips), - GetConstExprPointerSize(InstructionSet::kMips)); - EXPECT_EQ(GetInstructionSetPointerSize(InstructionSet::kMips64), - GetConstExprPointerSize(InstructionSet::kMips64)); - EXPECT_EQ(GetInstructionSetPointerSize(InstructionSet::kX86), - GetConstExprPointerSize(InstructionSet::kX86)); - EXPECT_EQ(GetInstructionSetPointerSize(InstructionSet::kX86_64), - GetConstExprPointerSize(InstructionSet::kX86_64)); -} - // This test ensures that the constexpr specialization of the return PC offset computation in // GetCalleeSavePCOffset is correct. TEST_F(QuickTrampolineEntrypointsTest, ReturnPC) { // Ensure that the computation in callee_save_frame.h correct. // Note: we can only check against the kRuntimeISA, because the ArtMethod computation uses // sizeof(void*), which is wrong when the target bitwidth is not the same as the host's. - CheckPCOffset(kRuntimeISA, CalleeSaveType::kSaveRefsAndArgs, - GetCalleeSaveReturnPcOffset(kRuntimeISA, CalleeSaveType::kSaveRefsAndArgs)); - CheckPCOffset(kRuntimeISA, CalleeSaveType::kSaveRefsOnly, - GetCalleeSaveReturnPcOffset(kRuntimeISA, CalleeSaveType::kSaveRefsOnly)); - CheckPCOffset(kRuntimeISA, CalleeSaveType::kSaveAllCalleeSaves, - GetCalleeSaveReturnPcOffset(kRuntimeISA, CalleeSaveType::kSaveAllCalleeSaves)); - CheckPCOffset(kRuntimeISA, CalleeSaveType::kSaveEverything, - GetCalleeSaveReturnPcOffset(kRuntimeISA, CalleeSaveType::kSaveEverything)); - CheckPCOffset(kRuntimeISA, CalleeSaveType::kSaveEverythingForClinit, - GetCalleeSaveReturnPcOffset(kRuntimeISA, CalleeSaveType::kSaveEverythingForClinit)); - CheckPCOffset(kRuntimeISA, CalleeSaveType::kSaveEverythingForSuspendCheck, - GetCalleeSaveReturnPcOffset(kRuntimeISA, - CalleeSaveType::kSaveEverythingForSuspendCheck)); + CheckPCOffset( + kRuntimeISA, + CalleeSaveType::kSaveRefsAndArgs, + RuntimeCalleeSaveFrame::GetReturnPcOffset(CalleeSaveType::kSaveRefsAndArgs)); + CheckPCOffset( + kRuntimeISA, + CalleeSaveType::kSaveRefsOnly, + RuntimeCalleeSaveFrame::GetReturnPcOffset(CalleeSaveType::kSaveRefsOnly)); + CheckPCOffset( + kRuntimeISA, + CalleeSaveType::kSaveAllCalleeSaves, + RuntimeCalleeSaveFrame::GetReturnPcOffset(CalleeSaveType::kSaveAllCalleeSaves)); + CheckPCOffset( + kRuntimeISA, + CalleeSaveType::kSaveEverything, + RuntimeCalleeSaveFrame::GetReturnPcOffset(CalleeSaveType::kSaveEverything)); + CheckPCOffset( + kRuntimeISA, + CalleeSaveType::kSaveEverythingForClinit, + RuntimeCalleeSaveFrame::GetReturnPcOffset(CalleeSaveType::kSaveEverythingForClinit)); + CheckPCOffset( + kRuntimeISA, + CalleeSaveType::kSaveEverythingForSuspendCheck, + RuntimeCalleeSaveFrame::GetReturnPcOffset(CalleeSaveType::kSaveEverythingForSuspendCheck)); } } // namespace art diff --git a/runtime/runtime-inl.h b/runtime/runtime-inl.h index 4584351a6a..374591eeb0 100644 --- a/runtime/runtime-inl.h +++ b/runtime/runtime-inl.h @@ -19,8 +19,10 @@ #include "runtime.h" +#include "arch/instruction_set.h" #include "art_method.h" #include "base/callee_save_type.h" +#include "entrypoints/quick/callee_save_frame.h" #include "gc_root-inl.h" #include "obj_ptr-inl.h" @@ -38,21 +40,22 @@ inline mirror::Object* Runtime::GetClearedJniWeakGlobal() { inline QuickMethodFrameInfo Runtime::GetRuntimeMethodFrameInfo(ArtMethod* method) { DCHECK(method != nullptr); + DCHECK_EQ(instruction_set_, kRuntimeISA); // Cannot be imt-conflict-method or resolution-method. DCHECK_NE(method, GetImtConflictMethod()); DCHECK_NE(method, GetResolutionMethod()); // Don't use GetCalleeSaveMethod(), some tests don't set all callee save methods. if (method == GetCalleeSaveMethodUnchecked(CalleeSaveType::kSaveRefsAndArgs)) { - return GetCalleeSaveMethodFrameInfo(CalleeSaveType::kSaveRefsAndArgs); + return RuntimeCalleeSaveFrame::GetMethodFrameInfo(CalleeSaveType::kSaveRefsAndArgs); } else if (method == GetCalleeSaveMethodUnchecked(CalleeSaveType::kSaveAllCalleeSaves)) { - return GetCalleeSaveMethodFrameInfo(CalleeSaveType::kSaveAllCalleeSaves); + return RuntimeCalleeSaveFrame::GetMethodFrameInfo(CalleeSaveType::kSaveAllCalleeSaves); } else if (method == GetCalleeSaveMethodUnchecked(CalleeSaveType::kSaveRefsOnly)) { - return GetCalleeSaveMethodFrameInfo(CalleeSaveType::kSaveRefsOnly); + return RuntimeCalleeSaveFrame::GetMethodFrameInfo(CalleeSaveType::kSaveRefsOnly); } else { DCHECK(method == GetCalleeSaveMethodUnchecked(CalleeSaveType::kSaveEverything) || method == GetCalleeSaveMethodUnchecked(CalleeSaveType::kSaveEverythingForClinit) || method == GetCalleeSaveMethodUnchecked(CalleeSaveType::kSaveEverythingForSuspendCheck)); - return GetCalleeSaveMethodFrameInfo(CalleeSaveType::kSaveEverything); + return RuntimeCalleeSaveFrame::GetMethodFrameInfo(CalleeSaveType::kSaveEverything); } } diff --git a/runtime/runtime.cc b/runtime/runtime.cc index b8775b874f..5d974246ff 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -39,18 +39,12 @@ #include "android-base/strings.h" #include "aot_class_linker.h" -#include "arch/arm/quick_method_frame_info_arm.h" #include "arch/arm/registers_arm.h" -#include "arch/arm64/quick_method_frame_info_arm64.h" #include "arch/arm64/registers_arm64.h" #include "arch/instruction_set_features.h" -#include "arch/mips/quick_method_frame_info_mips.h" #include "arch/mips/registers_mips.h" -#include "arch/mips64/quick_method_frame_info_mips64.h" #include "arch/mips64/registers_mips64.h" -#include "arch/x86/quick_method_frame_info_x86.h" #include "arch/x86/registers_x86.h" -#include "arch/x86_64/quick_method_frame_info_x86_64.h" #include "arch/x86_64/registers_x86_64.h" #include "art_field-inl.h" #include "art_method-inl.h" @@ -2203,38 +2197,21 @@ void Runtime::BroadcastForNewSystemWeaks(bool broadcast_for_checkpoint) { void Runtime::SetInstructionSet(InstructionSet instruction_set) { instruction_set_ = instruction_set; - if ((instruction_set_ == InstructionSet::kThumb2) || (instruction_set_ == InstructionSet::kArm)) { - for (int i = 0; i != kCalleeSaveSize; ++i) { - CalleeSaveType type = static_cast<CalleeSaveType>(i); - callee_save_method_frame_infos_[i] = arm::ArmCalleeSaveMethodFrameInfo(type); - } - } else if (instruction_set_ == InstructionSet::kMips) { - for (int i = 0; i != kCalleeSaveSize; ++i) { - CalleeSaveType type = static_cast<CalleeSaveType>(i); - callee_save_method_frame_infos_[i] = mips::MipsCalleeSaveMethodFrameInfo(type); - } - } else if (instruction_set_ == InstructionSet::kMips64) { - for (int i = 0; i != kCalleeSaveSize; ++i) { - CalleeSaveType type = static_cast<CalleeSaveType>(i); - callee_save_method_frame_infos_[i] = mips64::Mips64CalleeSaveMethodFrameInfo(type); - } - } else if (instruction_set_ == InstructionSet::kX86) { - for (int i = 0; i != kCalleeSaveSize; ++i) { - CalleeSaveType type = static_cast<CalleeSaveType>(i); - callee_save_method_frame_infos_[i] = x86::X86CalleeSaveMethodFrameInfo(type); - } - } else if (instruction_set_ == InstructionSet::kX86_64) { - for (int i = 0; i != kCalleeSaveSize; ++i) { - CalleeSaveType type = static_cast<CalleeSaveType>(i); - callee_save_method_frame_infos_[i] = x86_64::X86_64CalleeSaveMethodFrameInfo(type); - } - } else if (instruction_set_ == InstructionSet::kArm64) { - for (int i = 0; i != kCalleeSaveSize; ++i) { - CalleeSaveType type = static_cast<CalleeSaveType>(i); - callee_save_method_frame_infos_[i] = arm64::Arm64CalleeSaveMethodFrameInfo(type); - } - } else { - UNIMPLEMENTED(FATAL) << instruction_set_; + switch (instruction_set) { + case InstructionSet::kThumb2: + // kThumb2 is the same as kArm, use the canonical value. + instruction_set_ = InstructionSet::kArm; + break; + case InstructionSet::kArm: + case InstructionSet::kArm64: + case InstructionSet::kMips: + case InstructionSet::kMips64: + case InstructionSet::kX86: + case InstructionSet::kX86_64: + break; + default: + UNIMPLEMENTED(FATAL) << instruction_set_; + UNREACHABLE(); } } diff --git a/runtime/runtime.h b/runtime/runtime.h index 953acbb948..10f72e7c5b 100644 --- a/runtime/runtime.h +++ b/runtime/runtime.h @@ -399,10 +399,6 @@ class Runtime { ArtMethod* GetCalleeSaveMethodUnchecked(CalleeSaveType type) REQUIRES_SHARED(Locks::mutator_lock_); - QuickMethodFrameInfo GetCalleeSaveMethodFrameInfo(CalleeSaveType type) const { - return callee_save_method_frame_infos_[static_cast<size_t>(type)]; - } - QuickMethodFrameInfo GetRuntimeMethodFrameInfo(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_); @@ -831,7 +827,6 @@ class Runtime { GcRoot<mirror::Object> sentinel_; InstructionSet instruction_set_; - QuickMethodFrameInfo callee_save_method_frame_infos_[kCalleeSaveSize]; CompilerCallbacks* compiler_callbacks_; bool is_zygote_; diff --git a/runtime/stack.cc b/runtime/stack.cc index 229238e0f7..c58380dee2 100644 --- a/runtime/stack.cc +++ b/runtime/stack.cc @@ -25,6 +25,7 @@ #include "base/hex_dump.h" #include "dex/dex_file_types.h" #include "entrypoints/entrypoint_utils-inl.h" +#include "entrypoints/quick/callee_save_frame.h" #include "entrypoints/runtime_asm_entrypoints.h" #include "gc/space/image_space.h" #include "gc/space/space-inl.h" @@ -718,7 +719,7 @@ QuickMethodFrameInfo StackVisitor::GetCurrentQuickFrameInfo() const { Runtime* runtime = Runtime::Current(); if (method->IsAbstract()) { - return runtime->GetCalleeSaveMethodFrameInfo(CalleeSaveType::kSaveRefsAndArgs); + return RuntimeCalleeSaveFrame::GetMethodFrameInfo(CalleeSaveType::kSaveRefsAndArgs); } // This goes before IsProxyMethod since runtime methods have a null declaring class. @@ -732,7 +733,7 @@ QuickMethodFrameInfo StackVisitor::GetCurrentQuickFrameInfo() const { // compiled method without any stubs. Therefore the method must have a OatQuickMethodHeader. DCHECK(!method->IsDirect() && !method->IsConstructor()) << "Constructors of proxy classes must have a OatQuickMethodHeader"; - return runtime->GetCalleeSaveMethodFrameInfo(CalleeSaveType::kSaveRefsAndArgs); + return RuntimeCalleeSaveFrame::GetMethodFrameInfo(CalleeSaveType::kSaveRefsAndArgs); } // The only remaining case is if the method is native and uses the generic JNI stub, @@ -751,8 +752,8 @@ QuickMethodFrameInfo StackVisitor::GetCurrentQuickFrameInfo() const { // Generic JNI frame. uint32_t handle_refs = GetNumberOfReferenceArgsWithoutReceiver(method) + 1; size_t scope_size = HandleScope::SizeOf(handle_refs); - QuickMethodFrameInfo callee_info = - runtime->GetCalleeSaveMethodFrameInfo(CalleeSaveType::kSaveRefsAndArgs); + constexpr QuickMethodFrameInfo callee_info = + RuntimeCalleeSaveFrame::GetMethodFrameInfo(CalleeSaveType::kSaveRefsAndArgs); // Callee saves + handle scope + method ref + alignment // Note: -sizeof(void*) since callee-save frame stores a whole method pointer. |