Bug 1663902 - Avoid gcc emitting lots of static constructors for UnusedZero<T&>::defaultValue. r=dmajor

Differential Revision: https://phabricator.services.mozilla.com/D90359
This commit is contained in:
Simon Giesecke 2020-09-16 13:58:49 +00:00
Родитель 68133a2ff8
Коммит 59cd4601d7
3 изменённых файлов: 23 добавлений и 8 удалений

Просмотреть файл

@ -119,7 +119,13 @@ class ResultImplementationNullIsOkBase {
using ErrorStorageType = typename UnusedZero<E>::StorageType;
static constexpr auto kNullValue = UnusedZero<E>::nullValue;
static inline const auto kMovedFromMarker = UnusedZero<E>::defaultValue;
// This is static function rather than a static data member in order to avoid
// that gcc emits lots of static constructors. It may be changed to a static
// constexpr data member with C++20.
static inline auto GetMovedFromMarker() {
return UnusedZero<E>::GetDefaultValue();
}
static_assert(std::is_trivially_copyable_v<ErrorStorageType>);
static_assert(kNullValue == decltype(kNullValue)(0));
@ -154,7 +160,7 @@ class ResultImplementationNullIsOkBase {
if (isOk()) {
new (mValue.first().addr()) V(std::move(*aOther.mValue.first().addr()));
aOther.mValue.first().addr()->~V();
aOther.mValue.second() = kMovedFromMarker;
aOther.mValue.second() = GetMovedFromMarker();
}
}
}
@ -170,7 +176,7 @@ class ResultImplementationNullIsOkBase {
if (isOk()) {
new (mValue.first().addr()) V(std::move(*aOther.mValue.first().addr()));
aOther.mValue.first().addr()->~V();
aOther.mValue.second() = kMovedFromMarker;
aOther.mValue.second() = GetMovedFromMarker();
}
}
return *this;
@ -322,8 +328,13 @@ struct UnusedZero<T&> {
static constexpr bool value = true;
static inline StorageType const defaultValue =
reinterpret_cast<StorageType>(~ptrdiff_t(0));
// This is static function rather than a static data member in order to avoid
// that gcc emits lots of static constructors. It may be changed to a static
// constexpr data member using bit_cast with C++20.
static inline StorageType GetDefaultValue() {
return reinterpret_cast<StorageType>(~ptrdiff_t(0));
}
static constexpr StorageType nullValue = nullptr;
static constexpr const T& Inspect(StorageType aValue) {
@ -338,7 +349,7 @@ struct UnusedZero<T&> {
private:
static constexpr void AssertValid(StorageType aValue) {
MOZ_ASSERT(aValue != defaultValue);
MOZ_ASSERT(aValue != GetDefaultValue());
}
};

Просмотреть файл

@ -23,7 +23,10 @@ struct UnusedZero<UnusedZeroEnum> {
static constexpr bool value = true;
static constexpr StorageType nullValue = UnusedZeroEnum::Ok;
static constexpr StorageType defaultValue = UnusedZeroEnum::NotOk;
static constexpr StorageType GetDefaultValue() {
return UnusedZeroEnum::NotOk;
}
static constexpr void AssertValid(StorageType aValue) {}
static constexpr const UnusedZeroEnum& Inspect(const StorageType& aValue) {

Просмотреть файл

@ -223,7 +223,8 @@ struct UnusedZero<nsresult> {
static constexpr bool value = true;
static constexpr StorageType nullValue = NS_OK;
static constexpr StorageType defaultValue = NS_ERROR_FAILURE;
static constexpr StorageType GetDefaultValue() { return NS_ERROR_FAILURE; }
static constexpr void AssertValid(StorageType aValue) {}
static constexpr const nsresult& Inspect(const StorageType& aValue) {