From c2b022c174fd052d1e1687e39c17100322c8ff5f Mon Sep 17 00:00:00 2001 From: Chris Kennelly Date: Tue, 14 Jul 2026 08:08:17 -0700 Subject: [PATCH] De-std::atomic Span::allocated_. This prevents the compiler from merging redundant load/store operations. This is especially pronounced on InsertRange, while RemoveRange appears to have enough memory pressure that we will need to spill anyways. Since the turndown of the fragmentation profile, we no longer need to keep `Span::Allocated()` safe for accessing across threads so an ordinary integer will suffice. PiperOrigin-RevId: 947690429 --- tcmalloc/span.h | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/tcmalloc/span.h b/tcmalloc/span.h index a7a90998f..cdee263f6 100644 --- a/tcmalloc/span.h +++ b/tcmalloc/span.h @@ -86,7 +86,7 @@ class ABSL_CACHELINE_ALIGNED Span final : public SpanList::Elem { constexpr Span() : embed_count_(0), freelist_(0), - allocated_(std::numeric_limits::max()), + allocated_{std::numeric_limits::max()}, cache_size_(0), is_long_lived_span_(0), nonempty_index_(0), @@ -100,7 +100,7 @@ class ABSL_CACHELINE_ALIGNED Span final : public SpanList::Elem { explicit Span(Range r) : embed_count_(0), freelist_(0), - allocated_(0), + allocated_{0}, cache_size_(0), is_long_lived_span_(0), nonempty_index_(0), @@ -304,7 +304,18 @@ class ABSL_CACHELINE_ALIGNED Span final : public SpanList::Elem { uint16_t embed_count_; uint16_t freelist_; }; - std::atomic allocated_; // Number of non-free objects +#ifdef TCMALLOC_INTERNAL_LEGACY_LOCKING + std::atomic +#else + struct { + uint16_t value; + + uint16_t load(std::memory_order) const { return value; } + + void store(uint16_t v, std::memory_order) { value = v; } + } +#endif + allocated_; // Number of non-free objects #ifndef TCMALLOC_INTERNAL_LEGACY_LOCKING uint8_t cache_size_; #else