Skip to content

Commit b4a7757

Browse files
ezbrcopybara-github
authored andcommitted
Further refactoring in preparation for RepeatedField SOO: avoid repeated calls to accessors within the same functions.
Motivation: these accessors (e.g. size(), Capacity()) will have branches on `is_soo()` so it's best to avoid calling them repeatedly if we can instead save the result in a local variable. Also update some comments to avoid referring to the names of data members that will no longer exist with SOO. PiperOrigin-RevId: 653672810
1 parent cf948e4 commit b4a7757

File tree

2 files changed

+59
-45
lines changed

2 files changed

+59
-45
lines changed

src/google/protobuf/repeated_field.h

Lines changed: 57 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -387,9 +387,9 @@ class RepeatedField final
387387
// Reserves space to expand the field to at least the given size.
388388
// If the array is grown, it will always be at least doubled in size.
389389
// If `annotate_size` is true (the default), then this function will annotate
390-
// the old container from `old_size` to `capacity_` (unpoison memory)
390+
// the old container from `old_size` to `Capacity()` (unpoison memory)
391391
// directly before it is being released, and annotate the new container from
392-
// `capacity_` to `old_size` (poison unused memory).
392+
// `Capacity()` to `old_size` (poison unused memory).
393393
void Grow(int old_size, int new_size);
394394
void GrowNoAnnotate(int old_size, int new_size);
395395

@@ -410,10 +410,10 @@ class RepeatedField final
410410
}
411411
}
412412

413-
// Replaces size_ with new_size and returns the previous value of
414-
// size_. This function is intended to be the only place where
415-
// size_ is modified, with the exception of `AddInputIterator()`
416-
// where the size of added items is not known in advance.
413+
// Replaces size with new_size and returns the previous value of size. This
414+
// function is intended to be the only place where size is modified, with the
415+
// exception of `AddInputIterator()` where the size of added items is not
416+
// known in advance.
417417
inline int ExchangeCurrentSize(int new_size) {
418418
const int prev_size = size();
419419
AnnotateSize(prev_size, new_size);
@@ -422,7 +422,7 @@ class RepeatedField final
422422
}
423423

