Skip to content

Commit 5680834

Browse files
Turn on the inline buffer in 32-bit mode too.
Easier to maintain when there are less special cases, and no reason to waste the potential savings for very small strings. PiperOrigin-RevId: 739299996
1 parent 1c973ef commit 5680834

File tree

2 files changed

+32
-18
lines changed

2 files changed

+32
-18
lines changed

src/google/protobuf/micro_string.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class PROTOBUF_EXPORT MicroString {
7777

7878
public:
7979
#if defined(ABSL_IS_LITTLE_ENDIAN)
80-
static constexpr bool kHasInlineRep = sizeof(uintptr_t) >= 8;
80+
static constexpr bool kHasInlineRep = true;
8181
#else
8282
// For now, disable the inline rep if not in little endian.
8383
// We can revisit this later if performance in such platforms is relevant.
@@ -228,6 +228,7 @@ class PROTOBUF_EXPORT MicroString {
228228
}
229229
};
230230

231+
static_assert(alignof(void*) >= 4, "We need two tag bits from pointers.");
231232
static constexpr uintptr_t kIsLargeRepTag = 0x1;
232233
static_assert(sizeof(UnownedPayload::for_tag) == kIsLargeRepTag,
233234
"See comment in for_tag declaration above.");
@@ -484,11 +485,14 @@ void MicroString::SetInChunks(size_t size, Arena* arena, F setter,
484485

485486
template <size_t RequestedSpace>
486487
class MicroStringExtraImpl : private MicroString {
488+
static constexpr size_t RoundUp(size_t n) {
489+
return (n + (alignof(MicroString) - 1)) & ~(alignof(MicroString) - 1);
490+
}
491+
487492
public:
488493
// Round up to avoid padding
489494
static constexpr size_t kInlineCapacity =
490-
((RequestedSpace - MicroString::kInlineCapacity + 7) & ~7) +
491-
MicroString::kInlineCapacity;
495+
RoundUp(RequestedSpace + /* inline_size */ 1) - /* inline_size */ 1;
492496

493497
static_assert(kInlineCapacity < MicroString::kMaxInlineCapacity,
494498
"Must fit with the tags.");

src/google/protobuf/micro_string_test.cc

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ enum PreviousState { kInline, kMicroRep, kOwned, kUnowned, kString, kAlias };
4747
static constexpr auto kUnownedPayload =
4848
MicroString::MakeUnownedPayload("0123456789");
4949

50+
static constexpr auto kInlineInput =
51+
absl::string_view("0123456789").substr(0, MicroString::kInlineCapacity);
52+
5053
class MicroStringPrevTest
5154
: public testing::TestWithParam<std::tuple<bool, PreviousState>> {
5255
protected:
@@ -157,7 +160,7 @@ INSTANTIATE_TEST_SUITE_P(MicroStringTransitionTest, MicroStringPrevTest,
157160

158161
TEST(MicroStringTest, InlineIsEnabledWhenExpected) {
159162
#if defined(ABSL_IS_LITTLE_ENDIAN)
160-
constexpr bool kExpectInline = sizeof(uintptr_t) >= 8;
163+
constexpr bool kExpectInline = true;
161164
#else
162165
constexpr bool kExpectInline = false;
163166
#endif
@@ -266,21 +269,24 @@ TEST(MicroStringTest, SupportsExpectedInputTypes) {
266269

267270
template <int N>
268271
void TestExtraCapacity(int expected_sizeof) {
269-
EXPECT_EQ(sizeof(MicroStringExtra<N>), expected_sizeof);
270-
EXPECT_EQ(MicroStringExtra<N>::kInlineCapacity, expected_sizeof - 1);
272+
EXPECT_EQ(sizeof(MicroStringExtra<N>), expected_sizeof) << N;
273+
EXPECT_EQ(MicroStringExtra<N>::kInlineCapacity, expected_sizeof - 1) << N;
271274
}
272275

273276
TEST(MicroStringTest, ExtraRequestedInlineSpace) {
274277
if (!MicroString::kHasInlineRep) {
275278
GTEST_SKIP() << "Inline is not active";
276279
}
277-
TestExtraCapacity<0>(8);
278-
TestExtraCapacity<1>(8);
279-
TestExtraCapacity<7>(8);
280-
TestExtraCapacity<8>(16);
281-
TestExtraCapacity<15>(16);
282-
TestExtraCapacity<16>(24);
283-
TestExtraCapacity<23>(24);
280+
// We write in terms of steps to support 64 and 32 bits.
281+
static constexpr size_t kStep = alignof(MicroString);
282+
TestExtraCapacity<0 * kStep + 0>(1 * kStep);
283+
TestExtraCapacity<0 * kStep + 1>(1 * kStep);
284+
TestExtraCapacity<1 * kStep - 1>(1 * kStep);
285+
TestExtraCapacity<1 * kStep + 0>(2 * kStep);
286+
TestExtraCapacity<2 * kStep - 1>(2 * kStep);
287+
TestExtraCapacity<2 * kStep + 0>(3 * kStep);
288+
TestExtraCapacity<3 * kStep - 1>(3 * kStep);
289+
TestExtraCapacity<3 * kStep + 0>(4 * kStep);
284290
}
285291

286292
TEST(MicroStringTest, CapacityIsRoundedUpOnArena) {
@@ -364,7 +370,7 @@ TEST_P(MicroStringPrevTest, SetInline) {
364370
GTEST_SKIP() << "Inline is not active";
365371
}
366372

367-
const absl::string_view input("ABCD");
373+
const absl::string_view input = kInlineInput;
368374
const size_t used = arena_space_used();
369375
const size_t self_used = str_.SpaceUsedExcludingSelfLong();
370376
str_.Set(input, arena());
@@ -414,7 +420,7 @@ TEST_P(MicroStringPrevTest, SetAliasSmall) {
414420
if (!MicroString::kHasInlineRep) {
415421
GTEST_SKIP() << "Inline is not active";
416422
}
417-
const absl::string_view input("ABC");
423+
const absl::string_view input = kInlineInput;
418424

419425
const size_t used = arena_space_used();
420426
const size_t self_used = str_.SpaceUsedExcludingSelfLong();
@@ -430,8 +436,11 @@ TEST_P(MicroStringPrevTest, SetAliasSmall) {
430436
}
431437
EXPECT_EQ(out, input);
432438

433-
// We should not need to allocate memory here in any case.
434-
ExpectMemoryUsed(used, false, self_used);
439+
// In 32-bit mode, we will use memory that is not rounded to the arena
440+
// alignment because sizeof(LargeRep)==12. Avoid using `ExpectMemoryUsed`
441+
// because it expects it.
442+
EXPECT_EQ(0, arena_space_used() - used);
443+
EXPECT_EQ(self_used, str_.SpaceUsedExcludingSelfLong());
435444
}
436445

437446
TEST_P(MicroStringPrevTest, SetAliasLarge) {
@@ -895,7 +904,8 @@ TEST(MicroStringExtraTest, SetStringUsesInlineSpace) {
895904
const size_t used_in_string = StringSpaceUsedExcludingSelfLong(large);
896905
str.Set(std::move(large), &arena);
897906
// This one is too big, so we move the whole std::string.
898-
EXPECT_EQ(kLargeRepSize + sizeof(std::string), arena.SpaceUsed() - used);
907+
EXPECT_EQ(ArenaAlignDefault::Ceil(kLargeRepSize + sizeof(std::string)),
908+
arena.SpaceUsed() - used);
899909
EXPECT_EQ(kLargeRepSize + sizeof(std::string) + used_in_string,
900910
str.SpaceUsedExcludingSelfLong());
901911
}

0 commit comments

Comments
 (0)