For messages with all trivially copyable fields use the trivial copy of Impl_ in the copy constructor.

PiperOrigin-RevId: 686236500
pull/18797/head
Protobuf Team Bot 5 months ago committed by Copybara-Service
parent 27ddb9ce34
commit 085c6e3234
  1. 2
      src/google/protobuf/compiler/cpp/field.h
  2. 38
      src/google/protobuf/compiler/cpp/message.cc
  3. 5
      src/google/protobuf/compiler/cpp/message.h
  4. 10
      src/google/protobuf/compiler/java/java_features.pb.cc
  5. 10
      src/google/protobuf/cpp_features.pb.cc
  6. 20
      src/google/protobuf/descriptor.pb.cc

@ -254,6 +254,8 @@ class FieldGenerator {
// Properties: see FieldGeneratorBase for documentation
bool should_split() const { return impl_->should_split(); }
bool is_trivial() const { return impl_->is_trivial(); }
// Returns true if the field has trivial copy construction.
bool has_trivial_copy() const { return is_trivial(); }
bool has_trivial_value() const { return impl_->has_trivial_value(); }
bool has_trivial_zero_default() const {
return impl_->has_trivial_zero_default();

@ -3049,32 +3049,18 @@ void MessageGenerator::GenerateConstexprConstructor(io::Printer* p) {
)cc");
}
bool MessageGenerator::ImplHasCopyCtor() const {
bool MessageGenerator::CanUseTrivialCopy() const {
if (ShouldSplit(descriptor_, options_)) return false;
if (HasSimpleBaseClass(descriptor_, options_)) return false;
if (descriptor_->extension_range_count() > 0) return false;
if (descriptor_->real_oneof_decl_count() > 0) return false;
if (num_weak_fields_ > 0) return false;
// If the message contains only scalar fields (ints and enums),
// then we can copy the entire impl_ section with a single statement.
for (const auto* field : optimized_order_) {
if (field->is_repeated()) return false;
if (field->is_extension()) return false;
switch (field->cpp_type()) {
case FieldDescriptor::CPPTYPE_ENUM:
case FieldDescriptor::CPPTYPE_INT32:
case FieldDescriptor::CPPTYPE_INT64:
case FieldDescriptor::CPPTYPE_UINT32:
case FieldDescriptor::CPPTYPE_UINT64:
case FieldDescriptor::CPPTYPE_FLOAT:
case FieldDescriptor::CPPTYPE_DOUBLE:
case FieldDescriptor::CPPTYPE_BOOL:
break;
default:
return false;
}
// If all fields are trivially copyable then we can use the trivial copy
// constructor of Impl_
for (const auto* field : FieldRange(descriptor_)) {
if (!field_generators_.get(field).has_trivial_copy()) return false;
}
return true;
}
@ -3381,13 +3367,19 @@ void MessageGenerator::GenerateStructors(io::Printer* p) {
MergeFrom(from);
}
)cc");
} else if (ImplHasCopyCtor()) {
} else if (CanUseTrivialCopy()) {
p->Emit(R"cc(
$classname$::$classname$(
//~ Force alignment
::$proto_ns$::Arena* arena, const $classname$& from)
: $classname$(arena) {
MergeFrom(from);
#if defined(PROTOBUF_CUSTOM_VTABLE)
: $superclass$(arena, $classname$_class_data_.base()),
#else // PROTOBUF_CUSTOM_VTABLE
: $superclass$(arena),
#endif // PROTOBUF_CUSTOM_VTABLE
_impl_(from._impl_) {
_internal_metadata_.MergeFrom<$unknown_fields_type$>(
from._internal_metadata_);
}
)cc");
} else {

@ -174,8 +174,9 @@ class MessageGenerator {
// the current message's arena, reducing `GetArena()` call churn.
bool RequiresArena(GeneratorFunction function) const;
// Returns whether impl_ has a copy ctor.
bool ImplHasCopyCtor() const;
// Returns true if all fields are trivially copayble, and has no non-field
// state (eg extensions).
bool CanUseTrivialCopy() const;
// Returns the level that this message needs ArenaDtor. If the message has
// a field that is not arena-exclusive, it needs an ArenaDtor

@ -167,8 +167,14 @@ JavaFeatures::JavaFeatures(::google::protobuf::Arena* arena)
}
JavaFeatures::JavaFeatures(
::google::protobuf::Arena* arena, const JavaFeatures& from)
: JavaFeatures(arena) {
MergeFrom(from);
#if defined(PROTOBUF_CUSTOM_VTABLE)
: ::google::protobuf::Message(arena, JavaFeatures_class_data_.base()),
#else // PROTOBUF_CUSTOM_VTABLE
: ::google::protobuf::Message(arena),
#endif // PROTOBUF_CUSTOM_VTABLE
_impl_(from._impl_) {
_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(
from._internal_metadata_);
}
inline PROTOBUF_NDEBUG_INLINE JavaFeatures::Impl_::Impl_(
::google::protobuf::internal::InternalVisibility visibility,

@ -167,8 +167,14 @@ CppFeatures::CppFeatures(::google::protobuf::Arena* arena)
}
CppFeatures::CppFeatures(
::google::protobuf::Arena* arena, const CppFeatures& from)
: CppFeatures(arena) {
MergeFrom(from);
#if defined(PROTOBUF_CUSTOM_VTABLE)
: ::google::protobuf::Message(arena, CppFeatures_class_data_.base()),
#else // PROTOBUF_CUSTOM_VTABLE
: ::google::protobuf::Message(arena),
#endif // PROTOBUF_CUSTOM_VTABLE
_impl_(from._impl_) {
_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(
from._internal_metadata_);
}
inline PROTOBUF_NDEBUG_INLINE CppFeatures::Impl_::Impl_(
::google::protobuf::internal::InternalVisibility visibility,

@ -3892,8 +3892,14 @@ DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(::google::protobuf:
}
DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(
::google::protobuf::Arena* arena, const DescriptorProto_ReservedRange& from)
: DescriptorProto_ReservedRange(arena) {
MergeFrom(from);
#if defined(PROTOBUF_CUSTOM_VTABLE)
: ::google::protobuf::Message(arena, DescriptorProto_ReservedRange_class_data_.base()),
#else // PROTOBUF_CUSTOM_VTABLE
: ::google::protobuf::Message(arena),
#endif // PROTOBUF_CUSTOM_VTABLE
_impl_(from._impl_) {
_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(
from._internal_metadata_);
}
inline PROTOBUF_NDEBUG_INLINE DescriptorProto_ReservedRange::Impl_::Impl_(
::google::protobuf::internal::InternalVisibility visibility,
@ -6402,8 +6408,14 @@ EnumDescriptorProto_EnumReservedRange::EnumDescriptorProto_EnumReservedRange(::g
}
EnumDescriptorProto_EnumReservedRange::EnumDescriptorProto_EnumReservedRange(
::google::protobuf::Arena* arena, const EnumDescriptorProto_EnumReservedRange& from)
: EnumDescriptorProto_EnumReservedRange(arena) {
MergeFrom(from);
#if defined(PROTOBUF_CUSTOM_VTABLE)
: ::google::protobuf::Message(arena, EnumDescriptorProto_EnumReservedRange_class_data_.base()),
#else // PROTOBUF_CUSTOM_VTABLE
: ::google::protobuf::Message(arena),
#endif // PROTOBUF_CUSTOM_VTABLE
_impl_(from._impl_) {
_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(
from._internal_metadata_);
}
inline PROTOBUF_NDEBUG_INLINE EnumDescriptorProto_EnumReservedRange::Impl_::Impl_(
::google::protobuf::internal::InternalVisibility visibility,

Loading…
Cancel
Save