424424
// Returns a pointer to elements array.
425-
// pre-condition: the array must have been allocated.
425+
// pre-condition: Capacity() > 0.
426426
Element* elements() const {
427427
ABSL_DCHECK_GT(Capacity(), 0);
428428
// Because of above pre-condition this cast is safe.
@@ -612,12 +612,14 @@ inline Element* RepeatedField<Element>::AddNAlreadyReserved(int n)
612612
template <typename Element>
613613
inline void RepeatedField<Element>::Resize(int new_size, const Element& value) {
614614
ABSL_DCHECK_GE(new_size, 0);
615-
if (new_size > size()) {
616-
if (new_size > Capacity()) Grow(size(), new_size);
615+
const int old_size = size();
616+
if (new_size > old_size) {
617+
if (new_size > Capacity()) Grow(old_size, new_size);
617618
Element* first = elements() + ExchangeCurrentSize(new_size);
618-
std::uninitialized_fill(first, elements() + size(), value);
619-
} else if (new_size < size()) {
620-
Destroy(unsafe_elements() + new_size, unsafe_elements() + size());
619+
std::uninitialized_fill(first, elements() + new_size, value);
620+
} else if (new_size < old_size) {
621+
Element* elem = unsafe_elements();
622+
Destroy(elem + new_size, elem + old_size);
621623
ExchangeCurrentSize(new_size);
622624
}
623625
}
@@ -663,14 +665,15 @@ inline void RepeatedField<Element>::Set(int index, const Element& value) {
663665

664666
template <typename Element>
665667
inline void RepeatedField<Element>::Add(Element value) {
668+
const int old_size = size();
666669
int capacity = Capacity();
667670
Element* elem = unsafe_elements();
668-
if (ABSL_PREDICT_FALSE(size() == capacity)) {
669-
Grow(size(), size() + 1);
671+
if (ABSL_PREDICT_FALSE(old_size == capacity)) {
672+
Grow(old_size, old_size + 1);
670673
capacity = Capacity();
671674
elem = unsafe_elements();
672675
}
673-
int new_size = size() + 1;
676+
int new_size = old_size + 1;
674677
void* p = elem + ExchangeCurrentSize(new_size);
675678
::new (p) Element(std::move(value));
676679

@@ -682,21 +685,23 @@ inline void RepeatedField<Element>::Add(Element value) {
682685

683686
template <typename Element>
684687
inline Element* RepeatedField<Element>::Add() ABSL_ATTRIBUTE_LIFETIME_BOUND {
685-
if (ABSL_PREDICT_FALSE(size() == Capacity())) {
686-
Grow(size(), size() + 1);
688+
const int old_size = size();
689+
if (ABSL_PREDICT_FALSE(old_size == Capacity())) {
690+
Grow(old_size, old_size + 1);
687691
}
688-
void* p = unsafe_elements() + ExchangeCurrentSize(size() + 1);
692+
void* p = unsafe_elements() + ExchangeCurrentSize(old_size + 1);
689693
return ::new (p) Element;
690694
}
691695

692696
template <typename Element>
693697
template <typename Iter>
694698
inline void RepeatedField<Element>::AddForwardIterator(Iter begin, Iter end) {
699+
const int old_size = size();
695700
int capacity = Capacity();
696701
Element* elem = unsafe_elements();
697-
int new_size = size() + static_cast<int>(std::distance(begin, end));
702+
int new_size = old_size + static_cast<int>(std::distance(begin, end));
698703
if (ABSL_PREDICT_FALSE(new_size > capacity)) {
699-
Grow(size(), new_size);
704+
Grow(old_size, new_size);
700705
elem = unsafe_elements();
701706
capacity = Capacity();
702707
}
@@ -711,24 +716,27 @@ inline void RepeatedField<Element>::AddForwardIterator(Iter begin, Iter end) {
711716
template <typename Element>
712717
template <typename Iter>
713718
inline void RepeatedField<Element>::AddInputIterator(Iter begin, Iter end) {
714-
Element* first = unsafe_elements() + size();
715-
Element* last = unsafe_elements() + Capacity();
719+
Element* elem = unsafe_elements();
720+
Element* first = elem + size();
721+
Element* last = elem + Capacity();
716722
AnnotateSize(size(), Capacity());
717723

718724
while (begin != end) {
719725
if (ABSL_PREDICT_FALSE(first == last)) {
720-
int size = first - unsafe_elements();
726+
int size = first - elem;
721727
GrowNoAnnotate(size, size + 1);
722-
first = unsafe_elements() + size;
723-
last = unsafe_elements() + Capacity();
728+
elem = unsafe_elements();
729+
first = elem + size;
730+
last = elem + Capacity();
724731
}
725732
::new (static_cast<void*>(first)) Element(*begin);
726733
++begin;
727734
++first;
728735
}
729736

730-
set_size(first - unsafe_elements());
731-
AnnotateSize(Capacity(), size());
737+
const int new_size = first - elem;
738+
set_size(new_size);
739+
AnnotateSize(Capacity(), new_size);
732740
}
733741

734742
template <typename Element>
@@ -745,17 +753,19 @@ inline void RepeatedField<Element>::Add(Iter begin, Iter end) {
745753

746754
template <typename Element>
747755
inline void RepeatedField<Element>::RemoveLast() {
748-
ABSL_DCHECK_GT(size(), 0);
749-
elements()[size() - 1].~Element();
750-
ExchangeCurrentSize(size() - 1);
756+
const int old_size = size();
757+
ABSL_DCHECK_GT(old_size, 0);
758+
elements()[old_size - 1].~Element();
759+
ExchangeCurrentSize(old_size - 1);
751760
}
752761

753762
template <typename Element>
754763
void RepeatedField<Element>::ExtractSubrange(int start, int num,
755764
Element* elements) {
756765
ABSL_DCHECK_GE(start, 0);
757766
ABSL_DCHECK_GE(num, 0);
758-
ABSL_DCHECK_LE(start + num, size());
767+
const int old_size = size();
768+
ABSL_DCHECK_LE(start + num, old_size);
759769

760770
// Save the values of the removed elements if requested.
761771
if (elements != nullptr) {
@@ -764,24 +774,26 @@ void RepeatedField<Element>::ExtractSubrange(int start, int num,
764774

765775
// Slide remaining elements down to fill the gap.
766776
if (num > 0) {
767-
for (int i = start + num; i < size(); ++i) Set(i - num, Get(i));
768-
Truncate(size() - num);
777+
for (int i = start + num; i < old_size; ++i) Set(i - num, Get(i));
778+
Truncate(old_size - num);
769779
}
770780
}
771781

772782
template <typename Element>
773783
inline void RepeatedField<Element>::Clear() {
774-
Destroy(unsafe_elements(), unsafe_elements() + size());
784+
Element* elem = unsafe_elements();
785+
Destroy(elem, elem + size());
775786
ExchangeCurrentSize(0);
776787
}
777788

778789
template <typename Element>
779790
inline void RepeatedField<Element>::MergeFrom(const RepeatedField& other) {
780791
ABSL_DCHECK_NE(&other, this);
781-
if (auto size = other.size()) {
782-
Reserve(this->size() + size);
783-
Element* dst = elements() + ExchangeCurrentSize(this->size() + size);
784-
UninitializedCopyN(other.elements(), size, dst);
792+
if (auto other_size = other.size()) {
793+
const int old_size = size();
794+
Reserve(old_size + other_size);
795+
Element* dst = elements() + ExchangeCurrentSize(old_size + other_size);
796+
UninitializedCopyN(other.elements(), other_size, dst);
785797
}
786798
}
787799

@@ -905,8 +917,8 @@ RepeatedField<Element>::cend() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
905917

906918
template <typename Element>
907919
inline size_t RepeatedField<Element>::SpaceUsedExcludingSelfLong() const {
908-
return Capacity() > 0 ? (Capacity() * sizeof(Element) + kHeapRepHeaderSize)
909-
: 0;
920+
const int capacity = Capacity();
921+
return capacity > 0 ? capacity * sizeof(Element) + kHeapRepHeaderSize : 0;
910922
}
911923

912924
namespace internal {
@@ -1016,9 +1028,11 @@ PROTOBUF_NOINLINE void RepeatedField<Element>::Grow(int old_size,
10161028

10171029
template <typename Element>
10181030
inline void RepeatedField<Element>::Truncate(int new_size) {
1019-
ABSL_DCHECK_LE(new_size, size());
1020-
if (new_size < size()) {
1021-
Destroy(unsafe_elements() + new_size, unsafe_elements() + size());
1031+
const int old_size = size();
1032+
ABSL_DCHECK_LE(new_size, old_size);
1033+
if (new_size < old_size) {
1034+
Element* elem = unsafe_elements();
1035+
Destroy(elem + new_size, elem + old_size);
10221036
ExchangeCurrentSize(new_size);
10231037
}
10241038
}

src/google/protobuf/repeated_field_unittest.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,8 +1241,8 @@ TEST(RepeatedField, HardenAgainstBadTruncate) {
12411241
for (int size = 0; size < 10; ++size) {
12421242
field.Truncate(size);
12431243
#if GTEST_HAS_DEATH_TEST
1244-
EXPECT_DEBUG_DEATH(field.Truncate(size + 1), "new_size <= size");
1245-
EXPECT_DEBUG_DEATH(field.Truncate(size + 2), "new_size <= size");
1244+
EXPECT_DEBUG_DEATH(field.Truncate(size + 1), "new_size <= old_size");
1245+
EXPECT_DEBUG_DEATH(field.Truncate(size + 2), "new_size <= old_size");
12461246
#elif defined(NDEBUG)
12471247
field.Truncate(size + 1);
12481248
field.Truncate(size + 1);

0 commit comments

Comments
 (0)