Skip to content

Commit 9f2d7ea

Browse files
protobuf-github-botseongkim75
authored andcommitted
Automated rollback of commit adb2c4b.
PiperOrigin-RevId: 548128917
1 parent d1b6788 commit 9f2d7ea

3 files changed

Lines changed: 74 additions & 187 deletions

File tree

src/google/protobuf/generated_message_tctable_lite.cc

Lines changed: 74 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -393,45 +393,6 @@ inline PROTOBUF_ALWAYS_INLINE void InvertPacked(TcFieldData& data) {
393393
data.data ^= Wt ^ WireFormatLite::WIRETYPE_LENGTH_DELIMITED;
394394
}
395395

396-
constexpr uint32_t kAccumulatorBytesOnStack = 256;
397-
398-
// Accumulates fields to buffer repeated fields on parsing path to avoid growing
399-
// repeated field container type too frequently. It flushes to the backing
400-
// repeated fields if it's full or out of the scope. A larger buffer (e.g. 2KiB)
401-
// is actually harmful due to:
402-
// - increased stack overflow risk
403-
// - extra cache misses on accessing local variables
404-
// - less competitive to the cost of growing large buffer
405-
template <typename ElementType, typename ContainerType>
406-
class ScopedFieldAccumulator {
407-
public:
408-
constexpr explicit ScopedFieldAccumulator(ContainerType& field)
409-
: field_(field) {}
410-
411-
~ScopedFieldAccumulator() {
412-
if (ABSL_PREDICT_TRUE(current_size_ > 0)) {
413-
field_.MergeFromArray(buffer_, current_size_);
414-
}
415-
}
416-
417-
PROTOBUF_NODISCARD ElementType& Next() {
418-
if (ABSL_PREDICT_FALSE(current_size_ == kSize)) {
419-
field_.MergeFromArray(buffer_, kSize);
420-
current_size_ = 0;
421-
}
422-
return buffer_[current_size_++];
423-
}
424-
425-
private:
426-
static constexpr uint32_t kSize =
427-
kAccumulatorBytesOnStack / sizeof(ElementType);
428-
static_assert(kSize > 0, "Size cannot be zero");
429-
430-
uint32_t current_size_ = 0;
431-
ElementType buffer_[kSize];
432-
ContainerType& field_;
433-
};
434-
435396
} // namespace
436397

437398
//////////////////////////////////////////////////////////////////////////////
@@ -659,17 +620,14 @@ PROTOBUF_ALWAYS_INLINE const char* TcParser::RepeatedFixed(
659620
}
660621
auto& field = RefAt<RepeatedField<LayoutType>>(msg, data.offset());
661622
const auto tag = UnalignedLoad<TagType>(ptr);
662-
{
663-
ScopedFieldAccumulator<LayoutType, decltype(field)> accumulator(field);
664-
do {
665-
accumulator.Next() = UnalignedLoad<LayoutType>(ptr + sizeof(TagType));
666-
ptr += sizeof(TagType) + sizeof(LayoutType);
667-
if (PROTOBUF_PREDICT_FALSE(!ctx->DataAvailable(ptr))) goto parse_loop;
668-
} while (UnalignedLoad<TagType>(ptr) == tag);
669-
}
623+
do {
624+
field.Add(UnalignedLoad<LayoutType>(ptr + sizeof(TagType)));
625+
ptr += sizeof(TagType) + sizeof(LayoutType);
626+
if (PROTOBUF_PREDICT_FALSE(!ctx->DataAvailable(ptr))) {
627+
PROTOBUF_MUSTTAIL return ToParseLoop(PROTOBUF_TC_PARAM_NO_DATA_PASS);
628+
}
629+
} while (UnalignedLoad<TagType>(ptr) == tag);
670630
PROTOBUF_MUSTTAIL return ToTagDispatch(PROTOBUF_TC_PARAM_NO_DATA_PASS);
671-
parse_loop:
672-
PROTOBUF_MUSTTAIL return ToParseLoop(PROTOBUF_TC_PARAM_NO_DATA_PASS);
673631
}
674632

