Store string block sizes as uint16_ts instead of uint32_ts, which allows us to avoid using a bit field for heap_allocated_/allocated_size_.

PiperOrigin-RevId: 617974456
pull/16248/head
Protobuf Team Bot 11 months ago committed by Copybara-Service
parent 0c6aa9557a
commit 85b20391e0
  1. 36
      src/google/protobuf/string_block.h

@ -82,35 +82,37 @@ class alignas(std::string) StringBlock {
size_t effective_size() const; size_t effective_size() const;
private: private:
using size_type = uint16_t;
static_assert(alignof(std::string) <= sizeof(void*), ""); static_assert(alignof(std::string) <= sizeof(void*), "");
static_assert(alignof(std::string) <= ArenaAlignDefault::align, ""); static_assert(alignof(std::string) <= ArenaAlignDefault::align, "");
~StringBlock() = default; ~StringBlock() = default;
explicit StringBlock(StringBlock* next, bool heap_allocated, uint32_t size, explicit StringBlock(StringBlock* next, bool heap_allocated, size_type size,
uint32_t next_size) noexcept size_type next_size) noexcept
: next_(next), : next_(next),
heap_allocated_(heap_allocated),
allocated_size_(size), allocated_size_(size),
next_size_(next_size) {} next_size_(next_size),
heap_allocated_(heap_allocated) {}
static constexpr uint32_t min_size() { return size_t{256}; } static constexpr size_type min_size() { return size_type{256}; }
static constexpr uint32_t max_size() { return size_t{8192}; } static constexpr size_type max_size() { return size_type{8192}; }
// Returns `size` rounded down such that we can fit a perfect number // Returns `size` rounded down such that we can fit a perfect number
// of std::string instances inside a StringBlock of that size. // of std::string instances inside a StringBlock of that size.
static constexpr uint32_t RoundedSize(uint32_t size); static constexpr size_type RoundedSize(size_type size);
// Returns the size of the next block. // Returns the size of the next block.
size_t next_size() const { return next_size_; } size_t next_size() const { return next_size_; }
StringBlock* const next_; StringBlock* const next_;
const bool heap_allocated_ : 1; const size_type allocated_size_;
const uint32_t allocated_size_ : 31; const size_type next_size_;
const uint32_t next_size_; const bool heap_allocated_;
}; };
constexpr uint32_t StringBlock::RoundedSize(uint32_t size) { constexpr StringBlock::size_type StringBlock::RoundedSize(size_type size) {
return size - (size - sizeof(StringBlock)) % sizeof(std::string); return size - (size - sizeof(StringBlock)) % sizeof(std::string);
} }
@ -119,10 +121,10 @@ inline size_t StringBlock::NextSize(StringBlock* block) {
} }
inline StringBlock* StringBlock::Emplace(void* p, size_t n, StringBlock* next) { inline StringBlock* StringBlock::Emplace(void* p, size_t n, StringBlock* next) {
const auto count = static_cast<uint32_t>(n); const auto count = static_cast<size_type>(n);
ABSL_DCHECK_EQ(count, NextSize(next)); ABSL_DCHECK_EQ(count, NextSize(next));
uint32_t doubled = count * 2; size_type doubled = count * 2;
uint32_t next_size = next ? std::min(doubled, max_size()) : min_size(); size_type next_size = next ? std::min(doubled, max_size()) : min_size();
return new (p) StringBlock(next, false, RoundedSize(count), next_size); return new (p) StringBlock(next, false, RoundedSize(count), next_size);
} }
@ -130,11 +132,11 @@ inline StringBlock* StringBlock::New(StringBlock* next) {
// Compute required size, rounding down to a multiple of sizeof(std:string) // Compute required size, rounding down to a multiple of sizeof(std:string)
// so that we can optimize the allocation path. I.e., we incur a (constant // so that we can optimize the allocation path. I.e., we incur a (constant
// size) MOD() operation cost here to avoid any MUL() later on. // size) MOD() operation cost here to avoid any MUL() later on.
uint32_t size = min_size(); size_type size = min_size();
uint32_t next_size = min_size(); size_type next_size = min_size();
if (next) { if (next) {
size = next->next_size_; size = next->next_size_;
next_size = std::min(size * 2, max_size()); next_size = std::min<size_type>(size * 2, max_size());
} }
size = RoundedSize(size); size = RoundedSize(size);
void* p = ::operator new(size); void* p = ::operator new(size);

Loading…
Cancel
Save