Improve loops in RepeatedPtrField.

We do not want to repeatedly check `using_sso` when iterating over an array. Hence instead of using `Get(i) / Mutable(i)` from base class, we request a pointer to the underlying array (thus, reducing number of checks from N to 1).

Additionally, there is a loop with a `Delete` call - updated it to use `CommonHandler`, so that it reduces code bloat.

PiperOrigin-RevId: 565665669
pull/14098/head
Protobuf Team Bot 1 year ago committed by Copybara-Service
parent 991cfb4a67
commit 9b8f042770
  1. 61
      src/google/protobuf/repeated_ptr_field.h
  2. 1351
      upb/cmake/google/protobuf/descriptor.upb_minitable.c
  3. 78
      upb/cmake/google/protobuf/descriptor.upb_minitable.h

@ -149,6 +149,9 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase {
template <typename Handler>
using Value = typename Handler::Type;
static constexpr int kSSOCapacity = 1;
protected:
// We use the same Handler for all Message types to deduplicate generated
// code.
template <typename Handler>
@ -156,9 +159,6 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase {
std::is_base_of<MessageLite, Value<Handler>>::value,
internal::GenericTypeHandler<MessageLite>, Handler>::type;
static constexpr int kSSOCapacity = 1;
protected:
constexpr RepeatedPtrFieldBase()
: arena_(nullptr),
current_size_(0),
@ -353,7 +353,7 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase {
void Reserve(int new_size); // implemented in the cc file
template <typename TypeHandler>
static inline Value<TypeHandler>* copy(Value<TypeHandler>* value) {
static inline Value<TypeHandler>* copy(const Value<TypeHandler>* value) {
using H = CommonHandler<TypeHandler>;
auto* new_value = H::NewFromPrototype(value, nullptr);
H::Merge(*value, new_value);
@ -1466,8 +1466,11 @@ inline void RepeatedPtrField<Element>::DeleteSubrange(int start, int num) {
ABSL_DCHECK_GE(start, 0);
ABSL_DCHECK_GE(num, 0);
ABSL_DCHECK_LE(start + num, size());
void** subrange = raw_mutable_data() + start;
Arena* arena = GetOwningArena();
for (int i = 0; i < num; ++i) {
RepeatedPtrFieldBase::Delete<TypeHandler>(start + i);
using H = CommonHandler<TypeHandler>;
H::Delete(static_cast<Element*>(subrange[i]), arena);
}
UnsafeArenaExtractSubrange(start, num, nullptr);
}
@ -1494,37 +1497,31 @@ inline void RepeatedPtrField<Element>::ExtractSubrangeInternal(
ABSL_DCHECK_NE(elements, nullptr)
<< "Releasing elements without transferring ownership is an unsafe "
"operation. Use UnsafeArenaExtractSubrange.";
if (elements == nullptr) {
CloseGap(start, num);
return;
}
Arena* arena = GetOwningArena();
if (elements != nullptr) {
Arena* arena = GetOwningArena();
auto* extracted = data() + start;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
// Always copy.
for (int i = 0; i < num; ++i) {
elements[i] = copy<TypeHandler>(
RepeatedPtrFieldBase::Mutable<TypeHandler>(i + start));
}
if (arena == nullptr) {
// Always copy.
for (int i = 0; i < num; ++i) {
delete RepeatedPtrFieldBase::Mutable<TypeHandler>(i + start);
elements[i] = copy<TypeHandler>(extracted[i]);
}
}
#else // PROTOBUF_FORCE_COPY_IN_RELEASE
// If we're on an arena, we perform a copy for each element so that the
// returned elements are heap-allocated. Otherwise, just forward it.
if (arena != nullptr) {
for (int i = 0; i < num; ++i) {
elements[i] = copy<TypeHandler>(
RepeatedPtrFieldBase::Mutable<TypeHandler>(i + start));
if (arena == nullptr) {
for (int i = 0; i < num; ++i) {
delete extracted[i];
}
}
} else {
for (int i = 0; i < num; ++i) {
elements[i] = RepeatedPtrFieldBase::Mutable<TypeHandler>(i + start);
#else // PROTOBUF_FORCE_COPY_IN_RELEASE
// If we're on an arena, we perform a copy for each element so that the
// returned elements are heap-allocated. Otherwise, just forward it.
if (arena != nullptr) {
for (int i = 0; i < num; ++i) {
elements[i] = copy<TypeHandler>(extracted[i]);
}
} else {
memcpy(elements, extracted, num * sizeof(Element*));
}
}
#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE
}
CloseGap(start, num);
}
@ -1553,9 +1550,7 @@ inline void RepeatedPtrField<Element>::UnsafeArenaExtractSubrange(
if (num > 0) {
// Save the values of the removed elements if requested.
if (elements != nullptr) {
for (int i = 0; i < num; ++i) {
elements[i] = RepeatedPtrFieldBase::Mutable<TypeHandler>(i + start);
}
memcpy(elements, data() + start, num * sizeof(Element*));
}
CloseGap(start, num);
}

File diff suppressed because it is too large Load Diff

@ -1,78 +0,0 @@
/* This file was generated by upbc (the upb compiler) from the input
* file:
*
* google/protobuf/descriptor.proto
*
* Do not edit -- your changes will be discarded when the file is
* regenerated. */
#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_MINITABLE_H_
#define GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_MINITABLE_H_
#include "upb/upb/generated_code_support.h"
// Must be last.
#include "upb/upb/port/def.inc"
#ifdef __cplusplus
extern "C" {
#endif
extern const upb_MiniTable google_protobuf_FileDescriptorSet_msg_init;
extern const upb_MiniTable google_protobuf_FileDescriptorProto_msg_init;
extern const upb_MiniTable google_protobuf_DescriptorProto_msg_init;
extern const upb_MiniTable google_protobuf_DescriptorProto_ExtensionRange_msg_init;
extern const upb_MiniTable google_protobuf_DescriptorProto_ReservedRange_msg_init;
extern const upb_MiniTable google_protobuf_ExtensionRangeOptions_msg_init;
extern const upb_MiniTable google_protobuf_ExtensionRangeOptions_Declaration_msg_init;
extern const upb_MiniTable google_protobuf_FieldDescriptorProto_msg_init;
extern const upb_MiniTable google_protobuf_OneofDescriptorProto_msg_init;
extern const upb_MiniTable google_protobuf_EnumDescriptorProto_msg_init;
extern const upb_MiniTable google_protobuf_EnumDescriptorProto_EnumReservedRange_msg_init;
extern const upb_MiniTable google_protobuf_EnumValueDescriptorProto_msg_init;
extern const upb_MiniTable google_protobuf_ServiceDescriptorProto_msg_init;
extern const upb_MiniTable google_protobuf_MethodDescriptorProto_msg_init;
extern const upb_MiniTable google_protobuf_FileOptions_msg_init;
extern const upb_MiniTable google_protobuf_MessageOptions_msg_init;
extern const upb_MiniTable google_protobuf_FieldOptions_msg_init;
extern const upb_MiniTable google_protobuf_FieldOptions_EditionDefault_msg_init;
extern const upb_MiniTable google_protobuf_OneofOptions_msg_init;
extern const upb_MiniTable google_protobuf_EnumOptions_msg_init;
extern const upb_MiniTable google_protobuf_EnumValueOptions_msg_init;
extern const upb_MiniTable google_protobuf_ServiceOptions_msg_init;
extern const upb_MiniTable google_protobuf_MethodOptions_msg_init;
extern const upb_MiniTable google_protobuf_UninterpretedOption_msg_init;
extern const upb_MiniTable google_protobuf_UninterpretedOption_NamePart_msg_init;
extern const upb_MiniTable google_protobuf_FeatureSet_msg_init;
extern const upb_MiniTable google_protobuf_FeatureSetDefaults_msg_init;
extern const upb_MiniTable google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_msg_init;
extern const upb_MiniTable google_protobuf_SourceCodeInfo_msg_init;
extern const upb_MiniTable google_protobuf_SourceCodeInfo_Location_msg_init;
extern const upb_MiniTable google_protobuf_GeneratedCodeInfo_msg_init;
extern const upb_MiniTable google_protobuf_GeneratedCodeInfo_Annotation_msg_init;
extern const upb_MiniTableEnum google_protobuf_Edition_enum_init;
extern const upb_MiniTableEnum google_protobuf_ExtensionRangeOptions_VerificationState_enum_init;
extern const upb_MiniTableEnum google_protobuf_FeatureSet_EnumType_enum_init;
extern const upb_MiniTableEnum google_protobuf_FeatureSet_FieldPresence_enum_init;
extern const upb_MiniTableEnum google_protobuf_FeatureSet_JsonFormat_enum_init;
extern const upb_MiniTableEnum google_protobuf_FeatureSet_MessageEncoding_enum_init;
extern const upb_MiniTableEnum google_protobuf_FeatureSet_RepeatedFieldEncoding_enum_init;
extern const upb_MiniTableEnum google_protobuf_FieldDescriptorProto_Label_enum_init;
extern const upb_MiniTableEnum google_protobuf_FieldDescriptorProto_Type_enum_init;
extern const upb_MiniTableEnum google_protobuf_FieldOptions_CType_enum_init;
extern const upb_MiniTableEnum google_protobuf_FieldOptions_JSType_enum_init;
extern const upb_MiniTableEnum google_protobuf_FieldOptions_OptionRetention_enum_init;
extern const upb_MiniTableEnum google_protobuf_FieldOptions_OptionTargetType_enum_init;
extern const upb_MiniTableEnum google_protobuf_FileOptions_OptimizeMode_enum_init;
extern const upb_MiniTableEnum google_protobuf_GeneratedCodeInfo_Annotation_Semantic_enum_init;
extern const upb_MiniTableEnum google_protobuf_MethodOptions_IdempotencyLevel_enum_init;
extern const upb_MiniTableFile google_protobuf_descriptor_proto_upb_file_layout;
#ifdef __cplusplus
} /* extern "C" */
#endif
#include "upb/upb/port/undef.inc"
#endif /* GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_MINITABLE_H_ */
Loading…
Cancel
Save