675633
PROTOBUF_NOINLINE const char* TcParser::FastF32R1(PROTOBUF_TC_PARAM_DECL) {
@@ -1003,22 +961,19 @@ PROTOBUF_ALWAYS_INLINE const char* TcParser::RepeatedVarint(
1003961
}
1004962
auto& field = RefAt<RepeatedField<FieldType>>(msg, data.offset());
1005963
const auto expected_tag = UnalignedLoad<TagType>(ptr);
1006-
{
1007-
ScopedFieldAccumulator<FieldType, decltype(field)> accumulator(field);
1008-
do {
1009-
ptr += sizeof(TagType);
1010-
FieldType tmp;
1011-
ptr = ParseVarint(ptr, &tmp);
1012-
if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) goto error;
1013-
accumulator.Next() = ZigZagDecodeHelper<FieldType, zigzag>(tmp);
1014-
if (PROTOBUF_PREDICT_FALSE(!ctx->DataAvailable(ptr))) goto parse_loop;
1015-
} while (UnalignedLoad<TagType>(ptr) == expected_tag);
1016-
}
964+
do {
965+
ptr += sizeof(TagType);
966+
FieldType tmp;
967+
ptr = ParseVarint(ptr, &tmp);
968+
if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) {
969+
PROTOBUF_MUSTTAIL return Error(PROTOBUF_TC_PARAM_NO_DATA_PASS);
970+
}
971+
field.Add(ZigZagDecodeHelper<FieldType, zigzag>(tmp));
972+
if (PROTOBUF_PREDICT_FALSE(!ctx->DataAvailable(ptr))) {
973+
PROTOBUF_MUSTTAIL return ToParseLoop(PROTOBUF_TC_PARAM_NO_DATA_PASS);
974+
}
975+
} while (UnalignedLoad<TagType>(ptr) == expected_tag);
1017976
PROTOBUF_MUSTTAIL return ToTagDispatch(PROTOBUF_TC_PARAM_NO_DATA_PASS);
1018-
parse_loop:
1019-
PROTOBUF_MUSTTAIL return ToParseLoop(PROTOBUF_TC_PARAM_NO_DATA_PASS);
1020-
error:
1021-
PROTOBUF_MUSTTAIL return Error(PROTOBUF_TC_PARAM_NO_DATA_PASS);
1022977
}
1023978

