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 6 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 // Properties: see FieldGeneratorBase for documentation
bool should_split() const { return impl_->should_split(); } bool should_split() const { return impl_->should_split(); }
bool is_trivial() const { return impl_->is_trivial(); } 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_value() const { return impl_->has_trivial_value(); }
bool has_trivial_zero_default() const { bool has_trivial_zero_default() const {
return impl_->has_trivial_zero_default(); return impl_->has_trivial_zero_default();

@ -3049,32 +3049,18 @@ void MessageGenerator::GenerateConstexprConstructor(io::Printer* p) {
)cc"); )cc");
} }
bool MessageGenerator::ImplHasCopyCtor() const { bool MessageGenerator::CanUseTrivialCopy() const {
if (ShouldSplit(descriptor_, options_)) return false; if (ShouldSplit(descriptor_, options_)) return false;
if (HasSimpleBaseClass(descriptor_, options_)) return false; if (HasSimpleBaseClass(descriptor_, options_)) return false;
if (descriptor_->extension_range_count() > 0) 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 (num_weak_fields_ > 0) return false;
// If the message contains only scalar fields (ints and enums), // If all fields are trivially copyable then we can use the trivial copy
// then we can copy the entire impl_ section with a single statement. // constructor of Impl_
for (const auto* field : optimized_order_) { for (const auto* field : FieldRange(descriptor_)) {
if (field->is_repeated()) return false; if (!field_generators_.get(field).has_trivial_copy()) 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;
}
} }
return true; return true;
} }
@ -3381,13 +3367,19 @@ void MessageGenerator::GenerateStructors(io::Printer* p) {
MergeFrom(from); MergeFrom(from);
} }
)cc"); )cc");
} else if (ImplHasCopyCtor()) { } else if (CanUseTrivialCopy()) {
p->Emit(R"cc( p->Emit(R"cc(
$classname$::$classname$( $classname$::$classname$(
//~ Force alignment //~ Force alignment
::$proto_ns$::Arena* arena, const $classname$& from) ::$proto_ns$::Arena* arena, const $classname$& from)
: $classname$(arena) { #if defined(PROTOBUF_CUSTOM_VTABLE)
MergeFrom(from); : $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"); )cc");
} else { } else {

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

@ -167,8 +167,14 @@ JavaFeatures::JavaFeatures(::google::protobuf::Arena* arena)
} }
JavaFeatures::JavaFeatures( JavaFeatures::JavaFeatures(
::google::protobuf::Arena* arena, const JavaFeatures& from) ::google::protobuf::Arena* arena, const JavaFeatures& from)
: JavaFeatures(arena) { #if defined(PROTOBUF_CUSTOM_VTABLE)
MergeFrom(from); : ::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_( inline PROTOBUF_NDEBUG_INLINE JavaFeatures::Impl_::Impl_(
::google::protobuf::internal::InternalVisibility visibility, ::google::protobuf::internal::InternalVisibility visibility,

@ -167,8 +167,14 @@ CppFeatures::CppFeatures(::google::protobuf::Arena* arena)
} }
CppFeatures::CppFeatures( CppFeatures::CppFeatures(
::google::protobuf::Arena* arena, const CppFeatures& from) ::google::protobuf::Arena* arena, const CppFeatures& from)
: CppFeatures(arena) { #if defined(PROTOBUF_CUSTOM_VTABLE)
MergeFrom(from); : ::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_( inline PROTOBUF_NDEBUG_INLINE CppFeatures::Impl_::Impl_(
::google::protobuf::internal::InternalVisibility visibility, ::google::protobuf::internal::InternalVisibility visibility,

@ -3892,8 +3892,14 @@ DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(::google::protobuf:
} }
DescriptorProto_ReservedRange::DescriptorProto_ReservedRange( DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(
::google::protobuf::Arena* arena, const DescriptorProto_ReservedRange& from) ::google::protobuf::Arena* arena, const DescriptorProto_ReservedRange& from)
: DescriptorProto_ReservedRange(arena) { #if defined(PROTOBUF_CUSTOM_VTABLE)
MergeFrom(from); : ::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_( inline PROTOBUF_NDEBUG_INLINE DescriptorProto_ReservedRange::Impl_::Impl_(
::google::protobuf::internal::InternalVisibility visibility, ::google::protobuf::internal::InternalVisibility visibility,
@ -6402,8 +6408,14 @@ EnumDescriptorProto_EnumReservedRange::EnumDescriptorProto_EnumReservedRange(::g
} }
EnumDescriptorProto_EnumReservedRange::EnumDescriptorProto_EnumReservedRange( EnumDescriptorProto_EnumReservedRange::EnumDescriptorProto_EnumReservedRange(
::google::protobuf::Arena* arena, const EnumDescriptorProto_EnumReservedRange& from) ::google::protobuf::Arena* arena, const EnumDescriptorProto_EnumReservedRange& from)
: EnumDescriptorProto_EnumReservedRange(arena) { #if defined(PROTOBUF_CUSTOM_VTABLE)
MergeFrom(from); : ::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_( inline PROTOBUF_NDEBUG_INLINE EnumDescriptorProto_EnumReservedRange::Impl_::Impl_(
::google::protobuf::internal::InternalVisibility visibility, ::google::protobuf::internal::InternalVisibility visibility,

Loading…
Cancel
Save