summaryrefslogtreecommitdiff
path: root/absl/time/time.h
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2023-02-02 03:05:07 -0800
committerGravatar Copybara-Service <copybara-worker@google.com>2023-02-02 03:05:54 -0800
commit7005fede1e309d0a6070be3008b365112492aa80 (patch)
tree99968e37829bea518b344d13e286bd54508aa656 /absl/time/time.h
parent9858e5421b14c9d72f2103af10010c5452c6d55f (diff)
Get rid of tail padding within `absl::Duration`. This reduces memory usage needs when storing duration in containers (e.g. `vector<absl::Duration>` uses 25% less memory), and allows classes with `absl::Duration` fields to fit other stuff in memory previously used by tail padding (e.g. `std::optional<absl::Duration>` is now 16 bytes instead of 24).
PiperOrigin-RevId: 506568782 Change-Id: Ic9e077f02a80da013fb2d312aff77761b970c07a
Diffstat (limited to 'absl/time/time.h')
-rw-r--r--absl/time/time.h73
1 files changed, 3 insertions, 70 deletions
diff --git a/absl/time/time.h b/absl/time/time.h
index bf1007c2..cc390082 100644
--- a/absl/time/time.h
+++ b/absl/time/time.h
@@ -84,7 +84,6 @@ struct timeval;
#include <type_traits>
#include <utility>
-#include "absl/base/config.h"
#include "absl/base/macros.h"
#include "absl/strings/string_view.h"
#include "absl/time/civil_time.h"
@@ -215,7 +214,7 @@ class Duration {
template <typename H>
friend H AbslHashValue(H h, Duration d) {
- return H::combine(std::move(h), d.rep_hi_.Get(), d.rep_lo_);
+ return H::combine(std::move(h), d.rep_hi_, d.rep_lo_);
}
private:
@@ -224,73 +223,7 @@ class Duration {
friend constexpr Duration time_internal::MakeDuration(int64_t hi,
uint32_t lo);
constexpr Duration(int64_t hi, uint32_t lo) : rep_hi_(hi), rep_lo_(lo) {}
-
- // We store `hi_rep_` 4-byte rather than 8-byte aligned to avoid 4 bytes of
- // tail padding.
- class HiRep {
- public:
- // Default constructor default-initializes `hi_`, which has the same
- // semantics as default-initializing an `int64_t` (undetermined value).
- HiRep() = default;
-
- HiRep(const HiRep&) = default;
- HiRep& operator=(const HiRep&) = default;
-
- explicit constexpr HiRep(const int64_t value)
- : // C++17 forbids default-initialization in constexpr contexts. We can
- // remove this in C++20.
- lo_(0),
- hi_(0) {
- *this = value;
- }
-
- constexpr int64_t Get() const {
- const uint64_t unsigned_value =
- (static_cast<uint64_t>(hi_) << 32) | static_cast<uint64_t>(lo_);
- // `static_cast<int64_t>(unsigned_value)` is implementation-defined
- // before c++20. On all supported platforms the behaviour is that mandated
- // by c++20, i.e. "If the destination type is signed, [...] the result is
- // the unique value of the destination type equal to the source value
- // modulo 2^n, where n is the number of bits used to represent the
- // destination type."
- static_assert(
- (static_cast<int64_t>((std::numeric_limits<uint64_t>::max)()) ==
- int64_t{-1}) &&
- (static_cast<int64_t>(static_cast<uint64_t>(
- (std::numeric_limits<int64_t>::max)()) +
- 1) ==
- (std::numeric_limits<int64_t>::min)()),
- "static_cast<int64_t>(uint64_t) does not have c++20 semantics");
- return static_cast<int64_t>(unsigned_value);
- }
-
- constexpr HiRep& operator=(const int64_t value) {
- // "If the destination type is unsigned, the resulting value is the
- // smallest unsigned value equal to the source value modulo 2^n
- // where `n` is the number of bits used to represent the destination
- // type".
- const auto unsigned_value = static_cast<uint64_t>(value);
- hi_ = static_cast<uint32_t>(unsigned_value >> 32);
- lo_ = static_cast<uint32_t>(unsigned_value);
- return *this;
- }
-
- private:
- // Notes:
- // - Ideally we would use a `char[]` and `std::bitcast`, but the latter
- // does not exist (and is not constexpr in `absl`) before c++20.
- // - Order is optimized depending on endianness so that the compiler can
- // turn `Get()` (resp. `operator=()`) into a single 8-byte load (resp.
- // store).
-#if defined(ABSL_IS_BIG_ENDIAN) && ABSL_IS_BIG_ENDIAN
- uint32_t hi_;
- uint32_t lo_;
-#else
- uint32_t lo_;
- uint32_t hi_;
-#endif
- };
- HiRep rep_hi_;
+ int64_t rep_hi_;
uint32_t rep_lo_;
};
@@ -1558,7 +1491,7 @@ ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration MakeNormalizedDuration(
// Provide access to the Duration representation.
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr int64_t GetRepHi(Duration d) {
- return d.rep_hi_.Get();
+ return d.rep_hi_;
}
ABSL_ATTRIBUTE_CONST_FUNCTION constexpr uint32_t GetRepLo(Duration d) {
return d.rep_lo_;