From 4ea1f2024a3b37de97efff896f9c030309170167 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Thu, 18 Jul 2024 11:42:03 -0700 Subject: [PATCH] Move ByteSizeLong calculation of packed varint fields out of line. This reduces code size. PiperOrigin-RevId: 653700178 --- .../cpp/field_generators/enum_field.cc | 45 +++++----- .../cpp/field_generators/primitive_field.cc | 81 +++++++++-------- src/google/protobuf/descriptor.pb.cc | 67 ++++----------- src/google/protobuf/wire_format_lite.cc | 86 +++++++++++++++++++ src/google/protobuf/wire_format_lite.h | 22 +++++ 5 files changed, 188 insertions(+), 113 deletions(-) diff --git a/src/google/protobuf/compiler/cpp/field_generators/enum_field.cc b/src/google/protobuf/compiler/cpp/field_generators/enum_field.cc index d8fd612f0f..b974f78463 100644 --- a/src/google/protobuf/compiler/cpp/field_generators/enum_field.cc +++ b/src/google/protobuf/compiler/cpp/field_generators/enum_field.cc @@ -518,41 +518,38 @@ void RepeatedEnum::GenerateSerializeWithCachedSizesToArray( } void RepeatedEnum::GenerateByteSize(io::Printer* p) const { + if (has_cached_size_) { + ABSL_CHECK(field_->is_packed()); + p->Emit(R"cc( + total_size += ::_pbi::WireFormatLite::EnumSizeWithPackedTagSize( + this_._internal_$name$(), $kTagBytes$, this_.$cached_size_$); + )cc"); + return; + } p->Emit( { - {"add_to_size", + {"tag_size", [&] { - if (!field_->is_packed()) { + if (field_->is_packed()) { p->Emit(R"cc( - total_size += std::size_t{$kTagBytes$} * count; + data_size == 0 + ? 0 + : $kTagBytes$ + ::_pbi::WireFormatLite::Int32Size( + static_cast(data_size)); )cc"); - return; - } - - p->Emit(R"cc( - if (data_size > 0) { - total_size += $kTagBytes$; - total_size += ::_pbi::WireFormatLite::Int32Size( - static_cast(data_size)); - } - )cc"); - if (has_cached_size_) { + } else { p->Emit(R"cc( - this_.$cached_size_$.Set(::_pbi::ToCachedSize(data_size)); + std::size_t{$kTagBytes$} * + ::_pbi::FromIntSize(this_._internal_$name$_size()); )cc"); } }}, }, R"cc( - std::size_t data_size = 0; - auto count = static_cast(this_._internal_$name$_size()); - - for (std::size_t i = 0; i < count; ++i) { - data_size += ::_pbi::WireFormatLite::EnumSize( - this_._internal_$name$().Get(static_cast(i))); - } - total_size += data_size; - $add_to_size$; + std::size_t data_size = + ::_pbi::WireFormatLite::EnumSize(this_._internal_$name$()); + std::size_t tag_size = $tag_size$; + total_size += data_size + tag_size; )cc"); } } // namespace diff --git a/src/google/protobuf/compiler/cpp/field_generators/primitive_field.cc b/src/google/protobuf/compiler/cpp/field_generators/primitive_field.cc index 76a2fb2d2d..7590512e5a 100644 --- a/src/google/protobuf/compiler/cpp/field_generators/primitive_field.cc +++ b/src/google/protobuf/compiler/cpp/field_generators/primitive_field.cc @@ -590,54 +590,53 @@ void RepeatedPrimitive::GenerateSerializeWithCachedSizesToArray( } void RepeatedPrimitive::GenerateByteSize(io::Printer* p) const { + if (HasCachedSize()) { + ABSL_CHECK(field_->is_packed()); + p->Emit( + R"cc( + total_size += + ::_pbi::WireFormatLite::$DeclaredType$SizeWithPackedTagSize( + this_._internal_$name$(), $kTagBytes$, + this_.$_field_cached_byte_size_$); + )cc"); + return; + } p->Emit( { - Sub{"data_size", - [&] { - auto fixed_size = FixedSize(field_->type()); - if (fixed_size.has_value()) { - p->Emit({{"kFixed", *fixed_size}}, R"cc( - std::size_t{$kFixed$} * - ::_pbi::FromIntSize(this_._internal_$name$_size()) - )cc"); - } else { - p->Emit(R"cc( - ::_pbi::WireFormatLite::$DeclaredType$Size( - this_._internal_$name$()) - )cc"); - } - }} // Here and below, we need to disable the default ;-chomping - // that closure substitutions do. - .WithSuffix(""), - {"maybe_cache_data_size", + {"data_size", + [&] { + auto fixed_size = FixedSize(field_->type()); + if (fixed_size.has_value()) { + p->Emit({{"kFixed", *fixed_size}}, R"cc( + std::size_t{$kFixed$} * + ::_pbi::FromIntSize(this_._internal_$name$_size()); + )cc"); + } else { + p->Emit(R"cc( + ::_pbi::WireFormatLite::$DeclaredType$Size( + this_._internal_$name$()); + )cc"); + } + }}, + {"tag_size", [&] { - if (!HasCachedSize()) return; - p->Emit(R"cc( - this_.$_field_cached_byte_size_$.Set( - ::_pbi::ToCachedSize(data_size)); - )cc"); + if (field_->is_packed()) { + p->Emit(R"cc( + data_size == 0 + ? 0 + : $kTagBytes$ + ::_pbi::WireFormatLite::Int32Size( + static_cast(data_size)); + )cc"); + } else { + p->Emit(R"cc( + std::size_t{$kTagBytes$} * + ::_pbi::FromIntSize(this_._internal_$name$_size()); + )cc"); + } }}, - Sub{"tag_size", - [&] { - if (field_->is_packed()) { - p->Emit(R"cc( - data_size == 0 - ? 0 - : $kTagBytes$ + ::_pbi::WireFormatLite::Int32Size( - static_cast(data_size)) - )cc"); - } else { - p->Emit(R"cc( - std::size_t{$kTagBytes$} * - ::_pbi::FromIntSize(this_._internal_$name$_size()); - )cc"); - } - }} - .WithSuffix(""), }, R"cc( std::size_t data_size = $data_size$; - $maybe_cache_data_size$; std::size_t tag_size = $tag_size$; total_size += tag_size + data_size; )cc"); diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc index bd9612cbea..4b3f6ce1b5 100644 --- a/src/google/protobuf/descriptor.pb.cc +++ b/src/google/protobuf/descriptor.pb.cc @@ -3304,21 +3304,17 @@ PROTOBUF_NOINLINE void FileDescriptorProto::Clear() { // repeated int32 public_dependency = 10; { std::size_t data_size = ::_pbi::WireFormatLite::Int32Size( - this_._internal_public_dependency()) - ; + this_._internal_public_dependency()); std::size_t tag_size = std::size_t{1} * ::_pbi::FromIntSize(this_._internal_public_dependency_size()); - ; total_size += tag_size + data_size; } // repeated int32 weak_dependency = 11; { std::size_t data_size = ::_pbi::WireFormatLite::Int32Size( - this_._internal_weak_dependency()) - ; + this_._internal_weak_dependency()); std::size_t tag_size = std::size_t{1} * ::_pbi::FromIntSize(this_._internal_weak_dependency_size()); - ; total_size += tag_size + data_size; } } @@ -10112,15 +10108,11 @@ PROTOBUF_NOINLINE void FieldOptions::Clear() { { // repeated .google.protobuf.FieldOptions.OptionTargetType targets = 19; { - std::size_t data_size = 0; - auto count = static_cast(this_._internal_targets_size()); - - for (std::size_t i = 0; i < count; ++i) { - data_size += ::_pbi::WireFormatLite::EnumSize( - this_._internal_targets().Get(static_cast(i))); - } - total_size += data_size; - total_size += std::size_t{2} * count; + std::size_t data_size = + ::_pbi::WireFormatLite::EnumSize(this_._internal_targets()); + std::size_t tag_size = std::size_t{2} * + ::_pbi::FromIntSize(this_._internal_targets_size()); + total_size += data_size + tag_size; } // repeated .google.protobuf.FieldOptions.EditionDefault edition_defaults = 20; { @@ -14098,31 +14090,17 @@ PROTOBUF_NOINLINE void SourceCodeInfo_Location::Clear() { { // repeated int32 path = 1 [packed = true]; { - std::size_t data_size = ::_pbi::WireFormatLite::Int32Size( - this_._internal_path()) - ; - this_._impl_._path_cached_byte_size_.Set( - ::_pbi::ToCachedSize(data_size)); - std::size_t tag_size = data_size == 0 - ? 0 - : 1 + ::_pbi::WireFormatLite::Int32Size( - static_cast(data_size)) - ; - total_size += tag_size + data_size; + total_size += + ::_pbi::WireFormatLite::Int32SizeWithPackedTagSize( + this_._internal_path(), 1, + this_._impl_._path_cached_byte_size_); } // repeated int32 span = 2 [packed = true]; { - std::size_t data_size = ::_pbi::WireFormatLite::Int32Size( - this_._internal_span()) - ; - this_._impl_._span_cached_byte_size_.Set( - ::_pbi::ToCachedSize(data_size)); - std::size_t tag_size = data_size == 0 - ? 0 - : 1 + ::_pbi::WireFormatLite::Int32Size( - static_cast(data_size)) - ; - total_size += tag_size + data_size; + total_size += + ::_pbi::WireFormatLite::Int32SizeWithPackedTagSize( + this_._internal_span(), 1, + this_._impl_._span_cached_byte_size_); } // repeated string leading_detached_comments = 6; { @@ -14692,17 +14670,10 @@ PROTOBUF_NOINLINE void GeneratedCodeInfo_Annotation::Clear() { { // repeated int32 path = 1 [packed = true]; { - std::size_t data_size = ::_pbi::WireFormatLite::Int32Size( - this_._internal_path()) - ; - this_._impl_._path_cached_byte_size_.Set( - ::_pbi::ToCachedSize(data_size)); - std::size_t tag_size = data_size == 0 - ? 0 - : 1 + ::_pbi::WireFormatLite::Int32Size( - static_cast(data_size)) - ; - total_size += tag_size + data_size; + total_size += + ::_pbi::WireFormatLite::Int32SizeWithPackedTagSize( + this_._internal_path(), 1, + this_._impl_._path_cached_byte_size_); } } cached_has_bits = this_._impl_._has_bits_[0]; diff --git a/src/google/protobuf/wire_format_lite.cc b/src/google/protobuf/wire_format_lite.cc index 8fc29af555..e20eda908c 100644 --- a/src/google/protobuf/wire_format_lite.cc +++ b/src/google/protobuf/wire_format_lite.cc @@ -21,6 +21,7 @@ #include "absl/strings/cord.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" +#include "google/protobuf/message_lite.h" #include "utf8_validity.h" @@ -830,6 +831,91 @@ size_t WireFormatLite::SInt64Size(const RepeatedField& value) { #endif +size_t WireFormatLite::Int32SizeWithPackedTagSize( + const RepeatedField& value, size_t tag_size, + const internal::CachedSize& cached_size) { + if (value.empty()) { + cached_size.Set(0); + return 0; + } + size_t res; + PROTOBUF_ALWAYS_INLINE_CALL res = Int32Size(value); + cached_size.Set(ToCachedSize(res)); + return tag_size + res + Int32Size(static_cast(res)); +} +size_t WireFormatLite::Int64SizeWithPackedTagSize( + const RepeatedField& value, size_t tag_size, + const internal::CachedSize& cached_size) { + if (value.empty()) { + cached_size.Set(0); + return 0; + } + size_t res; + PROTOBUF_ALWAYS_INLINE_CALL res = Int64Size(value); + cached_size.Set(ToCachedSize(res)); + return tag_size + res + Int32Size(static_cast(res)); +} +size_t WireFormatLite::UInt32SizeWithPackedTagSize( + const RepeatedField& value, size_t tag_size, + const internal::CachedSize& cached_size) { + if (value.empty()) { + cached_size.Set(0); + return 0; + } + size_t res; + PROTOBUF_ALWAYS_INLINE_CALL res = UInt32Size(value); + cached_size.Set(ToCachedSize(res)); + return tag_size + res + Int32Size(static_cast(res)); +} +size_t WireFormatLite::UInt64SizeWithPackedTagSize( + const RepeatedField& value, size_t tag_size, + const internal::CachedSize& cached_size) { + if (value.empty()) { + cached_size.Set(0); + return 0; + } + size_t res; + PROTOBUF_ALWAYS_INLINE_CALL res = UInt64Size(value); + cached_size.Set(ToCachedSize(res)); + return tag_size + res + Int32Size(static_cast(res)); +} +size_t WireFormatLite::SInt32SizeWithPackedTagSize( + const RepeatedField& value, size_t tag_size, + const internal::CachedSize& cached_size) { + if (value.empty()) { + cached_size.Set(0); + return 0; + } + size_t res; + PROTOBUF_ALWAYS_INLINE_CALL res = SInt32Size(value); + cached_size.Set(ToCachedSize(res)); + return tag_size + res + Int32Size(static_cast(res)); +} +size_t WireFormatLite::SInt64SizeWithPackedTagSize( + const RepeatedField& value, size_t tag_size, + const internal::CachedSize& cached_size) { + if (value.empty()) { + cached_size.Set(0); + return 0; + } + size_t res; + PROTOBUF_ALWAYS_INLINE_CALL res = SInt64Size(value); + cached_size.Set(ToCachedSize(res)); + return tag_size + res + Int32Size(static_cast(res)); +} +size_t WireFormatLite::EnumSizeWithPackedTagSize( + const RepeatedField& value, size_t tag_size, + const internal::CachedSize& cached_size) { + if (value.empty()) { + cached_size.Set(0); + return 0; + } + size_t res; + PROTOBUF_ALWAYS_INLINE_CALL res = EnumSize(value); + cached_size.Set(ToCachedSize(res)); + return tag_size + res + Int32Size(static_cast(res)); +} + } // namespace internal } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/wire_format_lite.h b/src/google/protobuf/wire_format_lite.h index ad0167c850..42634885cd 100644 --- a/src/google/protobuf/wire_format_lite.h +++ b/src/google/protobuf/wire_format_lite.h @@ -700,6 +700,28 @@ class PROTOBUF_EXPORT WireFormatLite { static size_t SInt64Size(const RepeatedField& value); static size_t EnumSize(const RepeatedField& value); + static size_t Int32SizeWithPackedTagSize( + const RepeatedField& value, size_t tag_size, + const internal::CachedSize& cached_size); + static size_t Int64SizeWithPackedTagSize( + const RepeatedField& value, size_t tag_size, + const internal::CachedSize& cached_size); + static size_t UInt32SizeWithPackedTagSize( + const RepeatedField& value, size_t tag_size, + const internal::CachedSize& cached_size); + static size_t UInt64SizeWithPackedTagSize( + const RepeatedField& value, size_t tag_size, + const internal::CachedSize& cached_size); + static size_t SInt32SizeWithPackedTagSize( + const RepeatedField& value, size_t tag_size, + const internal::CachedSize& cached_size); + static size_t SInt64SizeWithPackedTagSize( + const RepeatedField& value, size_t tag_size, + const internal::CachedSize& cached_size); + static size_t EnumSizeWithPackedTagSize( + const RepeatedField& value, size_t tag_size, + const internal::CachedSize& cached_size); + // These types always have the same size. static constexpr size_t kFixed32Size = 4; static constexpr size_t kFixed64Size = 8;