diff options
| -rw-r--r-- | compiler/dex/reg_storage.h | 88 | ||||
| -rw-r--r-- | runtime/base/logging.h | 14 | ||||
| -rw-r--r-- | runtime/utils.h | 5 |
3 files changed, 64 insertions, 43 deletions
diff --git a/compiler/dex/reg_storage.h b/compiler/dex/reg_storage.h index 7e50c311da..3b891f2f20 100644 --- a/compiler/dex/reg_storage.h +++ b/compiler/dex/reg_storage.h @@ -17,6 +17,7 @@ #ifndef ART_COMPILER_DEX_REG_STORAGE_H_ #define ART_COMPILER_DEX_REG_STORAGE_H_ +#include "base/logging.h" namespace art { @@ -102,17 +103,21 @@ class RegStorage { static const uint16_t kHighRegMask = (kHighRegNumMask << kHighRegShift); // Reg is [F][LLLLL], will override any existing shape and use rs_kind. - RegStorage(RegStorageKind rs_kind, int reg) { - DCHECK_NE(rs_kind, k64BitPair); - DCHECK_EQ(rs_kind & ~kShapeMask, 0); - reg_ = kValid | rs_kind | (reg & kRegTypeMask); - } - RegStorage(RegStorageKind rs_kind, int low_reg, int high_reg) { - DCHECK_EQ(rs_kind, k64BitPair); - DCHECK_EQ(low_reg & kFloatingPoint, high_reg & kFloatingPoint); - DCHECK_LE(high_reg & kRegNumMask, kHighRegNumMask) << "High reg must be in 0..31"; - reg_ = kValid | rs_kind | ((high_reg & kHighRegNumMask) << kHighRegShift) | - (low_reg & kRegTypeMask); + constexpr RegStorage(RegStorageKind rs_kind, int reg) + : reg_( + DCHECK_CONSTEXPR(rs_kind != k64BitPair, , 0u) + DCHECK_CONSTEXPR((rs_kind & ~kShapeMask) == 0, , 0u) + kValid | rs_kind | (reg & kRegTypeMask)) { + } + constexpr RegStorage(RegStorageKind rs_kind, int low_reg, int high_reg) + : reg_( + DCHECK_CONSTEXPR(rs_kind == k64BitPair, << rs_kind, 0u) + DCHECK_CONSTEXPR((low_reg & kFloatingPoint) == (high_reg & kFloatingPoint), + << low_reg << ", " << high_reg, 0u) + DCHECK_CONSTEXPR((high_reg & kRegNumMask) <= kHighRegNumMask, + << "High reg must be in 0..31: " << high_reg, false) + kValid | rs_kind | ((high_reg & kHighRegNumMask) << kHighRegShift) | + (low_reg & kRegTypeMask)) { } constexpr explicit RegStorage(uint16_t val) : reg_(val) {} RegStorage() : reg_(kInvalid) {} @@ -125,50 +130,53 @@ class RegStorage { return (reg_ != rhs.GetRawBits()); } - bool Valid() const { + constexpr bool Valid() const { return ((reg_ & kValidMask) == kValid); } - bool Is32Bit() const { + constexpr bool Is32Bit() const { return ((reg_ & kShapeMask) == k32BitSolo); } - bool Is64Bit() const { + constexpr bool Is64Bit() const { return ((reg_ & k64BitMask) == k64Bits); } - bool Is64BitSolo() const { + constexpr bool Is64BitSolo() const { return ((reg_ & kShapeMask) == k64BitSolo); } - bool IsPair() const { + constexpr bool IsPair() const { return ((reg_ & kShapeMask) == k64BitPair); } - bool IsFloat() const { - DCHECK(Valid()); - return ((reg_ & kFloatingPoint) == kFloatingPoint); + constexpr bool IsFloat() const { + return + DCHECK_CONSTEXPR(Valid(), , false) + ((reg_ & kFloatingPoint) == kFloatingPoint); } - bool IsDouble() const { - DCHECK(Valid()); - return (reg_ & (kFloatingPoint | k64BitMask)) == (kFloatingPoint | k64Bits); + constexpr bool IsDouble() const { + return + DCHECK_CONSTEXPR(Valid(), , false) + (reg_ & (kFloatingPoint | k64BitMask)) == (kFloatingPoint | k64Bits); } - bool IsSingle() const { - DCHECK(Valid()); - return (reg_ & (kFloatingPoint | k64BitMask)) == kFloatingPoint; + constexpr bool IsSingle() const { + return + DCHECK_CONSTEXPR(Valid(), , false) + (reg_ & (kFloatingPoint | k64BitMask)) == kFloatingPoint; } - static bool IsFloat(uint16_t reg) { + static constexpr bool IsFloat(uint16_t reg) { return ((reg & kFloatingPoint) == kFloatingPoint); } - static bool IsDouble(uint16_t reg) { + static constexpr bool IsDouble(uint16_t reg) { return (reg & (kFloatingPoint | k64BitMask)) == (kFloatingPoint | k64Bits); } - static bool IsSingle(uint16_t reg) { + static constexpr bool IsSingle(uint16_t reg) { return (reg & (kFloatingPoint | k64BitMask)) == kFloatingPoint; } @@ -221,17 +229,17 @@ class RegStorage { } // Return the register number of low or solo. - int GetRegNum() const { + constexpr int GetRegNum() const { return reg_ & kRegNumMask; } // Is register number in 0..7? - bool Low8() const { + constexpr bool Low8() const { return GetRegNum() < 8; } // Is register number in 0..3? - bool Low4() const { + constexpr bool Low4() const { return GetRegNum() < 4; } @@ -244,11 +252,11 @@ class RegStorage { return RegStorage(k64BitPair, low.GetReg(), high.GetReg()); } - static bool SameRegType(RegStorage reg1, RegStorage reg2) { + static constexpr bool SameRegType(RegStorage reg1, RegStorage reg2) { return (reg1.IsDouble() == reg2.IsDouble()) && (reg1.IsSingle() == reg2.IsSingle()); } - static bool SameRegType(int reg1, int reg2) { + static constexpr bool SameRegType(int reg1, int reg2) { return (IsDouble(reg1) == IsDouble(reg2)) && (IsSingle(reg1) == IsSingle(reg2)); } @@ -258,17 +266,17 @@ class RegStorage { } // Create a floating point 32-bit solo. - static RegStorage FloatSolo32(int reg_num) { + static constexpr RegStorage FloatSolo32(int reg_num) { return RegStorage(k32BitSolo, (reg_num & kRegNumMask) | kFloatingPoint); } // Create a 128-bit solo. - static RegStorage Solo128(int reg_num) { + static constexpr RegStorage Solo128(int reg_num) { return RegStorage(k128BitSolo, reg_num & kRegTypeMask); } // Create a 64-bit solo. - static RegStorage Solo64(int reg_num) { + static constexpr RegStorage Solo64(int reg_num) { return RegStorage(k64BitSolo, reg_num & kRegTypeMask); } @@ -277,19 +285,19 @@ class RegStorage { return RegStorage(k64BitSolo, (reg_num & kRegNumMask) | kFloatingPoint); } - static RegStorage InvalidReg() { + static constexpr RegStorage InvalidReg() { return RegStorage(kInvalid); } - static uint16_t RegNum(int raw_reg_bits) { + static constexpr uint16_t RegNum(int raw_reg_bits) { return raw_reg_bits & kRegNumMask; } - int GetRawBits() const { + constexpr int GetRawBits() const { return reg_; } - size_t StorageSize() { + size_t StorageSize() const { switch (reg_ & kShapeMask) { case kInvalid: return 0; case k32BitSolo: return 4; diff --git a/runtime/base/logging.h b/runtime/base/logging.h index 814195c7fa..caeb946ff0 100644 --- a/runtime/base/logging.h +++ b/runtime/base/logging.h @@ -66,6 +66,16 @@ } \ } while (false) +// CHECK that can be used in a constexpr function. For example, +// constexpr int half(int n) { +// return +// DCHECK_CONSTEXPR(n >= 0, , 0) +// CHECK_CONSTEXPR((n & 1) == 0), << "Extra debugging output: n = " << n, 0) +// n / 2; +// } +#define CHECK_CONSTEXPR(x, out, dummy) \ + (UNLIKELY(!(x))) ? (LOG(FATAL) << "Check failed: " << #x out, dummy) : + #ifndef NDEBUG #define DCHECK(x) CHECK(x) @@ -77,6 +87,7 @@ #define DCHECK_GT(x, y) CHECK_GT(x, y) #define DCHECK_STREQ(s1, s2) CHECK_STREQ(s1, s2) #define DCHECK_STRNE(s1, s2) CHECK_STRNE(s1, s2) +#define DCHECK_CONSTEXPR(x, out, dummy) CHECK_CONSTEXPR(x, out, dummy) #else // NDEBUG @@ -116,6 +127,9 @@ while (false) \ CHECK_STRNE(str1, str2) +#define DCHECK_CONSTEXPR(x, out, dummy) \ + (false && (x)) ? (dummy) : + #endif #define LOG(severity) ::art::LogMessage(__FILE__, __LINE__, severity, -1).stream() diff --git a/runtime/utils.h b/runtime/utils.h index 6a4198fcfc..6d52459ec8 100644 --- a/runtime/utils.h +++ b/runtime/utils.h @@ -140,9 +140,8 @@ struct TypeIdentity { template<typename T> static constexpr T RoundDown(T x, typename TypeIdentity<T>::type n) { return - // DCHECK(IsPowerOfTwo(n)) in a form acceptable in a constexpr function: - (kIsDebugBuild && !IsPowerOfTwo(n)) ? (LOG(FATAL) << n << " isn't a power of 2", T(0)) - : (x & -n); + DCHECK_CONSTEXPR(IsPowerOfTwo(n), , T(0)) + (x & -n); } template<typename T> |