diff options
author | 2016-05-19 10:37:24 +0100 | |
---|---|---|
committer | 2016-05-19 18:12:22 +0100 | |
commit | 3224838dfe9c95330ad963286f2c47e9546d3b5c (patch) | |
tree | 50d1b8759c61d392ecc159ede7efab94ecbfcde8 | |
parent | db9fcb30402a2726564905c206fa23ee86e146c3 (diff) |
Clean up JNI calling convention callee saves.
Precalculate callee saves at compile time and return them
as ArrayRef<> instead of keeping then in a std::vector<>.
Change-Id: I4fd7d2bbf6138dc31b0fe8554eac35b0777ec9ef
38 files changed, 499 insertions, 356 deletions
diff --git a/compiler/jni/jni_cfi_test.cc b/compiler/jni/jni_cfi_test.cc index 371019a225..3526802d6c 100644 --- a/compiler/jni/jni_cfi_test.cc +++ b/compiler/jni/jni_cfi_test.cc @@ -52,7 +52,7 @@ class JNICFITest : public CFITest { std::unique_ptr<ManagedRuntimeCallingConvention> mr_conv( ManagedRuntimeCallingConvention::Create(&arena, is_static, is_synchronized, shorty, isa)); const int frame_size(jni_conv->FrameSize()); - const std::vector<ManagedRegister>& callee_save_regs = jni_conv->CalleeSaveRegisters(); + ArrayRef<const ManagedRegister> callee_save_regs = jni_conv->CalleeSaveRegisters(); // Assemble the method. std::unique_ptr<Assembler> jni_asm(Assembler::Create(&arena, isa)); diff --git a/compiler/jni/quick/arm/calling_convention_arm.cc b/compiler/jni/quick/arm/calling_convention_arm.cc index 9d2732aa2b..29411f0236 100644 --- a/compiler/jni/quick/arm/calling_convention_arm.cc +++ b/compiler/jni/quick/arm/calling_convention_arm.cc @@ -31,10 +31,6 @@ static const SRegister kHFSArgumentRegisters[] = { S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, S12, S13, S14, S15 }; -static const SRegister kHFSCalleeSaveRegisters[] = { - S16, S17, S18, S19, S20, S21, S22, S23, S24, S25, S26, S27, S28, S29, S30, S31 -}; - static const DRegister kHFDArgumentRegisters[] = { D0, D1, D2, D3, D4, D5, D6, D7 }; @@ -42,6 +38,57 @@ static const DRegister kHFDArgumentRegisters[] = { static_assert(arraysize(kHFDArgumentRegisters) * 2 == arraysize(kHFSArgumentRegisters), "ks d argument registers mismatch"); +static constexpr ManagedRegister kCalleeSaveRegisters[] = { + // Core registers. + ArmManagedRegister::FromCoreRegister(R5), + ArmManagedRegister::FromCoreRegister(R6), + ArmManagedRegister::FromCoreRegister(R7), + ArmManagedRegister::FromCoreRegister(R8), + ArmManagedRegister::FromCoreRegister(R10), + ArmManagedRegister::FromCoreRegister(R11), + // Hard float registers. + ArmManagedRegister::FromSRegister(S16), + ArmManagedRegister::FromSRegister(S17), + ArmManagedRegister::FromSRegister(S18), + ArmManagedRegister::FromSRegister(S19), + ArmManagedRegister::FromSRegister(S20), + ArmManagedRegister::FromSRegister(S21), + ArmManagedRegister::FromSRegister(S22), + ArmManagedRegister::FromSRegister(S23), + ArmManagedRegister::FromSRegister(S24), + ArmManagedRegister::FromSRegister(S25), + ArmManagedRegister::FromSRegister(S26), + ArmManagedRegister::FromSRegister(S27), + ArmManagedRegister::FromSRegister(S28), + ArmManagedRegister::FromSRegister(S29), + ArmManagedRegister::FromSRegister(S30), + ArmManagedRegister::FromSRegister(S31) +}; + +static constexpr uint32_t CalculateCoreCalleeSpillMask() { + // LR is a special callee save which is not reported by CalleeSaveRegisters(). + uint32_t result = 1 << LR; + for (auto&& r : kCalleeSaveRegisters) { + if (r.AsArm().IsCoreRegister()) { + result |= (1 << r.AsArm().AsCoreRegister()); + } + } + return result; +} + +static constexpr uint32_t CalculateFpCalleeSpillMask() { + uint32_t result = 0; + for (auto&& r : kCalleeSaveRegisters) { + if (r.AsArm().IsSRegister()) { + result |= (1 << r.AsArm().AsSRegister()); + } + } + return result; +} + +static constexpr uint32_t kCoreCalleeSpillMask = CalculateCoreCalleeSpillMask(); +static constexpr uint32_t kFpCalleeSpillMask = CalculateFpCalleeSpillMask(); + // Calling convention ManagedRegister ArmManagedRuntimeCallingConvention::InterproceduralScratchRegister() { @@ -223,32 +270,15 @@ ArmJniCallingConvention::ArmJniCallingConvention(bool is_static, bool is_synchro cur_reg++; // bump the iterator for every argument } padding_ = padding; - - callee_save_regs_.push_back(ArmManagedRegister::FromCoreRegister(R5)); - callee_save_regs_.push_back(ArmManagedRegister::FromCoreRegister(R6)); - callee_save_regs_.push_back(ArmManagedRegister::FromCoreRegister(R7)); - callee_save_regs_.push_back(ArmManagedRegister::FromCoreRegister(R8)); - callee_save_regs_.push_back(ArmManagedRegister::FromCoreRegister(R10)); - callee_save_regs_.push_back(ArmManagedRegister::FromCoreRegister(R11)); - - for (size_t i = 0; i < arraysize(kHFSCalleeSaveRegisters); ++i) { - callee_save_regs_.push_back(ArmManagedRegister::FromSRegister(kHFSCalleeSaveRegisters[i])); - } } uint32_t ArmJniCallingConvention::CoreSpillMask() const { // Compute spill mask to agree with callee saves initialized in the constructor - uint32_t result = 0; - result = 1 << R5 | 1 << R6 | 1 << R7 | 1 << R8 | 1 << R10 | 1 << R11 | 1 << LR; - return result; + return kCoreCalleeSpillMask; } uint32_t ArmJniCallingConvention::FpSpillMask() const { - uint32_t result = 0; - for (size_t i = 0; i < arraysize(kHFSCalleeSaveRegisters); ++i) { - result |= (1 << kHFSCalleeSaveRegisters[i]); - } - return result; + return kFpCalleeSpillMask; } ManagedRegister ArmJniCallingConvention::ReturnScratchRegister() const { @@ -269,6 +299,10 @@ size_t ArmJniCallingConvention::OutArgSize() { kStackAlignment); } +ArrayRef<const ManagedRegister> ArmJniCallingConvention::CalleeSaveRegisters() const { + return ArrayRef<const ManagedRegister>(kCalleeSaveRegisters); +} + // JniCallingConvention ABI follows AAPCS where longs and doubles must occur // in even register numbers and stack slots void ArmJniCallingConvention::Next() { diff --git a/compiler/jni/quick/arm/calling_convention_arm.h b/compiler/jni/quick/arm/calling_convention_arm.h index 35b50937e9..157880ba90 100644 --- a/compiler/jni/quick/arm/calling_convention_arm.h +++ b/compiler/jni/quick/arm/calling_convention_arm.h @@ -58,9 +58,7 @@ class ArmJniCallingConvention FINAL : public JniCallingConvention { void Next() OVERRIDE; // Override default behavior for AAPCS size_t FrameSize() OVERRIDE; size_t OutArgSize() OVERRIDE; - const std::vector<ManagedRegister>& CalleeSaveRegisters() const OVERRIDE { - return callee_save_regs_; - } + ArrayRef<const ManagedRegister> CalleeSaveRegisters() const OVERRIDE; ManagedRegister ReturnScratchRegister() const OVERRIDE; uint32_t CoreSpillMask() const OVERRIDE; uint32_t FpSpillMask() const OVERRIDE; @@ -78,9 +76,6 @@ class ArmJniCallingConvention FINAL : public JniCallingConvention { size_t NumberOfOutgoingStackArgs() OVERRIDE; private: - // TODO: these values aren't unique and can be shared amongst instances - std::vector<ManagedRegister> callee_save_regs_; - // Padding to ensure longs and doubles are not split in AAPCS size_t padding_; diff --git a/compiler/jni/quick/arm64/calling_convention_arm64.cc b/compiler/jni/quick/arm64/calling_convention_arm64.cc index 9aef10e8f4..ab56c1c04e 100644 --- a/compiler/jni/quick/arm64/calling_convention_arm64.cc +++ b/compiler/jni/quick/arm64/calling_convention_arm64.cc @@ -38,10 +38,65 @@ static const SRegister kSArgumentRegisters[] = { S0, S1, S2, S3, S4, S5, S6, S7 }; -static const DRegister kDCalleeSaveRegisters[] = { - D8, D9, D10, D11, D12, D13, D14, D15 +static constexpr ManagedRegister kCalleeSaveRegisters[] = { + // Core registers. + // Note: The native jni function may call to some VM runtime functions which may suspend + // or trigger GC. And the jni method frame will become top quick frame in those cases. + // So we need to satisfy GC to save LR and callee-save registers which is similar to + // CalleeSaveMethod(RefOnly) frame. + // Jni function is the native function which the java code wants to call. + // Jni method is the method that is compiled by jni compiler. + // Call chain: managed code(java) --> jni method --> jni function. + // Thread register(X19) is saved on stack. + Arm64ManagedRegister::FromXRegister(X19), + Arm64ManagedRegister::FromXRegister(X20), + Arm64ManagedRegister::FromXRegister(X21), + Arm64ManagedRegister::FromXRegister(X22), + Arm64ManagedRegister::FromXRegister(X23), + Arm64ManagedRegister::FromXRegister(X24), + Arm64ManagedRegister::FromXRegister(X25), + Arm64ManagedRegister::FromXRegister(X26), + Arm64ManagedRegister::FromXRegister(X27), + Arm64ManagedRegister::FromXRegister(X28), + Arm64ManagedRegister::FromXRegister(X29), + Arm64ManagedRegister::FromXRegister(LR), + // Hard float registers. + // Considering the case, java_method_1 --> jni method --> jni function --> java_method_2, + // we may break on java_method_2 and we still need to find out the values of DEX registers + // in java_method_1. So all callee-saves(in managed code) need to be saved. + Arm64ManagedRegister::FromDRegister(D8), + Arm64ManagedRegister::FromDRegister(D9), + Arm64ManagedRegister::FromDRegister(D10), + Arm64ManagedRegister::FromDRegister(D11), + Arm64ManagedRegister::FromDRegister(D12), + Arm64ManagedRegister::FromDRegister(D13), + Arm64ManagedRegister::FromDRegister(D14), + Arm64ManagedRegister::FromDRegister(D15), }; +static constexpr uint32_t CalculateCoreCalleeSpillMask() { + uint32_t result = 0u; + for (auto&& r : kCalleeSaveRegisters) { + if (r.AsArm64().IsXRegister()) { + result |= (1 << r.AsArm64().AsXRegister()); + } + } + return result; +} + +static constexpr uint32_t CalculateFpCalleeSpillMask() { + uint32_t result = 0; + for (auto&& r : kCalleeSaveRegisters) { + if (r.AsArm64().IsDRegister()) { + result |= (1 << r.AsArm64().AsDRegister()); + } + } + return result; +} + +static constexpr uint32_t kCoreCalleeSpillMask = CalculateCoreCalleeSpillMask(); +static constexpr uint32_t kFpCalleeSpillMask = CalculateFpCalleeSpillMask(); + // Calling convention ManagedRegister Arm64ManagedRuntimeCallingConvention::InterproceduralScratchRegister() { return Arm64ManagedRegister::FromXRegister(X20); // saved on entry restored on exit @@ -157,47 +212,14 @@ const ManagedRegisterEntrySpills& Arm64ManagedRuntimeCallingConvention::EntrySpi Arm64JniCallingConvention::Arm64JniCallingConvention(bool is_static, bool is_synchronized, const char* shorty) : JniCallingConvention(is_static, is_synchronized, shorty, kFramePointerSize) { - uint32_t core_spill_mask = CoreSpillMask(); - DCHECK_EQ(XZR, kNumberOfXRegisters - 1); // Exclude XZR from the loop (avoid 1 << 32). - for (int x_reg = 0; x_reg < kNumberOfXRegisters - 1; ++x_reg) { - if (((1 << x_reg) & core_spill_mask) != 0) { - callee_save_regs_.push_back( - Arm64ManagedRegister::FromXRegister(static_cast<XRegister>(x_reg))); - } - } - - uint32_t fp_spill_mask = FpSpillMask(); - for (int d_reg = 0; d_reg < kNumberOfDRegisters; ++d_reg) { - if (((1 << d_reg) & fp_spill_mask) != 0) { - callee_save_regs_.push_back( - Arm64ManagedRegister::FromDRegister(static_cast<DRegister>(d_reg))); - } - } } uint32_t Arm64JniCallingConvention::CoreSpillMask() const { - // Compute spill mask to agree with callee saves initialized in the constructor. - // Note: The native jni function may call to some VM runtime functions which may suspend - // or trigger GC. And the jni method frame will become top quick frame in those cases. - // So we need to satisfy GC to save LR and callee-save registers which is similar to - // CalleeSaveMethod(RefOnly) frame. - // Jni function is the native function which the java code wants to call. - // Jni method is the method that compiled by jni compiler. - // Call chain: managed code(java) --> jni method --> jni function. - // Thread register(X19) is saved on stack. - return 1 << X19 | 1 << X20 | 1 << X21 | 1 << X22 | 1 << X23 | 1 << X24 | - 1 << X25 | 1 << X26 | 1 << X27 | 1 << X28 | 1 << X29 | 1 << LR; + return kCoreCalleeSpillMask; } uint32_t Arm64JniCallingConvention::FpSpillMask() const { - // Considering the case, java_method_1 --> jni method --> jni function --> java_method_2, we may - // break on java_method_2 and we still need to find out the values of DEX registers in - // java_method_1. So all callee-saves(in managed code) need to be saved. - uint32_t result = 0; - for (size_t i = 0; i < arraysize(kDCalleeSaveRegisters); ++i) { - result |= (1 << kDCalleeSaveRegisters[i]); - } - return result; + return kFpCalleeSpillMask; } ManagedRegister Arm64JniCallingConvention::ReturnScratchRegister() const { @@ -218,6 +240,10 @@ size_t Arm64JniCallingConvention::OutArgSize() { return RoundUp(NumberOfOutgoingStackArgs() * kFramePointerSize, kStackAlignment); } +ArrayRef<const ManagedRegister> Arm64JniCallingConvention::CalleeSaveRegisters() const { + return ArrayRef<const ManagedRegister>(kCalleeSaveRegisters); +} + bool Arm64JniCallingConvention::IsCurrentParamInRegister() { if (IsCurrentParamAFloatOrDouble()) { return (itr_float_and_doubles_ < 8); diff --git a/compiler/jni/quick/arm64/calling_convention_arm64.h b/compiler/jni/quick/arm64/calling_convention_arm64.h index 37c92b2034..337e881fb7 100644 --- a/compiler/jni/quick/arm64/calling_convention_arm64.h +++ b/compiler/jni/quick/arm64/calling_convention_arm64.h @@ -57,9 +57,7 @@ class Arm64JniCallingConvention FINAL : public JniCallingConvention { // JNI calling convention size_t FrameSize() OVERRIDE; size_t OutArgSize() OVERRIDE; - const std::vector<ManagedRegister>& CalleeSaveRegisters() const OVERRIDE { - return callee_save_regs_; - } + ArrayRef<const ManagedRegister> CalleeSaveRegisters() const OVERRIDE; ManagedRegister ReturnScratchRegister() const OVERRIDE; uint32_t CoreSpillMask() const OVERRIDE; uint32_t FpSpillMask() const OVERRIDE; @@ -77,9 +75,6 @@ class Arm64JniCallingConvention FINAL : public JniCallingConvention { size_t NumberOfOutgoingStackArgs() OVERRIDE; private: - // TODO: these values aren't unique and can be shared amongst instances - std::vector<ManagedRegister> callee_save_regs_; - DISALLOW_COPY_AND_ASSIGN(Arm64JniCallingConvention); }; diff --git a/compiler/jni/quick/calling_convention.h b/compiler/jni/quick/calling_convention.h index 2c4b15ca31..e8f738d4d7 100644 --- a/compiler/jni/quick/calling_convention.h +++ b/compiler/jni/quick/calling_convention.h @@ -17,12 +17,11 @@ #ifndef ART_COMPILER_JNI_QUICK_CALLING_CONVENTION_H_ #define ART_COMPILER_JNI_QUICK_CALLING_CONVENTION_H_ -#include <vector> - #include "base/arena_object.h" #include "handle_scope.h" #include "primitive.h" #include "thread.h" +#include "utils/array_ref.h" #include "utils/managed_register.h" namespace art { @@ -301,7 +300,7 @@ class JniCallingConvention : public CallingConvention { virtual bool RequiresSmallResultTypeExtension() const = 0; // Callee save registers to spill prior to native code (which may clobber) - virtual const std::vector<ManagedRegister>& CalleeSaveRegisters() const = 0; + virtual ArrayRef<const ManagedRegister> CalleeSaveRegisters() const = 0; // Spill mask values virtual uint32_t CoreSpillMask() const = 0; diff --git a/compiler/jni/quick/jni_compiler.cc b/compiler/jni/quick/jni_compiler.cc index 27714b8055..4311a34494 100644 --- a/compiler/jni/quick/jni_compiler.cc +++ b/compiler/jni/quick/jni_compiler.cc @@ -112,7 +112,7 @@ CompiledMethod* ArtJniCompileMethodInternal(CompilerDriver* driver, // 1. Build the frame saving all callee saves const size_t frame_size(main_jni_conv->FrameSize()); - const std::vector<ManagedRegister>& callee_save_regs = main_jni_conv->CalleeSaveRegisters(); + ArrayRef<const ManagedRegister> callee_save_regs = main_jni_conv->CalleeSaveRegisters(); __ BuildFrame(frame_size, mr_conv->MethodRegister(), callee_save_regs, mr_conv->EntrySpills()); DCHECK_EQ(jni_asm->cfi().GetCurrentCFAOffset(), static_cast<int>(frame_size)); diff --git a/compiler/jni/quick/mips/calling_convention_mips.cc b/compiler/jni/quick/mips/calling_convention_mips.cc index 2d31a9881e..3d4d140b73 100644 --- a/compiler/jni/quick/mips/calling_convention_mips.cc +++ b/compiler/jni/quick/mips/calling_convention_mips.cc @@ -27,6 +27,32 @@ static const Register kCoreArgumentRegisters[] = { A0, A1, A2, A3 }; static const FRegister kFArgumentRegisters[] = { F12, F14 }; static const DRegister kDArgumentRegisters[] = { D6, D7 }; +static constexpr ManagedRegister kCalleeSaveRegisters[] = { + // Core registers. + MipsManagedRegister::FromCoreRegister(S2), + MipsManagedRegister::FromCoreRegister(S3), + MipsManagedRegister::FromCoreRegister(S4), + MipsManagedRegister::FromCoreRegister(S5), + MipsManagedRegister::FromCoreRegister(S6), + MipsManagedRegister::FromCoreRegister(S7), + MipsManagedRegister::FromCoreRegister(FP), + // No hard float callee saves. +}; + +static constexpr uint32_t CalculateCoreCalleeSpillMask() { + // RA is a special callee save which is not reported by CalleeSaveRegisters(). + uint32_t result = 1 << RA; + for (auto&& r : kCalleeSaveRegisters) { + if (r.AsMips().IsCoreRegister()) { + result |= (1 << r.AsMips().AsCoreRegister()); + } + } + return result; +} + +static constexpr uint32_t kCoreCalleeSpillMask = CalculateCoreCalleeSpillMask(); +static constexpr uint32_t kFpCalleeSpillMask = 0u; + // Calling convention ManagedRegister MipsManagedRuntimeCallingConvention::InterproceduralScratchRegister() { return MipsManagedRegister::FromCoreRegister(T9); @@ -161,21 +187,14 @@ MipsJniCallingConvention::MipsJniCallingConvention(bool is_static, bool is_synch cur_reg++; // bump the iterator for every argument } padding_ = padding; - - callee_save_regs_.push_back(MipsManagedRegister::FromCoreRegister(S2)); - callee_save_regs_.push_back(MipsManagedRegister::FromCoreRegister(S3)); - callee_save_regs_.push_back(MipsManagedRegister::FromCoreRegister(S4)); - callee_save_regs_.push_back(MipsManagedRegister::FromCoreRegister(S5)); - callee_save_regs_.push_back(MipsManagedRegister::FromCoreRegister(S6)); - callee_save_regs_.push_back(MipsManagedRegister::FromCoreRegister(S7)); - callee_save_regs_.push_back(MipsManagedRegister::FromCoreRegister(FP)); } uint32_t MipsJniCallingConvention::CoreSpillMask() const { - // Compute spill mask to agree with callee saves initialized in the constructor - uint32_t result = 0; - result = 1 << S2 | 1 << S3 | 1 << S4 | 1 << S5 | 1 << S6 | 1 << S7 | 1 << FP | 1 << RA; - return result; + return kCoreCalleeSpillMask; +} + +uint32_t MipsJniCallingConvention::FpSpillMask() const { + return kFpCalleeSpillMask; } ManagedRegister MipsJniCallingConvention::ReturnScratchRegister() const { @@ -196,6 +215,10 @@ size_t MipsJniCallingConvention::OutArgSize() { return RoundUp(NumberOfOutgoingStackArgs() * kFramePointerSize + padding_, kStackAlignment); } +ArrayRef<const ManagedRegister> MipsJniCallingConvention::CalleeSaveRegisters() const { + return ArrayRef<const ManagedRegister>(kCalleeSaveRegisters); +} + // JniCallingConvention ABI follows AAPCS where longs and doubles must occur // in even register numbers and stack slots void MipsJniCallingConvention::Next() { diff --git a/compiler/jni/quick/mips/calling_convention_mips.h b/compiler/jni/quick/mips/calling_convention_mips.h index dc45432410..5c128b0343 100644 --- a/compiler/jni/quick/mips/calling_convention_mips.h +++ b/compiler/jni/quick/mips/calling_convention_mips.h @@ -58,14 +58,10 @@ class MipsJniCallingConvention FINAL : public JniCallingConvention { void Next() OVERRIDE; // Override default behavior for AAPCS size_t FrameSize() OVERRIDE; size_t OutArgSize() OVERRIDE; - const std::vector<ManagedRegister>& CalleeSaveRegisters() const OVERRIDE { - return callee_save_regs_; - } + ArrayRef<const ManagedRegister> CalleeSaveRegisters() const OVERRIDE; ManagedRegister ReturnScratchRegister() const OVERRIDE; uint32_t CoreSpillMask() const OVERRIDE; - uint32_t FpSpillMask() const OVERRIDE { - return 0; // Floats aren't spilled in JNI down call - } + uint32_t FpSpillMask() const OVERRIDE; bool IsCurrentParamInRegister() OVERRIDE; bool IsCurrentParamOnStack() OVERRIDE; ManagedRegister CurrentParamRegister() OVERRIDE; @@ -80,9 +76,6 @@ class MipsJniCallingConvention FINAL : public JniCallingConvention { size_t NumberOfOutgoingStackArgs() OVERRIDE; private: - // TODO: these values aren't unique and can be shared amongst instances - std::vector<ManagedRegister> callee_save_regs_; - // Padding to ensure longs and doubles are not split in AAPCS size_t padding_; diff --git a/compiler/jni/quick/mips64/calling_convention_mips64.cc b/compiler/jni/quick/mips64/calling_convention_mips64.cc index 807d740b4d..f2e1da8254 100644 --- a/compiler/jni/quick/mips64/calling_convention_mips64.cc +++ b/compiler/jni/quick/mips64/calling_convention_mips64.cc @@ -31,6 +31,33 @@ static const FpuRegister kFpuArgumentRegisters[] = { F12, F13, F14, F15, F16, F17, F18, F19 }; +static constexpr ManagedRegister kCalleeSaveRegisters[] = { + // Core registers. + Mips64ManagedRegister::FromGpuRegister(S2), + Mips64ManagedRegister::FromGpuRegister(S3), + Mips64ManagedRegister::FromGpuRegister(S4), + Mips64ManagedRegister::FromGpuRegister(S5), + Mips64ManagedRegister::FromGpuRegister(S6), + Mips64ManagedRegister::FromGpuRegister(S7), + Mips64ManagedRegister::FromGpuRegister(GP), + Mips64ManagedRegister::FromGpuRegister(S8), + // No hard float callee saves. +}; + +static constexpr uint32_t CalculateCoreCalleeSpillMask() { + // RA is a special callee save which is not reported by CalleeSaveRegisters(). + uint32_t result = 1 << RA; + for (auto&& r : kCalleeSaveRegisters) { + if (r.AsMips64().IsGpuRegister()) { + result |= (1 << r.AsMips64().AsGpuRegister()); + } + } + return result; +} + +static constexpr uint32_t kCoreCalleeSpillMask = CalculateCoreCalleeSpillMask(); +static constexpr uint32_t kFpCalleeSpillMask = 0u; + // Calling convention ManagedRegister Mips64ManagedRuntimeCallingConvention::InterproceduralScratchRegister() { return Mips64ManagedRegister::FromGpuRegister(T9); @@ -126,22 +153,14 @@ const ManagedRegisterEntrySpills& Mips64ManagedRuntimeCallingConvention::EntrySp Mips64JniCallingConvention::Mips64JniCallingConvention(bool is_static, bool is_synchronized, const char* shorty) : JniCallingConvention(is_static, is_synchronized, shorty, kFramePointerSize) { - callee_save_regs_.push_back(Mips64ManagedRegister::FromGpuRegister(S2)); - callee_save_regs_.push_back(Mips64ManagedRegister::FromGpuRegister(S3)); - callee_save_regs_.push_back(Mips64ManagedRegister::FromGpuRegister(S4)); - callee_save_regs_.push_back(Mips64ManagedRegister::FromGpuRegister(S5)); - callee_save_regs_.push_back(Mips64ManagedRegister::FromGpuRegister(S6)); - callee_save_regs_.push_back(Mips64ManagedRegister::FromGpuRegister(S7)); - callee_save_regs_.push_back(Mips64ManagedRegister::FromGpuRegister(GP)); - callee_save_regs_.push_back(Mips64ManagedRegister::FromGpuRegister(S8)); } uint32_t Mips64JniCallingConvention::CoreSpillMask() const { - // Compute spill mask to agree with callee saves initialized in the constructor - uint32_t result = 0; - result = 1 << S2 | 1 << S3 | 1 << S4 | 1 << S5 | 1 << S6 | 1 << S7 | 1 << GP | 1 << S8 | 1 << RA; - DCHECK_EQ(static_cast<size_t>(POPCOUNT(result)), callee_save_regs_.size() + 1); - return result; + return kCoreCalleeSpillMask; +} + +uint32_t Mips64JniCallingConvention::FpSpillMask() const { + return kFpCalleeSpillMask; } ManagedRegister Mips64JniCallingConvention::ReturnScratchRegister() const { @@ -162,6 +181,10 @@ size_t Mips64JniCallingConvention::OutArgSize() { return RoundUp(NumberOfOutgoingStackArgs() * kFramePointerSize, kStackAlignment); } +ArrayRef<const ManagedRegister> Mips64JniCallingConvention::CalleeSaveRegisters() const { + return ArrayRef<const ManagedRegister>(kCalleeSaveRegisters); +} + bool Mips64JniCallingConvention::IsCurrentParamInRegister() { return itr_args_ < 8; } diff --git a/compiler/jni/quick/mips64/calling_convention_mips64.h b/compiler/jni/quick/mips64/calling_convention_mips64.h index 3d6aab7399..99ea3cd66c 100644 --- a/compiler/jni/quick/mips64/calling_convention_mips64.h +++ b/compiler/jni/quick/mips64/calling_convention_mips64.h @@ -57,14 +57,10 @@ class Mips64JniCallingConvention FINAL : public JniCallingConvention { // JNI calling convention size_t FrameSize() OVERRIDE; size_t OutArgSize() OVERRIDE; - const std::vector<ManagedRegister>& CalleeSaveRegisters() const OVERRIDE { - return callee_save_regs_; - } + ArrayRef<const ManagedRegister> CalleeSaveRegisters() const OVERRIDE; ManagedRegister ReturnScratchRegister() const OVERRIDE; uint32_t CoreSpillMask() const OVERRIDE; - uint32_t FpSpillMask() const OVERRIDE { - return 0; // Floats aren't spilled in JNI down call - } + uint32_t FpSpillMask() const OVERRIDE; bool IsCurrentParamInRegister() OVERRIDE; bool IsCurrentParamOnStack() OVERRIDE; ManagedRegister CurrentParamRegister() OVERRIDE; @@ -79,9 +75,6 @@ class Mips64JniCallingConvention FINAL : public JniCallingConvention { size_t NumberOfOutgoingStackArgs() OVERRIDE; private: - // TODO: these values aren't unique and can be shared amongst instances - std::vector<ManagedRegister> callee_save_regs_; - DISALLOW_COPY_AND_ASSIGN(Mips64JniCallingConvention); }; diff --git a/compiler/jni/quick/x86/calling_convention_x86.cc b/compiler/jni/quick/x86/calling_convention_x86.cc index 322caca41f..22c7cd04e8 100644 --- a/compiler/jni/quick/x86/calling_convention_x86.cc +++ b/compiler/jni/quick/x86/calling_convention_x86.cc @@ -23,6 +23,28 @@ namespace art { namespace x86 { +static constexpr ManagedRegister kCalleeSaveRegisters[] = { + // Core registers. + X86ManagedRegister::FromCpuRegister(EBP), + X86ManagedRegister::FromCpuRegister(ESI), + X86ManagedRegister::FromCpuRegister(EDI), + // No hard float callee saves. +}; + +static constexpr uint32_t CalculateCoreCalleeSpillMask() { + // The spilled PC gets a special marker. + uint32_t result = 1 << kNumberOfCpuRegisters; + for (auto&& r : kCalleeSaveRegisters) { + if (r.AsX86().IsCpuRegister()) { + result |= (1 << r.AsX86().AsCpuRegister()); + } + } + return result; +} + +static constexpr uint32_t kCoreCalleeSpillMask = CalculateCoreCalleeSpillMask(); +static constexpr uint32_t kFpCalleeSpillMask = 0u; + // Calling convention ManagedRegister X86ManagedRuntimeCallingConvention::InterproceduralScratchRegister() { @@ -169,13 +191,14 @@ const ManagedRegisterEntrySpills& X86ManagedRuntimeCallingConvention::EntrySpill X86JniCallingConvention::X86JniCallingConvention(bool is_static, bool is_synchronized, const char* shorty) : JniCallingConvention(is_static, is_synchronized, shorty, kFramePointerSize) { - callee_save_regs_.push_back(X86ManagedRegister::FromCpuRegister(EBP)); - callee_save_regs_.push_back(X86ManagedRegister::FromCpuRegister(ESI)); - callee_save_regs_.push_back(X86ManagedRegister::FromCpuRegister(EDI)); } uint32_t X86JniCallingConvention::CoreSpillMask() const { - return 1 << EBP | 1 << ESI | 1 << EDI | 1 << kNumberOfCpuRegisters; + return kCoreCalleeSpillMask; +} + +uint32_t X86JniCallingConvention::FpSpillMask() const { + return kFpCalleeSpillMask; } size_t X86JniCallingConvention::FrameSize() { @@ -192,6 +215,10 @@ size_t X86JniCallingConvention::OutArgSize() { return RoundUp(NumberOfOutgoingStackArgs() * kFramePointerSize, kStackAlignment); } +ArrayRef<const ManagedRegister> X86JniCallingConvention::CalleeSaveRegisters() const { + return ArrayRef<const ManagedRegister>(kCalleeSaveRegisters); +} + bool X86JniCallingConvention::IsCurrentParamInRegister() { return false; // Everything is passed by stack. } diff --git a/compiler/jni/quick/x86/calling_convention_x86.h b/compiler/jni/quick/x86/calling_convention_x86.h index cdf0956c9a..9d678b7a63 100644 --- a/compiler/jni/quick/x86/calling_convention_x86.h +++ b/compiler/jni/quick/x86/calling_convention_x86.h @@ -59,14 +59,10 @@ class X86JniCallingConvention FINAL : public JniCallingConvention { // JNI calling convention size_t FrameSize() OVERRIDE; size_t OutArgSize() OVERRIDE; - const std::vector<ManagedRegister>& CalleeSaveRegisters() const OVERRIDE { - return callee_save_regs_; - } + ArrayRef<const ManagedRegister> CalleeSaveRegisters() const OVERRIDE; ManagedRegister ReturnScratchRegister() const OVERRIDE; uint32_t CoreSpillMask() const OVERRIDE; - uint32_t FpSpillMask() const OVERRIDE { - return 0; - } + uint32_t FpSpillMask() const OVERRIDE; bool IsCurrentParamInRegister() OVERRIDE; bool IsCurrentParamOnStack() OVERRIDE; ManagedRegister CurrentParamRegister() OVERRIDE; @@ -81,9 +77,6 @@ class X86JniCallingConvention FINAL : public JniCallingConvention { size_t NumberOfOutgoingStackArgs() OVERRIDE; private: - // TODO: these values aren't unique and can be shared amongst instances - std::vector<ManagedRegister> callee_save_regs_; - DISALLOW_COPY_AND_ASSIGN(X86JniCallingConvention); }; diff --git a/compiler/jni/quick/x86_64/calling_convention_x86_64.cc b/compiler/jni/quick/x86_64/calling_convention_x86_64.cc index b6b11ca51f..cc4d2324ba 100644 --- a/compiler/jni/quick/x86_64/calling_convention_x86_64.cc +++ b/compiler/jni/quick/x86_64/calling_convention_x86_64.cc @@ -24,6 +24,45 @@ namespace art { namespace x86_64 { +static constexpr ManagedRegister kCalleeSaveRegisters[] = { + // Core registers. + X86_64ManagedRegister::FromCpuRegister(RBX), + X86_64ManagedRegister::FromCpuRegister(RBP), + X86_64ManagedRegister::FromCpuRegister(R12), + X86_64ManagedRegister::FromCpuRegister(R13), + X86_64ManagedRegister::FromCpuRegister(R14), + X86_64ManagedRegister::FromCpuRegister(R15), + // Hard float registers. + X86_64ManagedRegister::FromXmmRegister(XMM12), + X86_64ManagedRegister::FromXmmRegister(XMM13), + X86_64ManagedRegister::FromXmmRegister(XMM14), + X86_64ManagedRegister::FromXmmRegister(XMM15), +}; + +static constexpr uint32_t CalculateCoreCalleeSpillMask() { + // The spilled PC gets a special marker. + uint32_t result = 1 << kNumberOfCpuRegisters; + for (auto&& r : kCalleeSaveRegisters) { + if (r.AsX86_64().IsCpuRegister()) { + result |= (1 << r.AsX86_64().AsCpuRegister().AsRegister()); + } + } + return result; +} + +static constexpr uint32_t CalculateFpCalleeSpillMask() { + uint32_t result = 0; + for (auto&& r : kCalleeSaveRegisters) { + if (r.AsX86_64().IsXmmRegister()) { + result |= (1 << r.AsX86_64().AsXmmRegister().AsFloatRegister()); + } + } + return result; +} + +static constexpr uint32_t kCoreCalleeSpillMask = CalculateCoreCalleeSpillMask(); +static constexpr uint32_t kFpCalleeSpillMask = CalculateFpCalleeSpillMask(); + // Calling convention ManagedRegister X86_64ManagedRuntimeCallingConvention::InterproceduralScratchRegister() { @@ -125,25 +164,14 @@ const ManagedRegisterEntrySpills& X86_64ManagedRuntimeCallingConvention::EntrySp X86_64JniCallingConvention::X86_64JniCallingConvention(bool is_static, bool is_synchronized, const char* shorty) : JniCallingConvention(is_static, is_synchronized, shorty, kFramePointerSize) { - callee_save_regs_.push_back(X86_64ManagedRegister::FromCpuRegister(RBX)); - callee_save_regs_.push_back(X86_64ManagedRegister::FromCpuRegister(RBP)); - callee_save_regs_.push_back(X86_64ManagedRegister::FromCpuRegister(R12)); - callee_save_regs_.push_back(X86_64ManagedRegister::FromCpuRegister(R13)); - callee_save_regs_.push_back(X86_64ManagedRegister::FromCpuRegister(R14)); - callee_save_regs_.push_back(X86_64ManagedRegister::FromCpuRegister(R15)); - callee_save_regs_.push_back(X86_64ManagedRegister::FromXmmRegister(XMM12)); - callee_save_regs_.push_back(X86_64ManagedRegister::FromXmmRegister(XMM13)); - callee_save_regs_.push_back(X86_64ManagedRegister::FromXmmRegister(XMM14)); - callee_save_regs_.push_back(X86_64ManagedRegister::FromXmmRegister(XMM15)); } uint32_t X86_64JniCallingConvention::CoreSpillMask() const { - return 1 << RBX | 1 << RBP | 1 << R12 | 1 << R13 | 1 << R14 | 1 << R15 | - 1 << kNumberOfCpuRegisters; + return kCoreCalleeSpillMask; } uint32_t X86_64JniCallingConvention::FpSpillMask() const { - return 1 << XMM12 | 1 << XMM13 | 1 << XMM14 | 1 << XMM15; + return kFpCalleeSpillMask; } size_t X86_64JniCallingConvention::FrameSize() { @@ -160,6 +188,10 @@ size_t X86_64JniCallingConvention::OutArgSize() { return RoundUp(NumberOfOutgoingStackArgs() * kFramePointerSize, kStackAlignment); } +ArrayRef<const ManagedRegister> X86_64JniCallingConvention::CalleeSaveRegisters() const { + return ArrayRef<const ManagedRegister>(kCalleeSaveRegisters); +} + bool X86_64JniCallingConvention::IsCurrentParamInRegister() { return !IsCurrentParamOnStack(); } diff --git a/compiler/jni/quick/x86_64/calling_convention_x86_64.h b/compiler/jni/quick/x86_64/calling_convention_x86_64.h index 6e47c9fae3..e2d3d48bc0 100644 --- a/compiler/jni/quick/x86_64/calling_convention_x86_64.h +++ b/compiler/jni/quick/x86_64/calling_convention_x86_64.h @@ -55,9 +55,7 @@ class X86_64JniCallingConvention FINAL : public JniCallingConvention { // JNI calling convention size_t FrameSize() OVERRIDE; size_t OutArgSize() OVERRIDE; - const std::vector<ManagedRegister>& CalleeSaveRegisters() const OVERRIDE { - return callee_save_regs_; - } + ArrayRef<const ManagedRegister> CalleeSaveRegisters() const OVERRIDE; ManagedRegister ReturnScratchRegister() const OVERRIDE; uint32_t CoreSpillMask() const OVERRIDE; uint32_t FpSpillMask() const OVERRIDE; @@ -75,9 +73,6 @@ class X86_64JniCallingConvention FINAL : public JniCallingConvention { size_t NumberOfOutgoingStackArgs() OVERRIDE; private: - // TODO: these values aren't unique and can be shared amongst instances - std::vector<ManagedRegister> callee_save_regs_; - DISALLOW_COPY_AND_ASSIGN(X86_64JniCallingConvention); }; diff --git a/compiler/utils/arm/assembler_arm.cc b/compiler/utils/arm/assembler_arm.cc index e5f91dc8ca..a7f4547514 100644 --- a/compiler/utils/arm/assembler_arm.cc +++ b/compiler/utils/arm/assembler_arm.cc @@ -386,8 +386,9 @@ static dwarf::Reg DWARFReg(SRegister reg) { constexpr size_t kFramePointerSize = kArmPointerSize; -void ArmAssembler::BuildFrame(size_t frame_size, ManagedRegister method_reg, - const std::vector<ManagedRegister>& callee_save_regs, +void ArmAssembler::BuildFrame(size_t frame_size, + ManagedRegister method_reg, + ArrayRef<const ManagedRegister> callee_save_regs, const ManagedRegisterEntrySpills& entry_spills) { CHECK_EQ(buffer_.Size(), 0U); // Nothing emitted yet CHECK_ALIGNED(frame_size, kStackAlignment); @@ -442,7 +443,7 @@ void ArmAssembler::BuildFrame(size_t frame_size, ManagedRegister method_reg, } void ArmAssembler::RemoveFrame(size_t frame_size, - const std::vector<ManagedRegister>& callee_save_regs) { + ArrayRef<const ManagedRegister> callee_save_regs) { CHECK_ALIGNED(frame_size, kStackAlignment); cfi_.RememberState(); diff --git a/compiler/utils/arm/assembler_arm.h b/compiler/utils/arm/assembler_arm.h index ffbe786bf4..274d0de166 100644 --- a/compiler/utils/arm/assembler_arm.h +++ b/compiler/utils/arm/assembler_arm.h @@ -907,12 +907,13 @@ class ArmAssembler : public Assembler { // // Emit code that will create an activation on the stack - void BuildFrame(size_t frame_size, ManagedRegister method_reg, - const std::vector<ManagedRegister>& callee_save_regs, + void BuildFrame(size_t frame_size, + ManagedRegister method_reg, + ArrayRef<const ManagedRegister> callee_save_regs, const ManagedRegisterEntrySpills& entry_spills) OVERRIDE; // Emit code that will remove an activation from the stack - void RemoveFrame(size_t frame_size, const std::vector<ManagedRegister>& callee_save_regs) + void RemoveFrame(size_t frame_size, ArrayRef<const ManagedRegister> callee_save_regs) OVERRIDE; void IncreaseFrameSize(size_t adjust) OVERRIDE; diff --git a/compiler/utils/arm/managed_register_arm.h b/compiler/utils/arm/managed_register_arm.h index 5b84058f7f..276db4420c 100644 --- a/compiler/utils/arm/managed_register_arm.h +++ b/compiler/utils/arm/managed_register_arm.h @@ -85,34 +85,34 @@ const int kNumberOfAllocIds = // There is a one-to-one mapping between ManagedRegister and register id. class ArmManagedRegister : public ManagedRegister { public: - Register AsCoreRegister() const { + constexpr Register AsCoreRegister() const { CHECK(IsCoreRegister()); return static_cast<Register>(id_); } - SRegister AsSRegister() const { + constexpr SRegister AsSRegister() const { CHECK(IsSRegister()); return static_cast<SRegister>(id_ - kNumberOfCoreRegIds); } - DRegister AsDRegister() const { + constexpr DRegister AsDRegister() const { CHECK(IsDRegister()); return static_cast<DRegister>(id_ - kNumberOfCoreRegIds - kNumberOfSRegIds); } - SRegister AsOverlappingDRegisterLow() const { + constexpr SRegister AsOverlappingDRegisterLow() const { CHECK(IsOverlappingDRegister()); DRegister d_reg = AsDRegister(); return static_cast<SRegister>(d_reg * 2); } - SRegister AsOverlappingDRegisterHigh() const { + constexpr SRegister AsOverlappingDRegisterHigh() const { CHECK(IsOverlappingDRegister()); DRegister d_reg = AsDRegister(); return static_cast<SRegister>(d_reg * 2 + 1); } - RegisterPair AsRegisterPair() const { + constexpr RegisterPair AsRegisterPair() const { CHECK(IsRegisterPair()); Register reg_low = AsRegisterPairLow(); if (reg_low == R1) { @@ -122,50 +122,50 @@ class ArmManagedRegister : public ManagedRegister { } } - Register AsRegisterPairLow() const { + constexpr Register AsRegisterPairLow() const { CHECK(IsRegisterPair()); // Appropriate mapping of register ids allows to use AllocIdLow(). return FromRegId(AllocIdLow()).AsCoreRegister(); } - Register AsRegisterPairHigh() const { + constexpr Register AsRegisterPairHigh() const { CHECK(IsRegisterPair()); // Appropriate mapping of register ids allows to use AllocIdHigh(). return FromRegId(AllocIdHigh()).AsCoreRegister(); } - bool IsCoreRegister() const { + constexpr bool IsCoreRegister() const { CHECK(IsValidManagedRegister()); return (0 <= id_) && (id_ < kNumberOfCoreRegIds); } - bool IsSRegister() const { + constexpr bool IsSRegister() const { CHECK(IsValidManagedRegister()); const int test = id_ - kNumberOfCoreRegIds; return (0 <= test) && (test < kNumberOfSRegIds); } - bool IsDRegister() const { + constexpr bool IsDRegister() const { CHECK(IsValidManagedRegister()); const int test = id_ - (kNumberOfCoreRegIds + kNumberOfSRegIds); return (0 <= test) && (test < kNumberOfDRegIds); } // Returns true if this DRegister overlaps SRegisters. - bool IsOverlappingDRegister() const { + constexpr bool IsOverlappingDRegister() const { CHECK(IsValidManagedRegister()); const int test = id_ - (kNumberOfCoreRegIds + kNumberOfSRegIds); return (0 <= test) && (test < kNumberOfOverlappingDRegIds); } - bool IsRegisterPair() const { + constexpr bool IsRegisterPair() const { CHECK(IsValidManagedRegister()); const int test = id_ - (kNumberOfCoreRegIds + kNumberOfSRegIds + kNumberOfDRegIds); return (0 <= test) && (test < kNumberOfPairRegIds); } - bool IsSameType(ArmManagedRegister test) const { + constexpr bool IsSameType(ArmManagedRegister test) const { CHECK(IsValidManagedRegister() && test.IsValidManagedRegister()); return (IsCoreRegister() && test.IsCoreRegister()) || @@ -182,29 +182,29 @@ class ArmManagedRegister : public ManagedRegister { void Print(std::ostream& os) const; - static ArmManagedRegister FromCoreRegister(Register r) { + static constexpr ArmManagedRegister FromCoreRegister(Register r) { CHECK_NE(r, kNoRegister); return FromRegId(r); } - static ArmManagedRegister FromSRegister(SRegister r) { + static constexpr ArmManagedRegister FromSRegister(SRegister r) { CHECK_NE(r, kNoSRegister); return FromRegId(r + kNumberOfCoreRegIds); } - static ArmManagedRegister FromDRegister(DRegister r) { + static constexpr ArmManagedRegister FromDRegister(DRegister r) { CHECK_NE(r, kNoDRegister); return FromRegId(r + (kNumberOfCoreRegIds + kNumberOfSRegIds)); } - static ArmManagedRegister FromRegisterPair(RegisterPair r) { + static constexpr ArmManagedRegister FromRegisterPair(RegisterPair r) { CHECK_NE(r, kNoRegisterPair); return FromRegId(r + (kNumberOfCoreRegIds + kNumberOfSRegIds + kNumberOfDRegIds)); } // Return a RegisterPair consisting of Register r_low and r_low + 1. - static ArmManagedRegister FromCoreRegisterPair(Register r_low) { + static constexpr ArmManagedRegister FromCoreRegisterPair(Register r_low) { if (r_low != R1) { // not the dalvik special case CHECK_NE(r_low, kNoRegister); CHECK_EQ(0, (r_low % 2)); @@ -217,7 +217,7 @@ class ArmManagedRegister : public ManagedRegister { } // Return a DRegister overlapping SRegister r_low and r_low + 1. - static ArmManagedRegister FromSRegisterPair(SRegister r_low) { + static constexpr ArmManagedRegister FromSRegisterPair(SRegister r_low) { CHECK_NE(r_low, kNoSRegister); CHECK_EQ(0, (r_low % 2)); const int r = r_low / 2; @@ -226,7 +226,7 @@ class ArmManagedRegister : public ManagedRegister { } private: - bool IsValidManagedRegister() const { + constexpr bool IsValidManagedRegister() const { return (0 <= id_) && (id_ < kNumberOfRegIds); } @@ -251,9 +251,9 @@ class ArmManagedRegister : public ManagedRegister { friend class ManagedRegister; - explicit ArmManagedRegister(int reg_id) : ManagedRegister(reg_id) {} + explicit constexpr ArmManagedRegister(int reg_id) : ManagedRegister(reg_id) {} - static ArmManagedRegister FromRegId(int reg_id) { + static constexpr ArmManagedRegister FromRegId(int reg_id) { ArmManagedRegister reg(reg_id); CHECK(reg.IsValidManagedRegister()); return reg; @@ -264,7 +264,7 @@ std::ostream& operator<<(std::ostream& os, const ArmManagedRegister& reg); } // namespace arm -inline arm::ArmManagedRegister ManagedRegister::AsArm() const { +constexpr inline arm::ArmManagedRegister ManagedRegister::AsArm() const { arm::ArmManagedRegister reg(id_); CHECK(reg.IsNoRegister() || reg.IsValidManagedRegister()); return reg; diff --git a/compiler/utils/arm64/assembler_arm64.cc b/compiler/utils/arm64/assembler_arm64.cc index eb5112b464..1842f00ff6 100644 --- a/compiler/utils/arm64/assembler_arm64.cc +++ b/compiler/utils/arm64/assembler_arm64.cc @@ -683,8 +683,9 @@ void Arm64Assembler::UnspillRegisters(vixl::CPURegList registers, int offset) { DCHECK(registers.IsEmpty()); } -void Arm64Assembler::BuildFrame(size_t frame_size, ManagedRegister method_reg, - const std::vector<ManagedRegister>& callee_save_regs, +void Arm64Assembler::BuildFrame(size_t frame_size, + ManagedRegister method_reg, + ArrayRef<const ManagedRegister> callee_save_regs, const ManagedRegisterEntrySpills& entry_spills) { // Setup VIXL CPURegList for callee-saves. CPURegList core_reg_list(CPURegister::kRegister, kXRegSize, 0); @@ -741,7 +742,7 @@ void Arm64Assembler::BuildFrame(size_t frame_size, ManagedRegister method_reg, } void Arm64Assembler::RemoveFrame(size_t frame_size, - const std::vector<ManagedRegister>& callee_save_regs) { + ArrayRef<const ManagedRegister> callee_save_regs) { // Setup VIXL CPURegList for callee-saves. CPURegList core_reg_list(CPURegister::kRegister, kXRegSize, 0); CPURegList fp_reg_list(CPURegister::kFPRegister, kDRegSize, 0); diff --git a/compiler/utils/arm64/assembler_arm64.h b/compiler/utils/arm64/assembler_arm64.h index c4e5de7a67..91171a8686 100644 --- a/compiler/utils/arm64/assembler_arm64.h +++ b/compiler/utils/arm64/assembler_arm64.h @@ -109,12 +109,13 @@ class Arm64Assembler FINAL : public Assembler { void UnspillRegisters(vixl::CPURegList registers, int offset); // Emit code that will create an activation on the stack. - void BuildFrame(size_t frame_size, ManagedRegister method_reg, - const std::vector<ManagedRegister>& callee_save_regs, + void BuildFrame(size_t frame_size, + ManagedRegister method_reg, + ArrayRef<const ManagedRegister> callee_save_regs, const ManagedRegisterEntrySpills& entry_spills) OVERRIDE; // Emit code that will remove an activation from the stack. - void RemoveFrame(size_t frame_size, const std::vector<ManagedRegister>& callee_save_regs) + void RemoveFrame(size_t frame_size, ArrayRef<const ManagedRegister> callee_save_regs) OVERRIDE; void IncreaseFrameSize(size_t adjust) OVERRIDE; diff --git a/compiler/utils/arm64/managed_register_arm64.h b/compiler/utils/arm64/managed_register_arm64.h index 46be1c528c..f7d74d2af4 100644 --- a/compiler/utils/arm64/managed_register_arm64.h +++ b/compiler/utils/arm64/managed_register_arm64.h @@ -56,80 +56,80 @@ const int kNumberOfRegIds = kNumberOfXRegIds + kNumberOfWRegIds + class Arm64ManagedRegister : public ManagedRegister { public: - XRegister AsXRegister() const { + constexpr XRegister AsXRegister() const { CHECK(IsXRegister()); return static_cast<XRegister>(id_); } - WRegister AsWRegister() const { + constexpr WRegister AsWRegister() const { CHECK(IsWRegister()); return static_cast<WRegister>(id_ - kNumberOfXRegIds); } - DRegister AsDRegister() const { + constexpr DRegister AsDRegister() const { CHECK(IsDRegister()); return static_cast<DRegister>(id_ - kNumberOfXRegIds - kNumberOfWRegIds); } - SRegister AsSRegister() const { + constexpr SRegister AsSRegister() const { CHECK(IsSRegister()); return static_cast<SRegister>(id_ - kNumberOfXRegIds - kNumberOfWRegIds - kNumberOfDRegIds); } - WRegister AsOverlappingWRegister() const { + constexpr WRegister AsOverlappingWRegister() const { CHECK(IsValidManagedRegister()); if (IsZeroRegister()) return WZR; return static_cast<WRegister>(AsXRegister()); } - XRegister AsOverlappingXRegister() const { + constexpr XRegister AsOverlappingXRegister() const { CHECK(IsValidManagedRegister()); return static_cast<XRegister>(AsWRegister()); } - SRegister AsOverlappingSRegister() const { + constexpr SRegister AsOverlappingSRegister() const { CHECK(IsValidManagedRegister()); return static_cast<SRegister>(AsDRegister()); } - DRegister AsOverlappingDRegister() const { + constexpr DRegister AsOverlappingDRegister() const { CHECK(IsValidManagedRegister()); return static_cast<DRegister>(AsSRegister()); } - bool IsXRegister() const { + constexpr bool IsXRegister() const { CHECK(IsValidManagedRegister()); return (0 <= id_) && (id_ < kNumberOfXRegIds); } - bool IsWRegister() const { + constexpr bool IsWRegister() const { CHECK(IsValidManagedRegister()); const int test = id_ - kNumberOfXRegIds; return (0 <= test) && (test < kNumberOfWRegIds); } - bool IsDRegister() const { + constexpr bool IsDRegister() const { CHECK(IsValidManagedRegister()); const int test = id_ - (kNumberOfXRegIds + kNumberOfWRegIds); return (0 <= test) && (test < kNumberOfDRegIds); } - bool IsSRegister() const { + constexpr bool IsSRegister() const { CHECK(IsValidManagedRegister()); const int test = id_ - (kNumberOfXRegIds + kNumberOfWRegIds + kNumberOfDRegIds); return (0 <= test) && (test < kNumberOfSRegIds); } - bool IsGPRegister() const { + constexpr bool IsGPRegister() const { return IsXRegister() || IsWRegister(); } - bool IsFPRegister() const { + constexpr bool IsFPRegister() const { return IsDRegister() || IsSRegister(); } - bool IsSameType(Arm64ManagedRegister test) const { + constexpr bool IsSameType(Arm64ManagedRegister test) const { CHECK(IsValidManagedRegister() && test.IsValidManagedRegister()); return (IsXRegister() && test.IsXRegister()) || @@ -145,53 +145,53 @@ class Arm64ManagedRegister : public ManagedRegister { void Print(std::ostream& os) const; - static Arm64ManagedRegister FromXRegister(XRegister r) { + static constexpr Arm64ManagedRegister FromXRegister(XRegister r) { CHECK_NE(r, kNoRegister); return FromRegId(r); } - static Arm64ManagedRegister FromWRegister(WRegister r) { + static constexpr Arm64ManagedRegister FromWRegister(WRegister r) { CHECK_NE(r, kNoWRegister); return FromRegId(r + kNumberOfXRegIds); } - static Arm64ManagedRegister FromDRegister(DRegister r) { + static constexpr Arm64ManagedRegister FromDRegister(DRegister r) { CHECK_NE(r, kNoDRegister); return FromRegId(r + (kNumberOfXRegIds + kNumberOfWRegIds)); } - static Arm64ManagedRegister FromSRegister(SRegister r) { + static constexpr Arm64ManagedRegister FromSRegister(SRegister r) { CHECK_NE(r, kNoSRegister); return FromRegId(r + (kNumberOfXRegIds + kNumberOfWRegIds + kNumberOfDRegIds)); } // Returns the X register overlapping W register r. - static Arm64ManagedRegister FromWRegisterX(WRegister r) { + static constexpr Arm64ManagedRegister FromWRegisterX(WRegister r) { CHECK_NE(r, kNoWRegister); return FromRegId(r); } // Return the D register overlapping S register r. - static Arm64ManagedRegister FromSRegisterD(SRegister r) { + static constexpr Arm64ManagedRegister FromSRegisterD(SRegister r) { CHECK_NE(r, kNoSRegister); return FromRegId(r + (kNumberOfXRegIds + kNumberOfWRegIds)); } private: - bool IsValidManagedRegister() const { + constexpr bool IsValidManagedRegister() const { return (0 <= id_) && (id_ < kNumberOfRegIds); } - bool IsStackPointer() const { + constexpr bool IsStackPointer() const { return IsXRegister() && (id_ == SP); } - bool IsZeroRegister() const { + constexpr bool IsZeroRegister() const { return IsXRegister() && (id_ == XZR); } - int RegId() const { + constexpr int RegId() const { CHECK(!IsNoRegister()); return id_; } @@ -202,9 +202,9 @@ class Arm64ManagedRegister : public ManagedRegister { friend class ManagedRegister; - explicit Arm64ManagedRegister(int reg_id) : ManagedRegister(reg_id) {} + explicit constexpr Arm64ManagedRegister(int reg_id) : ManagedRegister(reg_id) {} - static Arm64ManagedRegister FromRegId(int reg_id) { + static constexpr Arm64ManagedRegister FromRegId(int reg_id) { Arm64ManagedRegister reg(reg_id); CHECK(reg.IsValidManagedRegister()); return reg; @@ -215,7 +215,7 @@ std::ostream& operator<<(std::ostream& os, const Arm64ManagedRegister& reg); } // namespace arm64 -inline arm64::Arm64ManagedRegister ManagedRegister::AsArm64() const { +constexpr inline arm64::Arm64ManagedRegister ManagedRegister::AsArm64() const { arm64::Arm64ManagedRegister reg(id_); CHECK(reg.IsNoRegister() || reg.IsValidManagedRegister()); return reg; diff --git a/compiler/utils/assembler.h b/compiler/utils/assembler.h index 5267dc3812..80aa630424 100644 --- a/compiler/utils/assembler.h +++ b/compiler/utils/assembler.h @@ -32,6 +32,7 @@ #include "memory_region.h" #include "mips/constants_mips.h" #include "offsets.h" +#include "utils/array_ref.h" #include "x86/constants_x86.h" #include "x86_64/constants_x86_64.h" @@ -375,13 +376,14 @@ class Assembler : public DeletableArenaObject<kArenaAllocAssembler> { virtual void Comment(const char* format ATTRIBUTE_UNUSED, ...) {} // Emit code that will create an activation on the stack - virtual void BuildFrame(size_t frame_size, ManagedRegister method_reg, - const std::vector<ManagedRegister>& callee_save_regs, + virtual void BuildFrame(size_t frame_size, + ManagedRegister method_reg, + ArrayRef<const ManagedRegister> callee_save_regs, const ManagedRegisterEntrySpills& entry_spills) = 0; // Emit code that will remove an activation from the stack virtual void RemoveFrame(size_t frame_size, - const std::vector<ManagedRegister>& callee_save_regs) = 0; + ArrayRef<const ManagedRegister> callee_save_regs) = 0; virtual void IncreaseFrameSize(size_t adjust) = 0; virtual void DecreaseFrameSize(size_t adjust) = 0; diff --git a/compiler/utils/managed_register.h b/compiler/utils/managed_register.h index 893daff719..46adb3f2d2 100644 --- a/compiler/utils/managed_register.h +++ b/compiler/utils/managed_register.h @@ -47,40 +47,40 @@ class ManagedRegister { // ManagedRegister is a value class. There exists no method to change the // internal state. We therefore allow a copy constructor and an // assignment-operator. - ManagedRegister(const ManagedRegister& other) : id_(other.id_) { } + constexpr ManagedRegister(const ManagedRegister& other) : id_(other.id_) { } ManagedRegister& operator=(const ManagedRegister& other) { id_ = other.id_; return *this; } - arm::ArmManagedRegister AsArm() const; - arm64::Arm64ManagedRegister AsArm64() const; - mips::MipsManagedRegister AsMips() const; - mips64::Mips64ManagedRegister AsMips64() const; - x86::X86ManagedRegister AsX86() const; - x86_64::X86_64ManagedRegister AsX86_64() const; + constexpr arm::ArmManagedRegister AsArm() const; + constexpr arm64::Arm64ManagedRegister AsArm64() const; + constexpr mips::MipsManagedRegister AsMips() const; + constexpr mips64::Mips64ManagedRegister AsMips64() const; + constexpr x86::X86ManagedRegister AsX86() const; + constexpr x86_64::X86_64ManagedRegister AsX86_64() const; // It is valid to invoke Equals on and with a NoRegister. - bool Equals(const ManagedRegister& other) const { + constexpr bool Equals(const ManagedRegister& other) const { return id_ == other.id_; } - bool IsNoRegister() const { + constexpr bool IsNoRegister() const { return id_ == kNoRegister; } - static ManagedRegister NoRegister() { + static constexpr ManagedRegister NoRegister() { return ManagedRegister(); } - int RegId() const { return id_; } - explicit ManagedRegister(int reg_id) : id_(reg_id) { } + constexpr int RegId() const { return id_; } + explicit constexpr ManagedRegister(int reg_id) : id_(reg_id) { } protected: static const int kNoRegister = -1; - ManagedRegister() : id_(kNoRegister) { } + constexpr ManagedRegister() : id_(kNoRegister) { } int id_; }; diff --git a/compiler/utils/mips/assembler_mips.cc b/compiler/utils/mips/assembler_mips.cc index a1798c0f70..9368301d07 100644 --- a/compiler/utils/mips/assembler_mips.cc +++ b/compiler/utils/mips/assembler_mips.cc @@ -2438,8 +2438,9 @@ static dwarf::Reg DWARFReg(Register reg) { constexpr size_t kFramePointerSize = 4; -void MipsAssembler::BuildFrame(size_t frame_size, ManagedRegister method_reg, - const std::vector<ManagedRegister>& callee_save_regs, +void MipsAssembler::BuildFrame(size_t frame_size, + ManagedRegister method_reg, + ArrayRef<const ManagedRegister> callee_save_regs, const ManagedRegisterEntrySpills& entry_spills) { CHECK_ALIGNED(frame_size, kStackAlignment); DCHECK(!overwriting_); @@ -2453,7 +2454,7 @@ void MipsAssembler::BuildFrame(size_t frame_size, ManagedRegister method_reg, cfi_.RelOffset(DWARFReg(RA), stack_offset); for (int i = callee_save_regs.size() - 1; i >= 0; --i) { stack_offset -= kFramePointerSize; - Register reg = callee_save_regs.at(i).AsMips().AsCoreRegister(); + Register reg = callee_save_regs[i].AsMips().AsCoreRegister(); StoreToOffset(kStoreWord, reg, SP, stack_offset); cfi_.RelOffset(DWARFReg(reg), stack_offset); } @@ -2482,7 +2483,7 @@ void MipsAssembler::BuildFrame(size_t frame_size, ManagedRegister method_reg, } void MipsAssembler::RemoveFrame(size_t frame_size, - const std::vector<ManagedRegister>& callee_save_regs) { + ArrayRef<const ManagedRegister> callee_save_regs) { CHECK_ALIGNED(frame_size, kStackAlignment); DCHECK(!overwriting_); cfi_.RememberState(); @@ -2490,7 +2491,7 @@ void MipsAssembler::RemoveFrame(size_t frame_size, // Pop callee saves and return address. int stack_offset = frame_size - (callee_save_regs.size() * kFramePointerSize) - kFramePointerSize; for (size_t i = 0; i < callee_save_regs.size(); ++i) { - Register reg = callee_save_regs.at(i).AsMips().AsCoreRegister(); + Register reg = callee_save_regs[i].AsMips().AsCoreRegister(); LoadFromOffset(kLoadWord, reg, SP, stack_offset); cfi_.Restore(DWARFReg(reg)); stack_offset += kFramePointerSize; diff --git a/compiler/utils/mips/assembler_mips.h b/compiler/utils/mips/assembler_mips.h index ecb67bd053..d5e62853f4 100644 --- a/compiler/utils/mips/assembler_mips.h +++ b/compiler/utils/mips/assembler_mips.h @@ -414,11 +414,11 @@ class MipsAssembler FINAL : public Assembler { // Emit code that will create an activation on the stack. void BuildFrame(size_t frame_size, ManagedRegister method_reg, - const std::vector<ManagedRegister>& callee_save_regs, + ArrayRef<const ManagedRegister> callee_save_regs, const ManagedRegisterEntrySpills& entry_spills) OVERRIDE; // Emit code that will remove an activation from the stack. - void RemoveFrame(size_t frame_size, const std::vector<ManagedRegister>& callee_save_regs) + void RemoveFrame(size_t frame_size, ArrayRef<const ManagedRegister> callee_save_regs) OVERRIDE; void IncreaseFrameSize(size_t adjust) OVERRIDE; diff --git a/compiler/utils/mips/managed_register_mips.h b/compiler/utils/mips/managed_register_mips.h index 5e7ed11f51..66204e70e3 100644 --- a/compiler/utils/mips/managed_register_mips.h +++ b/compiler/utils/mips/managed_register_mips.h @@ -87,70 +87,70 @@ const int kNumberOfAllocIds = // There is a one-to-one mapping between ManagedRegister and register id. class MipsManagedRegister : public ManagedRegister { public: - Register AsCoreRegister() const { + constexpr Register AsCoreRegister() const { CHECK(IsCoreRegister()); return static_cast<Register>(id_); } - FRegister AsFRegister() const { + constexpr FRegister AsFRegister() const { CHECK(IsFRegister()); return static_cast<FRegister>(id_ - kNumberOfCoreRegIds); } - DRegister AsDRegister() const { + constexpr DRegister AsDRegister() const { CHECK(IsDRegister()); return static_cast<DRegister>(id_ - kNumberOfCoreRegIds - kNumberOfFRegIds); } - FRegister AsOverlappingDRegisterLow() const { + constexpr FRegister AsOverlappingDRegisterLow() const { CHECK(IsOverlappingDRegister()); DRegister d_reg = AsDRegister(); return static_cast<FRegister>(d_reg * 2); } - FRegister AsOverlappingDRegisterHigh() const { + constexpr FRegister AsOverlappingDRegisterHigh() const { CHECK(IsOverlappingDRegister()); DRegister d_reg = AsDRegister(); return static_cast<FRegister>(d_reg * 2 + 1); } - Register AsRegisterPairLow() const { + constexpr Register AsRegisterPairLow() const { CHECK(IsRegisterPair()); // Appropriate mapping of register ids allows to use AllocIdLow(). return FromRegId(AllocIdLow()).AsCoreRegister(); } - Register AsRegisterPairHigh() const { + constexpr Register AsRegisterPairHigh() const { CHECK(IsRegisterPair()); // Appropriate mapping of register ids allows to use AllocIdHigh(). return FromRegId(AllocIdHigh()).AsCoreRegister(); } - bool IsCoreRegister() const { + constexpr bool IsCoreRegister() const { CHECK(IsValidManagedRegister()); return (0 <= id_) && (id_ < kNumberOfCoreRegIds); } - bool IsFRegister() const { + constexpr bool IsFRegister() const { CHECK(IsValidManagedRegister()); const int test = id_ - kNumberOfCoreRegIds; return (0 <= test) && (test < kNumberOfFRegIds); } - bool IsDRegister() const { + constexpr bool IsDRegister() const { CHECK(IsValidManagedRegister()); const int test = id_ - (kNumberOfCoreRegIds + kNumberOfFRegIds); return (0 <= test) && (test < kNumberOfDRegIds); } // Returns true if this DRegister overlaps FRegisters. - bool IsOverlappingDRegister() const { + constexpr bool IsOverlappingDRegister() const { CHECK(IsValidManagedRegister()); const int test = id_ - (kNumberOfCoreRegIds + kNumberOfFRegIds); return (0 <= test) && (test < kNumberOfOverlappingDRegIds); } - bool IsRegisterPair() const { + constexpr bool IsRegisterPair() const { CHECK(IsValidManagedRegister()); const int test = id_ - (kNumberOfCoreRegIds + kNumberOfFRegIds + kNumberOfDRegIds); @@ -164,32 +164,32 @@ class MipsManagedRegister : public ManagedRegister { // then false is returned. bool Overlaps(const MipsManagedRegister& other) const; - static MipsManagedRegister FromCoreRegister(Register r) { + static constexpr MipsManagedRegister FromCoreRegister(Register r) { CHECK_NE(r, kNoRegister); return FromRegId(r); } - static MipsManagedRegister FromFRegister(FRegister r) { + static constexpr MipsManagedRegister FromFRegister(FRegister r) { CHECK_NE(r, kNoFRegister); return FromRegId(r + kNumberOfCoreRegIds); } - static MipsManagedRegister FromDRegister(DRegister r) { + static constexpr MipsManagedRegister FromDRegister(DRegister r) { CHECK_NE(r, kNoDRegister); return FromRegId(r + kNumberOfCoreRegIds + kNumberOfFRegIds); } - static MipsManagedRegister FromRegisterPair(RegisterPair r) { + static constexpr MipsManagedRegister FromRegisterPair(RegisterPair r) { CHECK_NE(r, kNoRegisterPair); return FromRegId(r + (kNumberOfCoreRegIds + kNumberOfFRegIds + kNumberOfDRegIds)); } private: - bool IsValidManagedRegister() const { + constexpr bool IsValidManagedRegister() const { return (0 <= id_) && (id_ < kNumberOfRegIds); } - int RegId() const { + constexpr int RegId() const { CHECK(!IsNoRegister()); return id_; } @@ -205,9 +205,9 @@ class MipsManagedRegister : public ManagedRegister { friend class ManagedRegister; - explicit MipsManagedRegister(int reg_id) : ManagedRegister(reg_id) {} + explicit constexpr MipsManagedRegister(int reg_id) : ManagedRegister(reg_id) {} - static MipsManagedRegister FromRegId(int reg_id) { + static constexpr MipsManagedRegister FromRegId(int reg_id) { MipsManagedRegister reg(reg_id); CHECK(reg.IsValidManagedRegister()); return reg; @@ -218,7 +218,7 @@ std::ostream& operator<<(std::ostream& os, const MipsManagedRegister& reg); } // namespace mips -inline mips::MipsManagedRegister ManagedRegister::AsMips() const { +constexpr inline mips::MipsManagedRegister ManagedRegister::AsMips() const { mips::MipsManagedRegister reg(id_); CHECK(reg.IsNoRegister() || reg.IsValidManagedRegister()); return reg; diff --git a/compiler/utils/mips64/assembler_mips64.cc b/compiler/utils/mips64/assembler_mips64.cc index ab480cafd5..447ede5166 100644 --- a/compiler/utils/mips64/assembler_mips64.cc +++ b/compiler/utils/mips64/assembler_mips64.cc @@ -1977,8 +1977,9 @@ static dwarf::Reg DWARFReg(GpuRegister reg) { constexpr size_t kFramePointerSize = 8; -void Mips64Assembler::BuildFrame(size_t frame_size, ManagedRegister method_reg, - const std::vector<ManagedRegister>& callee_save_regs, +void Mips64Assembler::BuildFrame(size_t frame_size, + ManagedRegister method_reg, + ArrayRef<const ManagedRegister> callee_save_regs, const ManagedRegisterEntrySpills& entry_spills) { CHECK_ALIGNED(frame_size, kStackAlignment); DCHECK(!overwriting_); @@ -1992,7 +1993,7 @@ void Mips64Assembler::BuildFrame(size_t frame_size, ManagedRegister method_reg, cfi_.RelOffset(DWARFReg(RA), stack_offset); for (int i = callee_save_regs.size() - 1; i >= 0; --i) { stack_offset -= kFramePointerSize; - GpuRegister reg = callee_save_regs.at(i).AsMips64().AsGpuRegister(); + GpuRegister reg = callee_save_regs[i].AsMips64().AsGpuRegister(); StoreToOffset(kStoreDoubleword, reg, SP, stack_offset); cfi_.RelOffset(DWARFReg(reg), stack_offset); } @@ -2003,7 +2004,7 @@ void Mips64Assembler::BuildFrame(size_t frame_size, ManagedRegister method_reg, // Write out entry spills. int32_t offset = frame_size + kFramePointerSize; for (size_t i = 0; i < entry_spills.size(); ++i) { - Mips64ManagedRegister reg = entry_spills.at(i).AsMips64(); + Mips64ManagedRegister reg = entry_spills[i].AsMips64(); ManagedRegisterSpill spill = entry_spills.at(i); int32_t size = spill.getSize(); if (reg.IsNoRegister()) { @@ -2022,7 +2023,7 @@ void Mips64Assembler::BuildFrame(size_t frame_size, ManagedRegister method_reg, } void Mips64Assembler::RemoveFrame(size_t frame_size, - const std::vector<ManagedRegister>& callee_save_regs) { + ArrayRef<const ManagedRegister> callee_save_regs) { CHECK_ALIGNED(frame_size, kStackAlignment); DCHECK(!overwriting_); cfi_.RememberState(); @@ -2030,7 +2031,7 @@ void Mips64Assembler::RemoveFrame(size_t frame_size, // Pop callee saves and return address int stack_offset = frame_size - (callee_save_regs.size() * kFramePointerSize) - kFramePointerSize; for (size_t i = 0; i < callee_save_regs.size(); ++i) { - GpuRegister reg = callee_save_regs.at(i).AsMips64().AsGpuRegister(); + GpuRegister reg = callee_save_regs[i].AsMips64().AsGpuRegister(); LoadFromOffset(kLoadDoubleword, reg, SP, stack_offset); cfi_.Restore(DWARFReg(reg)); stack_offset += kFramePointerSize; diff --git a/compiler/utils/mips64/assembler_mips64.h b/compiler/utils/mips64/assembler_mips64.h index 8acc38ac82..0cd07089d0 100644 --- a/compiler/utils/mips64/assembler_mips64.h +++ b/compiler/utils/mips64/assembler_mips64.h @@ -365,13 +365,13 @@ class Mips64Assembler FINAL : public Assembler { // // Emit code that will create an activation on the stack. - void BuildFrame(size_t frame_size, ManagedRegister method_reg, - const std::vector<ManagedRegister>& callee_save_regs, + void BuildFrame(size_t frame_size, + ManagedRegister method_reg, + ArrayRef<const ManagedRegister> callee_save_regs, const ManagedRegisterEntrySpills& entry_spills) OVERRIDE; // Emit code that will remove an activation from the stack. - void RemoveFrame(size_t frame_size, - const std::vector<ManagedRegister>& callee_save_regs) OVERRIDE; + void RemoveFrame(size_t frame_size, ArrayRef<const ManagedRegister> callee_save_regs) OVERRIDE; void IncreaseFrameSize(size_t adjust) OVERRIDE; void DecreaseFrameSize(size_t adjust) OVERRIDE; diff --git a/compiler/utils/mips64/managed_register_mips64.h b/compiler/utils/mips64/managed_register_mips64.h index 1d36128a09..c9f95569cf 100644 --- a/compiler/utils/mips64/managed_register_mips64.h +++ b/compiler/utils/mips64/managed_register_mips64.h @@ -39,22 +39,22 @@ const int kNumberOfAllocIds = kNumberOfGpuAllocIds + kNumberOfFpuAllocIds; // There is a one-to-one mapping between ManagedRegister and register id. class Mips64ManagedRegister : public ManagedRegister { public: - GpuRegister AsGpuRegister() const { + constexpr GpuRegister AsGpuRegister() const { CHECK(IsGpuRegister()); return static_cast<GpuRegister>(id_); } - FpuRegister AsFpuRegister() const { + constexpr FpuRegister AsFpuRegister() const { CHECK(IsFpuRegister()); return static_cast<FpuRegister>(id_ - kNumberOfGpuRegIds); } - bool IsGpuRegister() const { + constexpr bool IsGpuRegister() const { CHECK(IsValidManagedRegister()); return (0 <= id_) && (id_ < kNumberOfGpuRegIds); } - bool IsFpuRegister() const { + constexpr bool IsFpuRegister() const { CHECK(IsValidManagedRegister()); const int test = id_ - kNumberOfGpuRegIds; return (0 <= test) && (test < kNumberOfFpuRegIds); @@ -67,22 +67,22 @@ class Mips64ManagedRegister : public ManagedRegister { // then false is returned. bool Overlaps(const Mips64ManagedRegister& other) const; - static Mips64ManagedRegister FromGpuRegister(GpuRegister r) { + static constexpr Mips64ManagedRegister FromGpuRegister(GpuRegister r) { CHECK_NE(r, kNoGpuRegister); return FromRegId(r); } - static Mips64ManagedRegister FromFpuRegister(FpuRegister r) { + static constexpr Mips64ManagedRegister FromFpuRegister(FpuRegister r) { CHECK_NE(r, kNoFpuRegister); return FromRegId(r + kNumberOfGpuRegIds); } private: - bool IsValidManagedRegister() const { + constexpr bool IsValidManagedRegister() const { return (0 <= id_) && (id_ < kNumberOfRegIds); } - int RegId() const { + constexpr int RegId() const { CHECK(!IsNoRegister()); return id_; } @@ -98,9 +98,9 @@ class Mips64ManagedRegister : public ManagedRegister { friend class ManagedRegister; - explicit Mips64ManagedRegister(int reg_id) : ManagedRegister(reg_id) {} + explicit constexpr Mips64ManagedRegister(int reg_id) : ManagedRegister(reg_id) {} - static Mips64ManagedRegister FromRegId(int reg_id) { + static constexpr Mips64ManagedRegister FromRegId(int reg_id) { Mips64ManagedRegister reg(reg_id); CHECK(reg.IsValidManagedRegister()); return reg; @@ -111,7 +111,7 @@ std::ostream& operator<<(std::ostream& os, const Mips64ManagedRegister& reg); } // namespace mips64 -inline mips64::Mips64ManagedRegister ManagedRegister::AsMips64() const { +constexpr inline mips64::Mips64ManagedRegister ManagedRegister::AsMips64() const { mips64::Mips64ManagedRegister reg(id_); CHECK(reg.IsNoRegister() || reg.IsValidManagedRegister()); return reg; diff --git a/compiler/utils/x86/assembler_x86.cc b/compiler/utils/x86/assembler_x86.cc index 84cdb7d4d3..f931d75e77 100644 --- a/compiler/utils/x86/assembler_x86.cc +++ b/compiler/utils/x86/assembler_x86.cc @@ -1932,15 +1932,16 @@ static dwarf::Reg DWARFReg(Register reg) { constexpr size_t kFramePointerSize = 4; -void X86Assembler::BuildFrame(size_t frame_size, ManagedRegister method_reg, - const std::vector<ManagedRegister>& spill_regs, +void X86Assembler::BuildFrame(size_t frame_size, + ManagedRegister method_reg, + ArrayRef<const ManagedRegister> spill_regs, const ManagedRegisterEntrySpills& entry_spills) { DCHECK_EQ(buffer_.Size(), 0U); // Nothing emitted yet. cfi_.SetCurrentCFAOffset(4); // Return address on stack. CHECK_ALIGNED(frame_size, kStackAlignment); int gpr_count = 0; for (int i = spill_regs.size() - 1; i >= 0; --i) { - Register spill = spill_regs.at(i).AsX86().AsCpuRegister(); + Register spill = spill_regs[i].AsX86().AsCpuRegister(); pushl(spill); gpr_count++; cfi_.AdjustCFAOffset(kFramePointerSize); @@ -1974,7 +1975,7 @@ void X86Assembler::BuildFrame(size_t frame_size, ManagedRegister method_reg, } } -void X86Assembler::RemoveFrame(size_t frame_size, const std::vector<ManagedRegister>& spill_regs) { +void X86Assembler::RemoveFrame(size_t frame_size, ArrayRef<const ManagedRegister> spill_regs) { CHECK_ALIGNED(frame_size, kStackAlignment); cfi_.RememberState(); // -kFramePointerSize for ArtMethod*. @@ -1982,7 +1983,7 @@ void X86Assembler::RemoveFrame(size_t frame_size, const std::vector<ManagedRegis addl(ESP, Immediate(adjust)); cfi_.AdjustCFAOffset(-adjust); for (size_t i = 0; i < spill_regs.size(); ++i) { - Register spill = spill_regs.at(i).AsX86().AsCpuRegister(); + Register spill = spill_regs[i].AsX86().AsCpuRegister(); popl(spill); cfi_.AdjustCFAOffset(-static_cast<int>(kFramePointerSize)); cfi_.Restore(DWARFReg(spill)); diff --git a/compiler/utils/x86/assembler_x86.h b/compiler/utils/x86/assembler_x86.h index bc46e9f7c9..fa616620b6 100644 --- a/compiler/utils/x86/assembler_x86.h +++ b/compiler/utils/x86/assembler_x86.h @@ -633,12 +633,13 @@ class X86Assembler FINAL : public Assembler { // // Emit code that will create an activation on the stack - void BuildFrame(size_t frame_size, ManagedRegister method_reg, - const std::vector<ManagedRegister>& callee_save_regs, + void BuildFrame(size_t frame_size, + ManagedRegister method_reg, + ArrayRef<const ManagedRegister> callee_save_regs, const ManagedRegisterEntrySpills& entry_spills) OVERRIDE; // Emit code that will remove an activation from the stack - void RemoveFrame(size_t frame_size, const std::vector<ManagedRegister>& callee_save_regs) + void RemoveFrame(size_t frame_size, ArrayRef<const ManagedRegister> callee_save_regs) OVERRIDE; void IncreaseFrameSize(size_t adjust) OVERRIDE; diff --git a/compiler/utils/x86/managed_register_x86.h b/compiler/utils/x86/managed_register_x86.h index fc20d7e208..c0c2b650e9 100644 --- a/compiler/utils/x86/managed_register_x86.h +++ b/compiler/utils/x86/managed_register_x86.h @@ -89,64 +89,64 @@ const int kNumberOfAllocIds = kNumberOfCpuAllocIds + kNumberOfXmmAllocIds + // There is a one-to-one mapping between ManagedRegister and register id. class X86ManagedRegister : public ManagedRegister { public: - ByteRegister AsByteRegister() const { + constexpr ByteRegister AsByteRegister() const { CHECK(IsCpuRegister()); CHECK_LT(AsCpuRegister(), ESP); // ESP, EBP, ESI and EDI cannot be encoded as byte registers. return static_cast<ByteRegister>(id_); } - Register AsCpuRegister() const { + constexpr Register AsCpuRegister() const { CHECK(IsCpuRegister()); return static_cast<Register>(id_); } - XmmRegister AsXmmRegister() const { + constexpr XmmRegister AsXmmRegister() const { CHECK(IsXmmRegister()); return static_cast<XmmRegister>(id_ - kNumberOfCpuRegIds); } - X87Register AsX87Register() const { + constexpr X87Register AsX87Register() const { CHECK(IsX87Register()); return static_cast<X87Register>(id_ - (kNumberOfCpuRegIds + kNumberOfXmmRegIds)); } - Register AsRegisterPairLow() const { + constexpr Register AsRegisterPairLow() const { CHECK(IsRegisterPair()); // Appropriate mapping of register ids allows to use AllocIdLow(). return FromRegId(AllocIdLow()).AsCpuRegister(); } - Register AsRegisterPairHigh() const { + constexpr Register AsRegisterPairHigh() const { CHECK(IsRegisterPair()); // Appropriate mapping of register ids allows to use AllocIdHigh(). return FromRegId(AllocIdHigh()).AsCpuRegister(); } - RegisterPair AsRegisterPair() const { + constexpr RegisterPair AsRegisterPair() const { CHECK(IsRegisterPair()); return static_cast<RegisterPair>(id_ - (kNumberOfCpuRegIds + kNumberOfXmmRegIds + kNumberOfX87RegIds)); } - bool IsCpuRegister() const { + constexpr bool IsCpuRegister() const { CHECK(IsValidManagedRegister()); return (0 <= id_) && (id_ < kNumberOfCpuRegIds); } - bool IsXmmRegister() const { + constexpr bool IsXmmRegister() const { CHECK(IsValidManagedRegister()); const int test = id_ - kNumberOfCpuRegIds; return (0 <= test) && (test < kNumberOfXmmRegIds); } - bool IsX87Register() const { + constexpr bool IsX87Register() const { CHECK(IsValidManagedRegister()); const int test = id_ - (kNumberOfCpuRegIds + kNumberOfXmmRegIds); return (0 <= test) && (test < kNumberOfX87RegIds); } - bool IsRegisterPair() const { + constexpr bool IsRegisterPair() const { CHECK(IsValidManagedRegister()); const int test = id_ - (kNumberOfCpuRegIds + kNumberOfXmmRegIds + kNumberOfX87RegIds); @@ -160,33 +160,33 @@ class X86ManagedRegister : public ManagedRegister { // then false is returned. bool Overlaps(const X86ManagedRegister& other) const; - static X86ManagedRegister FromCpuRegister(Register r) { + static constexpr X86ManagedRegister FromCpuRegister(Register r) { CHECK_NE(r, kNoRegister); return FromRegId(r); } - static X86ManagedRegister FromXmmRegister(XmmRegister r) { + static constexpr X86ManagedRegister FromXmmRegister(XmmRegister r) { CHECK_NE(r, kNoXmmRegister); return FromRegId(r + kNumberOfCpuRegIds); } - static X86ManagedRegister FromX87Register(X87Register r) { + static constexpr X86ManagedRegister FromX87Register(X87Register r) { CHECK_NE(r, kNoX87Register); return FromRegId(r + kNumberOfCpuRegIds + kNumberOfXmmRegIds); } - static X86ManagedRegister FromRegisterPair(RegisterPair r) { + static constexpr X86ManagedRegister FromRegisterPair(RegisterPair r) { CHECK_NE(r, kNoRegisterPair); return FromRegId(r + (kNumberOfCpuRegIds + kNumberOfXmmRegIds + kNumberOfX87RegIds)); } private: - bool IsValidManagedRegister() const { + constexpr bool IsValidManagedRegister() const { return (0 <= id_) && (id_ < kNumberOfRegIds); } - int RegId() const { + constexpr int RegId() const { CHECK(!IsNoRegister()); return id_; } @@ -202,9 +202,9 @@ class X86ManagedRegister : public ManagedRegister { friend class ManagedRegister; - explicit X86ManagedRegister(int reg_id) : ManagedRegister(reg_id) {} + explicit constexpr X86ManagedRegister(int reg_id) : ManagedRegister(reg_id) {} - static X86ManagedRegister FromRegId(int reg_id) { + static constexpr X86ManagedRegister FromRegId(int reg_id) { X86ManagedRegister reg(reg_id); CHECK(reg.IsValidManagedRegister()); return reg; @@ -215,7 +215,7 @@ std::ostream& operator<<(std::ostream& os, const X86ManagedRegister& reg); } // namespace x86 -inline x86::X86ManagedRegister ManagedRegister::AsX86() const { +constexpr inline x86::X86ManagedRegister ManagedRegister::AsX86() const { x86::X86ManagedRegister reg(id_); CHECK(reg.IsNoRegister() || reg.IsValidManagedRegister()); return reg; diff --git a/compiler/utils/x86_64/assembler_x86_64.cc b/compiler/utils/x86_64/assembler_x86_64.cc index 5e7b587e40..3046710603 100644 --- a/compiler/utils/x86_64/assembler_x86_64.cc +++ b/compiler/utils/x86_64/assembler_x86_64.cc @@ -2648,15 +2648,16 @@ static dwarf::Reg DWARFReg(FloatRegister reg) { constexpr size_t kFramePointerSize = 8; -void X86_64Assembler::BuildFrame(size_t frame_size, ManagedRegister method_reg, - const std::vector<ManagedRegister>& spill_regs, +void X86_64Assembler::BuildFrame(size_t frame_size, + ManagedRegister method_reg, + ArrayRef<const ManagedRegister> spill_regs, const ManagedRegisterEntrySpills& entry_spills) { DCHECK_EQ(buffer_.Size(), 0U); // Nothing emitted yet. cfi_.SetCurrentCFAOffset(8); // Return address on stack. CHECK_ALIGNED(frame_size, kStackAlignment); int gpr_count = 0; for (int i = spill_regs.size() - 1; i >= 0; --i) { - x86_64::X86_64ManagedRegister spill = spill_regs.at(i).AsX86_64(); + x86_64::X86_64ManagedRegister spill = spill_regs[i].AsX86_64(); if (spill.IsCpuRegister()) { pushq(spill.AsCpuRegister()); gpr_count++; @@ -2674,7 +2675,7 @@ void X86_64Assembler::BuildFrame(size_t frame_size, ManagedRegister method_reg, // spill xmms int64_t offset = rest_of_frame; for (int i = spill_regs.size() - 1; i >= 0; --i) { - x86_64::X86_64ManagedRegister spill = spill_regs.at(i).AsX86_64(); + x86_64::X86_64ManagedRegister spill = spill_regs[i].AsX86_64(); if (spill.IsXmmRegister()) { offset -= sizeof(double); movsd(Address(CpuRegister(RSP), offset), spill.AsXmmRegister()); @@ -2707,15 +2708,14 @@ void X86_64Assembler::BuildFrame(size_t frame_size, ManagedRegister method_reg, } } -void X86_64Assembler::RemoveFrame(size_t frame_size, - const std::vector<ManagedRegister>& spill_regs) { +void X86_64Assembler::RemoveFrame(size_t frame_size, ArrayRef<const ManagedRegister> spill_regs) { CHECK_ALIGNED(frame_size, kStackAlignment); cfi_.RememberState(); int gpr_count = 0; // unspill xmms int64_t offset = static_cast<int64_t>(frame_size) - (spill_regs.size() * kFramePointerSize) - 2 * kFramePointerSize; for (size_t i = 0; i < spill_regs.size(); ++i) { - x86_64::X86_64ManagedRegister spill = spill_regs.at(i).AsX86_64(); + x86_64::X86_64ManagedRegister spill = spill_regs[i].AsX86_64(); if (spill.IsXmmRegister()) { offset += sizeof(double); movsd(spill.AsXmmRegister(), Address(CpuRegister(RSP), offset)); @@ -2728,7 +2728,7 @@ void X86_64Assembler::RemoveFrame(size_t frame_size, addq(CpuRegister(RSP), Immediate(adjust)); cfi_.AdjustCFAOffset(-adjust); for (size_t i = 0; i < spill_regs.size(); ++i) { - x86_64::X86_64ManagedRegister spill = spill_regs.at(i).AsX86_64(); + x86_64::X86_64ManagedRegister spill = spill_regs[i].AsX86_64(); if (spill.IsCpuRegister()) { popq(spill.AsCpuRegister()); cfi_.AdjustCFAOffset(-static_cast<int>(kFramePointerSize)); diff --git a/compiler/utils/x86_64/assembler_x86_64.h b/compiler/utils/x86_64/assembler_x86_64.h index 720a402b5f..361f73cffa 100644 --- a/compiler/utils/x86_64/assembler_x86_64.h +++ b/compiler/utils/x86_64/assembler_x86_64.h @@ -704,12 +704,13 @@ class X86_64Assembler FINAL : public Assembler { // // Emit code that will create an activation on the stack - void BuildFrame(size_t frame_size, ManagedRegister method_reg, - const std::vector<ManagedRegister>& callee_save_regs, + void BuildFrame(size_t frame_size, + ManagedRegister method_reg, + ArrayRef<const ManagedRegister> callee_save_regs, const ManagedRegisterEntrySpills& entry_spills) OVERRIDE; // Emit code that will remove an activation from the stack - void RemoveFrame(size_t frame_size, const std::vector<ManagedRegister>& callee_save_regs) + void RemoveFrame(size_t frame_size, ArrayRef<const ManagedRegister> callee_save_regs) OVERRIDE; void IncreaseFrameSize(size_t adjust) OVERRIDE; diff --git a/compiler/utils/x86_64/assembler_x86_64_test.cc b/compiler/utils/x86_64/assembler_x86_64_test.cc index 9dccc9f21f..788c7253cf 100644 --- a/compiler/utils/x86_64/assembler_x86_64_test.cc +++ b/compiler/utils/x86_64/assembler_x86_64_test.cc @@ -1498,9 +1498,11 @@ std::string buildframe_test_fn(AssemblerX86_64Test::Base* assembler_test ATTRIBU // TODO: more interesting spill registers / entry spills. // Two random spill regs. - std::vector<ManagedRegister> spill_regs; - spill_regs.push_back(ManagedFromCpu(x86_64::R10)); - spill_regs.push_back(ManagedFromCpu(x86_64::RSI)); + const ManagedRegister raw_spill_regs[] = { + ManagedFromCpu(x86_64::R10), + ManagedFromCpu(x86_64::RSI) + }; + ArrayRef<const ManagedRegister> spill_regs(raw_spill_regs); // Three random entry spills. ManagedRegisterEntrySpills entry_spills; @@ -1543,9 +1545,11 @@ std::string removeframe_test_fn(AssemblerX86_64Test::Base* assembler_test ATTRIB // TODO: more interesting spill registers / entry spills. // Two random spill regs. - std::vector<ManagedRegister> spill_regs; - spill_regs.push_back(ManagedFromCpu(x86_64::R10)); - spill_regs.push_back(ManagedFromCpu(x86_64::RSI)); + const ManagedRegister raw_spill_regs[] = { + ManagedFromCpu(x86_64::R10), + ManagedFromCpu(x86_64::RSI) + }; + ArrayRef<const ManagedRegister> spill_regs(raw_spill_regs); size_t frame_size = 10 * kStackAlignment; assembler->RemoveFrame(10 * kStackAlignment, spill_regs); diff --git a/compiler/utils/x86_64/constants_x86_64.h b/compiler/utils/x86_64/constants_x86_64.h index 0c782d46cd..37db6b1543 100644 --- a/compiler/utils/x86_64/constants_x86_64.h +++ b/compiler/utils/x86_64/constants_x86_64.h @@ -29,15 +29,15 @@ namespace x86_64 { class CpuRegister { public: - explicit CpuRegister(Register r) : reg_(r) {} - explicit CpuRegister(int r) : reg_(Register(r)) {} - Register AsRegister() const { + explicit constexpr CpuRegister(Register r) : reg_(r) {} + explicit constexpr CpuRegister(int r) : reg_(Register(r)) {} + constexpr Register AsRegister() const { return reg_; } - uint8_t LowBits() const { + constexpr uint8_t LowBits() const { return reg_ & 7; } - bool NeedsRex() const { + constexpr bool NeedsRex() const { return reg_ > 7; } private: @@ -47,15 +47,15 @@ std::ostream& operator<<(std::ostream& os, const CpuRegister& reg); class XmmRegister { public: - explicit XmmRegister(FloatRegister r) : reg_(r) {} - explicit XmmRegister(int r) : reg_(FloatRegister(r)) {} - FloatRegister AsFloatRegister() const { + explicit constexpr XmmRegister(FloatRegister r) : reg_(r) {} + explicit constexpr XmmRegister(int r) : reg_(FloatRegister(r)) {} + constexpr FloatRegister AsFloatRegister() const { return reg_; } - uint8_t LowBits() const { + constexpr uint8_t LowBits() const { return reg_ & 7; } - bool NeedsRex() const { + constexpr bool NeedsRex() const { return reg_ > 7; } private: diff --git a/compiler/utils/x86_64/managed_register_x86_64.h b/compiler/utils/x86_64/managed_register_x86_64.h index c4228c1139..32af672670 100644 --- a/compiler/utils/x86_64/managed_register_x86_64.h +++ b/compiler/utils/x86_64/managed_register_x86_64.h @@ -88,52 +88,52 @@ const int kNumberOfAllocIds = kNumberOfCpuAllocIds + kNumberOfXmmAllocIds + // There is a one-to-one mapping between ManagedRegister and register id. class X86_64ManagedRegister : public ManagedRegister { public: - CpuRegister AsCpuRegister() const { + constexpr CpuRegister AsCpuRegister() const { CHECK(IsCpuRegister()); return CpuRegister(static_cast<Register>(id_)); } - XmmRegister AsXmmRegister() const { + constexpr XmmRegister AsXmmRegister() const { CHECK(IsXmmRegister()); return XmmRegister(static_cast<FloatRegister>(id_ - kNumberOfCpuRegIds)); } - X87Register AsX87Register() const { + constexpr X87Register AsX87Register() const { CHECK(IsX87Register()); return static_cast<X87Register>(id_ - (kNumberOfCpuRegIds + kNumberOfXmmRegIds)); } - CpuRegister AsRegisterPairLow() const { + constexpr CpuRegister AsRegisterPairLow() const { CHECK(IsRegisterPair()); // Appropriate mapping of register ids allows to use AllocIdLow(). return FromRegId(AllocIdLow()).AsCpuRegister(); } - CpuRegister AsRegisterPairHigh() const { + constexpr CpuRegister AsRegisterPairHigh() const { CHECK(IsRegisterPair()); // Appropriate mapping of register ids allows to use AllocIdHigh(). return FromRegId(AllocIdHigh()).AsCpuRegister(); } - bool IsCpuRegister() const { + constexpr bool IsCpuRegister() const { CHECK(IsValidManagedRegister()); return (0 <= id_) && (id_ < kNumberOfCpuRegIds); } - bool IsXmmRegister() const { + constexpr bool IsXmmRegister() const { CHECK(IsValidManagedRegister()); const int test = id_ - kNumberOfCpuRegIds; return (0 <= test) && (test < kNumberOfXmmRegIds); } - bool IsX87Register() const { + constexpr bool IsX87Register() const { CHECK(IsValidManagedRegister()); const int test = id_ - (kNumberOfCpuRegIds + kNumberOfXmmRegIds); return (0 <= test) && (test < kNumberOfX87RegIds); } - bool IsRegisterPair() const { + constexpr bool IsRegisterPair() const { CHECK(IsValidManagedRegister()); const int test = id_ - (kNumberOfCpuRegIds + kNumberOfXmmRegIds + kNumberOfX87RegIds); @@ -147,32 +147,32 @@ class X86_64ManagedRegister : public ManagedRegister { // then false is returned. bool Overlaps(const X86_64ManagedRegister& other) const; - static X86_64ManagedRegister FromCpuRegister(Register r) { + static constexpr X86_64ManagedRegister FromCpuRegister(Register r) { CHECK_NE(r, kNoRegister); return FromRegId(r); } - static X86_64ManagedRegister FromXmmRegister(FloatRegister r) { + static constexpr X86_64ManagedRegister FromXmmRegister(FloatRegister r) { return FromRegId(r + kNumberOfCpuRegIds); } - static X86_64ManagedRegister FromX87Register(X87Register r) { + static constexpr X86_64ManagedRegister FromX87Register(X87Register r) { CHECK_NE(r, kNoX87Register); return FromRegId(r + kNumberOfCpuRegIds + kNumberOfXmmRegIds); } - static X86_64ManagedRegister FromRegisterPair(RegisterPair r) { + static constexpr X86_64ManagedRegister FromRegisterPair(RegisterPair r) { CHECK_NE(r, kNoRegisterPair); return FromRegId(r + (kNumberOfCpuRegIds + kNumberOfXmmRegIds + kNumberOfX87RegIds)); } private: - bool IsValidManagedRegister() const { + constexpr bool IsValidManagedRegister() const { return (0 <= id_) && (id_ < kNumberOfRegIds); } - int RegId() const { + constexpr int RegId() const { CHECK(!IsNoRegister()); return id_; } @@ -188,9 +188,9 @@ class X86_64ManagedRegister : public ManagedRegister { friend class ManagedRegister; - explicit X86_64ManagedRegister(int reg_id) : ManagedRegister(reg_id) {} + explicit constexpr X86_64ManagedRegister(int reg_id) : ManagedRegister(reg_id) {} - static X86_64ManagedRegister FromRegId(int reg_id) { + static constexpr X86_64ManagedRegister FromRegId(int reg_id) { X86_64ManagedRegister reg(reg_id); CHECK(reg.IsValidManagedRegister()); return reg; @@ -201,7 +201,7 @@ std::ostream& operator<<(std::ostream& os, const X86_64ManagedRegister& reg); } // namespace x86_64 -inline x86_64::X86_64ManagedRegister ManagedRegister::AsX86_64() const { +constexpr inline x86_64::X86_64ManagedRegister ManagedRegister::AsX86_64() const { x86_64::X86_64ManagedRegister reg(id_); CHECK(reg.IsNoRegister() || reg.IsValidManagedRegister()); return reg; diff --git a/runtime/base/logging.h b/runtime/base/logging.h index 3b5b8b54a5..e9e97b8e57 100644 --- a/runtime/base/logging.h +++ b/runtime/base/logging.h @@ -198,14 +198,14 @@ static constexpr bool kEnableDChecks = true; // types of LHS and RHS. template <typename LHS, typename RHS> struct EagerEvaluator { - EagerEvaluator(LHS l, RHS r) : lhs(l), rhs(r) { } + constexpr EagerEvaluator(LHS l, RHS r) : lhs(l), rhs(r) { } LHS lhs; RHS rhs; }; // Helper function for CHECK_xx. template <typename LHS, typename RHS> -static inline EagerEvaluator<LHS, RHS> MakeEagerEvaluator(LHS lhs, RHS rhs) { +static inline constexpr EagerEvaluator<LHS, RHS> MakeEagerEvaluator(LHS lhs, RHS rhs) { return EagerEvaluator<LHS, RHS>(lhs, rhs); } |