Small improvements:

- remove a branch from InternalExtend
 - remove redundant Destroy call
 - dedup UnsafeArenaAddAllocated
 - fix test

PiperOrigin-RevId: 592804776
pull/15162/head
Protobuf Team Bot 1 year ago committed by Copybara-Service
parent 706c0d03f8
commit 68f5ffb3a9
  1. 12
      src/google/protobuf/repeated_field_unittest.cc
  2. 9
      src/google/protobuf/repeated_ptr_field.cc
  3. 6
      src/google/protobuf/repeated_ptr_field.h

@ -1035,7 +1035,7 @@ TEST(Movable, Works) {
EXPECT_FALSE(internal::IsMovable<NonMovable>::value);
}
TEST(RepeatedField, MoveAdd) {
TEST(RepeatedPtrField, MoveAdd) {
RepeatedPtrField<TestAllTypes> field;
TestAllTypes test_all_types;
auto* optional_nested_message =
@ -1911,9 +1911,12 @@ TEST(RepeatedPtrField, SmallOptimization) {
// Verify the string is where we think it is.
EXPECT_EQ(&*array->begin(), &str);
EXPECT_EQ(array->pointer_begin()[0], &str);
auto is_inlined = [array]() {
return std::less_equal<void*>{}(array, &*array->pointer_begin()) &&
std::less<void*>{}(&*array->pointer_begin(), array + 1);
};
// The T** in pointer_begin points into the sso in the object.
EXPECT_TRUE(std::less_equal<void*>{}(array, &*array->pointer_begin()));
EXPECT_TRUE(std::less_equal<void*>{}(&*array->pointer_begin(), array + 1));
EXPECT_TRUE(is_inlined());
// Adding a second object stops sso.
std::string str2;
@ -1925,8 +1928,7 @@ TEST(RepeatedPtrField, SmallOptimization) {
// We used some arena space now.
EXPECT_LT(usage_before, arena.SpaceUsed());
// And the pointer_begin is not in the sso anymore.
EXPECT_FALSE(std::less_equal<void*>{}(array, &*array->pointer_begin()) &&
std::less_equal<void*>{}(&*array->pointer_begin(), array + 1));
EXPECT_FALSE(is_inlined());
}
TEST(RepeatedPtrField, CopyAssign) {

@ -9,6 +9,8 @@
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
#include "google/protobuf/repeated_ptr_field.h"
#include <algorithm>
#include <cstddef>
#include <cstdint>
@ -59,11 +61,8 @@ void** RepeatedPtrFieldBase::InternalExtend(int extend_amount) {
new_rep->elements[0] = tagged_rep_or_elem_;
} else {
Rep* old_rep = rep();
if (old_rep->allocated_size > 0) {
memcpy(new_rep->elements, old_rep->elements,
old_rep->allocated_size * ptr_size);
}
new_rep->allocated_size = old_rep->allocated_size;
memcpy(new_rep, old_rep,
old_rep->allocated_size * ptr_size + kRepHeaderSize);
size_t old_size = capacity * ptr_size + kRepHeaderSize;
if (arena == nullptr) {

@ -488,20 +488,20 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase {
// Pass value_arena and my_arena to avoid duplicate virtual call (value)
// or load (mine).
Value<TypeHandler>* value, Arena* value_arena, Arena* my_arena) {
using H = CommonHandler<TypeHandler>;
// Ensure that either the value is in the same arena, or if not, we do the
// appropriate thing: Own() it (if it's on heap and we're in an arena) or
// copy it to our arena/heap (otherwise).
if (my_arena != nullptr && value_arena == nullptr) {
my_arena->Own(value);
} else if (my_arena != value_arena) {
ABSL_DCHECK(value_arena != nullptr);
auto* new_value = TypeHandler::NewFromPrototype(value, my_arena);
using H = CommonHandler<TypeHandler>;
H::Merge(*value, new_value);
H::Delete(value, value_arena);
value = new_value;
}
UnsafeArenaAddAllocated<TypeHandler>(value);
UnsafeArenaAddAllocated<H>(value);
}
template <typename TypeHandler>

Loading…
Cancel
Save