1024979
PROTOBUF_NOINLINE const char* TcParser::FastV8R1(PROTOBUF_TC_PARAM_DECL) {
@@ -1080,8 +1035,7 @@ const char* TcParser::PackedVarint(PROTOBUF_TC_PARAM_DECL) {
10801035
// pending hasbits now:
10811036
SyncHasbits(msg, hasbits, table);
10821037
auto* field = &RefAt<RepeatedField<FieldType>>(msg, data.offset());
1083-
ScopedFieldAccumulator<FieldType, decltype(*field)> accumulator(*field);
1084-
return ctx->ReadPackedVarint(ptr, [&](uint64_t varint) {
1038+
return ctx->ReadPackedVarint(ptr, [field](uint64_t varint) {
10851039
FieldType val;
10861040
if (zigzag) {
10871041
if (sizeof(FieldType) == 8) {
@@ -1092,7 +1046,7 @@ const char* TcParser::PackedVarint(PROTOBUF_TC_PARAM_DECL) {
10921046
} else {
10931047
val = varint;
10941048
}
1095-
accumulator.Next() = val;
1049+
field->Add(val);
10961050
});
10971051
}
10981052

@@ -1227,33 +1181,28 @@ const char* TcParser::RepeatedEnum(PROTOBUF_TC_PARAM_DECL) {
12271181
auto& field = RefAt<RepeatedField<int32_t>>(msg, data.offset());
12281182
const auto expected_tag = UnalignedLoad<TagType>(ptr);
12291183
const TcParseTableBase::FieldAux aux = *table->field_aux(data.aux_idx());
1230-
{
1231-
ScopedFieldAccumulator<int32_t, decltype(field)> accumulator(field);
1232-
do {
1233-
const char* ptr2 = ptr; // save for unknown enum case
1234-
ptr += sizeof(TagType);
1235-
uint64_t tmp;
1236-
ptr = ParseVarint(ptr, &tmp);
1237-
if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) goto error;
1238-
if (PROTOBUF_PREDICT_FALSE(
1239-
!EnumIsValidAux(static_cast<int32_t>(tmp), xform_val, aux))) {
1240-
// We can avoid duplicate work in MiniParse by directly calling
1241-
// table->fallback.
1242-
ptr = ptr2;
1243-
goto unknown_enum_fallback;
1244-
}
1245-
accumulator.Next() = static_cast<int32_t>(tmp);
1246-
if (PROTOBUF_PREDICT_FALSE(!ctx->DataAvailable(ptr))) goto parse_loop;
1247-
} while (UnalignedLoad<TagType>(ptr) == expected_tag);
1248-
}
1184+
do {
1185+
const char* ptr2 = ptr; // save for unknown enum case
1186+
ptr += sizeof(TagType);
1187+
uint64_t tmp;
1188+
ptr = ParseVarint(ptr, &tmp);
1189+
if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) {
1190+
PROTOBUF_MUSTTAIL return Error(PROTOBUF_TC_PARAM_NO_DATA_PASS);
1191+
}
1192+
if (PROTOBUF_PREDICT_FALSE(
1193+
!EnumIsValidAux(static_cast<int32_t>(tmp), xform_val, aux))) {
1194+
// We can avoid duplicate work in MiniParse by directly calling
1195+
// table->fallback.
1196+
ptr = ptr2;
1197+
PROTOBUF_MUSTTAIL return FastUnknownEnumFallback(PROTOBUF_TC_PARAM_PASS);
1198+
}
1199+
field.Add(static_cast<int32_t>(tmp));
1200+
if (PROTOBUF_PREDICT_FALSE(!ctx->DataAvailable(ptr))) {
1201+
PROTOBUF_MUSTTAIL return ToParseLoop(PROTOBUF_TC_PARAM_NO_DATA_PASS);
1202+
}
1203+
} while (UnalignedLoad<TagType>(ptr) == expected_tag);
12491204

12501205
PROTOBUF_MUSTTAIL return ToTagDispatch(PROTOBUF_TC_PARAM_NO_DATA_PASS);
1251-
parse_loop:
1252-
PROTOBUF_MUSTTAIL return ToParseLoop(PROTOBUF_TC_PARAM_NO_DATA_PASS);
1253-
error:
1254-
PROTOBUF_MUSTTAIL return Error(PROTOBUF_TC_PARAM_NO_DATA_PASS);
1255-
unknown_enum_fallback:
1256-
PROTOBUF_MUSTTAIL return FastUnknownEnumFallback(PROTOBUF_TC_PARAM_PASS);
12571206
}
12581207

12591208
const TcParser::UnknownFieldOps& TcParser::GetUnknownFieldOps(
@@ -1387,22 +1336,19 @@ const char* TcParser::RepeatedEnumSmallRange(PROTOBUF_TC_PARAM_DECL) {
13871336
auto& field = RefAt<RepeatedField<int32_t>>(msg, data.offset());
13881337
auto expected_tag = UnalignedLoad<TagType>(ptr);
13891338
const uint8_t max = data.aux_idx();
1390-
{
1391-
ScopedFieldAccumulator<int32_t, decltype(field)> accumulator(field);
1392-
do {
1393-
uint8_t v = ptr[sizeof(TagType)];
1394-
if (PROTOBUF_PREDICT_FALSE(min > v || v > max)) goto mini_parse;
1395-
accumulator.Next() = static_cast<int32_t>(v);
1396-
ptr += sizeof(TagType) + 1;
1397-
if (PROTOBUF_PREDICT_FALSE(!ctx->DataAvailable(ptr))) goto parse_loop;
1398-
} while (UnalignedLoad<TagType>(ptr) == expected_tag);
1399-
}
1339+
do {
1340+
uint8_t v = ptr[sizeof(TagType)];
1341+
if (PROTOBUF_PREDICT_FALSE(min > v || v > max)) {
1342+
PROTOBUF_MUSTTAIL return MiniParse(PROTOBUF_TC_PARAM_NO_DATA_PASS);
1343+
}
1344+
field.Add(static_cast<int32_t>(v));
1345+
ptr += sizeof(TagType) + 1;
1346+
if (PROTOBUF_PREDICT_FALSE(!ctx->DataAvailable(ptr))) {
1347+
PROTOBUF_MUSTTAIL return ToParseLoop(PROTOBUF_TC_PARAM_NO_DATA_PASS);
1348+
}
1349+
} while (UnalignedLoad<TagType>(ptr) == expected_tag);
14001350

14011351
PROTOBUF_MUSTTAIL return ToTagDispatch(PROTOBUF_TC_PARAM_NO_DATA_PASS);
1402-
parse_loop:
1403-
PROTOBUF_MUSTTAIL return ToParseLoop(PROTOBUF_TC_PARAM_NO_DATA_PASS);
1404-
mini_parse:
1405-
PROTOBUF_MUSTTAIL return MiniParse(PROTOBUF_TC_PARAM_NO_DATA_PASS);
14061352
}
14071353

14081354
PROTOBUF_NOINLINE const char* TcParser::FastEr0R1(PROTOBUF_TC_PARAM_DECL) {
@@ -1904,10 +1850,9 @@ PROTOBUF_NOINLINE const char* TcParser::MpRepeatedFixed(
19041850
constexpr auto size = sizeof(uint64_t);
19051851
const char* ptr2 = ptr;
19061852
uint32_t next_tag;
1907-
ScopedFieldAccumulator<uint64_t, decltype(field)> accumulator(field);
19081853
do {
19091854
ptr = ptr2;
1910-
accumulator.Next() = UnalignedLoad<uint64_t>(ptr);
1855+
*field.Add() = UnalignedLoad<uint64_t>(ptr);
19111856
ptr += size;
19121857
if (PROTOBUF_PREDICT_FALSE(!ctx->DataAvailable(ptr))) goto parse_loop;
19131858
ptr2 = ReadTag(ptr, &next_tag);
@@ -1922,10 +1867,9 @@ PROTOBUF_NOINLINE const char* TcParser::MpRepeatedFixed(
19221867
constexpr auto size = sizeof(uint32_t);
19231868
const char* ptr2 = ptr;
19241869
uint32_t next_tag;
1925-
ScopedFieldAccumulator<uint32_t, decltype(field)> accumulator(field);
19261870
do {
19271871
ptr = ptr2;
1928-
accumulator.Next() = UnalignedLoad<uint32_t>(ptr);
1872+
*field.Add() = UnalignedLoad<uint32_t>(ptr);
19291873
ptr += size;
19301874
if (PROTOBUF_PREDICT_FALSE(!ctx->DataAvailable(ptr))) goto parse_loop;
19311875
ptr2 = ReadTag(ptr, &next_tag);
@@ -2055,13 +1999,11 @@ PROTOBUF_NOINLINE const char* TcParser::MpRepeatedVarint(
20551999
auto& field = RefAt<RepeatedField<uint64_t>>(msg, entry.offset);
20562000
const char* ptr2 = ptr;
20572001
uint32_t next_tag;
2058-
ScopedFieldAccumulator<uint64_t, decltype(field)> accumulator(field);
20592002
do {
20602003
uint64_t tmp;
20612004
ptr = ParseVarint(ptr2, &tmp);
20622005
if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) goto error;
2063-
accumulator.Next() =
2064-
is_zigzag ? WireFormatLite::ZigZagDecode64(tmp) : tmp;
2006+
field.Add(is_zigzag ? WireFormatLite::ZigZagDecode64(tmp) : tmp);
20652007
if (PROTOBUF_PREDICT_FALSE(!ctx->DataAvailable(ptr))) goto parse_loop;
20662008
ptr2 = ReadTag(ptr, &next_tag);
20672009
if (PROTOBUF_PREDICT_FALSE(ptr2 == nullptr)) goto error;
@@ -2070,20 +2012,20 @@ PROTOBUF_NOINLINE const char* TcParser::MpRepeatedVarint(
20702012
auto& field = RefAt<RepeatedField<uint32_t>>(msg, entry.offset);
20712013
const char* ptr2 = ptr;
20722014
uint32_t next_tag;
2073-
ScopedFieldAccumulator<uint32_t, decltype(field)> accumulator(field);
20742015
do {
20752016
uint64_t tmp;
20762017
ptr = ParseVarint(ptr2, &tmp);
20772018
if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) goto error;
20782019
if (is_validated_enum) {
20792020
if (!EnumIsValidAux(tmp, xform_val, *table->field_aux(&entry))) {
20802021
ptr = ptr2;
2081-
goto unknown_enum_fallback;
2022+
PROTOBUF_MUSTTAIL return MpUnknownEnumFallback(
2023+
PROTOBUF_TC_PARAM_PASS);
20822024
}
20832025
} else if (is_zigzag) {
20842026
tmp = WireFormatLite::ZigZagDecode32(tmp);
20852027
}
2086-
accumulator.Next() = tmp;
2028+
field.Add(tmp);
20872029
if (PROTOBUF_PREDICT_FALSE(!ctx->DataAvailable(ptr))) goto parse_loop;
20882030
ptr2 = ReadTag(ptr, &next_tag);
20892031
if (PROTOBUF_PREDICT_FALSE(ptr2 == nullptr)) goto error;
@@ -2093,12 +2035,11 @@ PROTOBUF_NOINLINE const char* TcParser::MpRepeatedVarint(
20932035
auto& field = RefAt<RepeatedField<bool>>(msg, entry.offset);
20942036
const char* ptr2 = ptr;
20952037
uint32_t next_tag;
2096-
ScopedFieldAccumulator<bool, decltype(field)> accumulator(field);
20972038
do {
20982039
uint64_t tmp;
20992040
ptr = ParseVarint(ptr2, &tmp);
21002041
if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) goto error;
2101-
accumulator.Next() = static_cast<bool>(tmp);
2042+
field.Add(static_cast<bool>(tmp));
21022043
if (PROTOBUF_PREDICT_FALSE(!ctx->DataAvailable(ptr))) goto parse_loop;
21032044
ptr2 = ReadTag(ptr, &next_tag);
21042045
if (PROTOBUF_PREDICT_FALSE(ptr2 == nullptr)) goto error;
@@ -2110,8 +2051,6 @@ PROTOBUF_NOINLINE const char* TcParser::MpRepeatedVarint(
21102051
PROTOBUF_MUSTTAIL return ToParseLoop(PROTOBUF_TC_PARAM_NO_DATA_PASS);
21112052
error:
21122053
PROTOBUF_MUSTTAIL return Error(PROTOBUF_TC_PARAM_NO_DATA_PASS);
2113-
unknown_enum_fallback:
2114-
PROTOBUF_MUSTTAIL return MpUnknownEnumFallback(PROTOBUF_TC_PARAM_PASS);
21152054
}
21162055

21172056
PROTOBUF_NOINLINE const char* TcParser::MpPackedVarint(PROTOBUF_TC_PARAM_DECL) {
@@ -2133,41 +2072,33 @@ PROTOBUF_NOINLINE const char* TcParser::MpPackedVarint(PROTOBUF_TC_PARAM_DECL) {
21332072

21342073
uint16_t rep = type_card & field_layout::kRepMask;
21352074
if (rep == field_layout::kRep64Bits) {
2136-
auto& field = RefAt<RepeatedField<uint64_t>>(msg, entry.offset);
2137-
ScopedFieldAccumulator<uint64_t, decltype(field)> accumulator(field);
2138-
return ctx->ReadPackedVarint(
2139-
ptr, [&accumulator, is_zigzag](uint64_t value) {
2140-
accumulator.Next() =
2141-
is_zigzag ? WireFormatLite::ZigZagDecode64(value) : value;
2142-
});
2075+
auto* field = &RefAt<RepeatedField<uint64_t>>(msg, entry.offset);
2076+
return ctx->ReadPackedVarint(ptr, [field, is_zigzag](uint64_t value) {
2077+
field->Add(is_zigzag ? WireFormatLite::ZigZagDecode64(value) : value);
2078+
});
21432079
} else if (rep == field_layout::kRep32Bits) {
2144-
auto& field = RefAt<RepeatedField<uint32_t>>(msg, entry.offset);
2080+
auto* field = &RefAt<RepeatedField<uint32_t>>(msg, entry.offset);
21452081
if (is_validated_enum) {
21462082
const TcParseTableBase::FieldAux aux = *table->field_aux(entry.aux_idx);
2147-
ScopedFieldAccumulator<uint32_t, decltype(field)> accumulator(field);
2148-
return ctx->ReadPackedVarint(ptr, [=, &accumulator](int32_t value) {
2083+
return ctx->ReadPackedVarint(ptr, [=](int32_t value) {
21492084
if (!EnumIsValidAux(value, xform_val, aux)) {
21502085
AddUnknownEnum(msg, table, data.tag(), value);
21512086
} else {
2152-
accumulator.Next() = value;
2087+
field->Add(value);
21532088
}
21542089
});
21552090
} else {
2156-
ScopedFieldAccumulator<uint32_t, decltype(field)> accumulator(field);
2157-
return ctx->ReadPackedVarint(
2158-
ptr, [&accumulator, is_zigzag](uint64_t value) {
2159-
accumulator.Next() = is_zigzag ? WireFormatLite::ZigZagDecode32(
2160-
static_cast<uint32_t>(value))
2161-
: value;
2162-
});
2091+
return ctx->ReadPackedVarint(ptr, [field, is_zigzag](uint64_t value) {
2092+
field->Add(is_zigzag ? WireFormatLite::ZigZagDecode32(
2093+
static_cast<uint32_t>(value))
2094+
: value);
2095+
});
21632096
}
21642097
} else {
21652098
ABSL_DCHECK_EQ(rep, static_cast<uint16_t>(field_layout::kRep8Bits));
2166-
auto& field = RefAt<RepeatedField<bool>>(msg, entry.offset);
2167-
ScopedFieldAccumulator<bool, decltype(field)> accumulator(field);
2168-
return ctx->ReadPackedVarint(ptr, [&](uint64_t value) {
2169-
accumulator.Next() = static_cast<bool>(value);
2170-
});
2099+
auto* field = &RefAt<RepeatedField<bool>>(msg, entry.offset);
2100+
return ctx->ReadPackedVarint(
2101+
ptr, [field](uint64_t value) { field->Add(static_cast<bool>(value)); });
21712102
}
21722103

21732104
PROTOBUF_MUSTTAIL return Error(PROTOBUF_TC_PARAM_NO_DATA_PASS);

src/google/protobuf/repeated_field.h

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -358,8 +358,6 @@ class RepeatedField final
358358
// This is public due to it being called by generated code.
359359
inline void InternalSwap(RepeatedField* other);
360360

361-
void MergeFromArray(const Element* array, size_t length);
362-
363361
private:
364362
RepeatedField(Arena* arena, const RepeatedField& rhs);
365363
template <typename T> friend class Arena::InternalHelper;
@@ -624,30 +622,6 @@ inline int RepeatedField<Element>::Capacity() const {
624622
return total_size_;
625623
}
626624

627-
template <typename Element>
628-
inline void RepeatedField<Element>::MergeFromArray(const Element* array,
629-
size_t length) {
630-
// Only supports trivially copyable types.
631-
static_assert(std::is_trivially_copyable<Element>::value,
632-
"only trivialy copyable types are supported");
633-
634-
ABSL_DCHECK_GT(length, 0u);
635-
if (ABSL_PREDICT_TRUE(current_size_ + static_cast<int>(length) >
636-
total_size_)) {
637-
Grow(current_size_, current_size_ + length);
638-
}
639-
Element* elem = unsafe_elements();
640-
ABSL_DCHECK_NE(elem, nullptr);
641-
void* p = elem + ExchangeCurrentSize(current_size_ + length);
642-
memcpy(p, array, sizeof(Element) * length);
643-
}
644-
645-
template <>
646-
inline void RepeatedField<absl::Cord>::MergeFromArray(const absl::Cord* array,
647-
size_t length) {
648-
ABSL_LOG(FATAL) << "not supported";
649-
}
650-
651625
template <typename Element>
652626
inline void RepeatedField<Element>::AddAlreadyReserved(Element value) {
653627
ABSL_DCHECK_LT(current_size_, total_size_);

0 commit comments

Comments
 (0)