diff --git a/src/google/protobuf/compiler/cpp/file.cc b/src/google/protobuf/compiler/cpp/file.cc index 49b077351c..4fd127f084 100644 --- a/src/google/protobuf/compiler/cpp/file.cc +++ b/src/google/protobuf/compiler/cpp/file.cc @@ -1242,11 +1242,18 @@ class FileGenerator::ForwardDeclarations { } void PrintTopLevelDecl(io::Printer* p, const Options& options) const { - for (const auto& c : classes_) { - p->Emit({{"class", QualifiedClassName(c.second, options)}}, R"cc( - template <> - $dllexport_decl $$class$* Arena::CreateMaybeMessage<$class$>(Arena*); - )cc"); + if (ShouldGenerateExternSpecializations(options)) { + for (const auto& c : classes_) { + // To reduce total linker input size in large binaries we make these + // functions extern and define then in the pb.cc file. This avoids bloat + // in callers by having duplicate definitions of the template. + // However, it increases the size of the pb.cc translation units so it + // is a tradeoff. + p->Emit({{"class", QualifiedClassName(c.second, options)}}, R"cc( + template <> + $dllexport_decl $$class$* Arena::CreateMaybeMessage<$class$>(Arena*); + )cc"); + } } } diff --git a/src/google/protobuf/compiler/cpp/helpers.h b/src/google/protobuf/compiler/cpp/helpers.h index c88c12a479..6ab842ee94 100644 --- a/src/google/protobuf/compiler/cpp/helpers.h +++ b/src/google/protobuf/compiler/cpp/helpers.h @@ -1008,6 +1008,14 @@ void GenerateUtf8CheckCodeForCord(io::Printer* p, const FieldDescriptor* field, const Options& options, bool for_parse, absl::string_view parameters); +inline bool ShouldGenerateExternSpecializations(const Options& options) { + // For OSS we omit the specializations to reduce codegen size. + // Some compilers can't handle that much input in a single translation unit. + // These specializations are just a link size optimization and do not affect + // correctness or performance, so it is ok to omit them. + return !options.opensource_runtime; +} + struct OneOfRangeImpl { struct Iterator { using iterator_category = std::forward_iterator_tag; diff --git a/src/google/protobuf/compiler/cpp/message.cc b/src/google/protobuf/compiler/cpp/message.cc index a623bf66eb..b9dfb7a70e 100644 --- a/src/google/protobuf/compiler/cpp/message.cc +++ b/src/google/protobuf/compiler/cpp/message.cc @@ -2953,12 +2953,14 @@ void MessageGenerator::GenerateSourceInProto2Namespace(io::Printer* p) { auto v = p->WithVars(ClassVars(descriptor_, options_)); auto t = p->WithVars(MakeTrackerCalls(descriptor_, options_)); Formatter format(p); - format( - "template<> " - "PROTOBUF_NOINLINE $classtype$*\n" - "Arena::CreateMaybeMessage< $classtype$ >(Arena* arena) {\n" - " return Arena::CreateMessageInternal< $classtype$ >(arena);\n" - "}\n"); + if (ShouldGenerateExternSpecializations(options_)) { + format( + "template<> " + "PROTOBUF_NOINLINE $classtype$*\n" + "Arena::CreateMaybeMessage< $classtype$ >(Arena* arena) {\n" + " return Arena::CreateMessageInternal< $classtype$ >(arena);\n" + "}\n"); + } } void MessageGenerator::GenerateClear(io::Printer* p) { diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc index 532469ac9d..b4b57ce99d 100644 --- a/src/google/protobuf/compiler/plugin.pb.cc +++ b/src/google/protobuf/compiler/plugin.pb.cc @@ -1584,22 +1584,6 @@ void CodeGeneratorResponse::InternalSwap(CodeGeneratorResponse* other) { } // namespace google namespace google { namespace protobuf { -template<> PROTOBUF_NOINLINE ::google::protobuf::compiler::Version* -Arena::CreateMaybeMessage< ::google::protobuf::compiler::Version >(Arena* arena) { - return Arena::CreateMessageInternal< ::google::protobuf::compiler::Version >(arena); -} -template<> PROTOBUF_NOINLINE ::google::protobuf::compiler::CodeGeneratorRequest* -Arena::CreateMaybeMessage< ::google::protobuf::compiler::CodeGeneratorRequest >(Arena* arena) { - return Arena::CreateMessageInternal< ::google::protobuf::compiler::CodeGeneratorRequest >(arena); -} -template<> PROTOBUF_NOINLINE ::google::protobuf::compiler::CodeGeneratorResponse_File* -Arena::CreateMaybeMessage< ::google::protobuf::compiler::CodeGeneratorResponse_File >(Arena* arena) { - return Arena::CreateMessageInternal< ::google::protobuf::compiler::CodeGeneratorResponse_File >(arena); -} -template<> PROTOBUF_NOINLINE ::google::protobuf::compiler::CodeGeneratorResponse* -Arena::CreateMaybeMessage< ::google::protobuf::compiler::CodeGeneratorResponse >(Arena* arena) { - return Arena::CreateMessageInternal< ::google::protobuf::compiler::CodeGeneratorResponse >(arena); -} } // namespace protobuf } // namespace google // @@protoc_insertion_point(global_scope) diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h index ac6a28d33e..70740fd91b 100644 --- a/src/google/protobuf/compiler/plugin.pb.h +++ b/src/google/protobuf/compiler/plugin.pb.h @@ -77,14 +77,6 @@ class Version; struct VersionDefaultTypeInternal; PROTOC_EXPORT extern VersionDefaultTypeInternal _Version_default_instance_; } // namespace compiler -template <> -PROTOC_EXPORT ::google::protobuf::compiler::CodeGeneratorRequest* Arena::CreateMaybeMessage<::google::protobuf::compiler::CodeGeneratorRequest>(Arena*); -template <> -PROTOC_EXPORT ::google::protobuf::compiler::CodeGeneratorResponse* Arena::CreateMaybeMessage<::google::protobuf::compiler::CodeGeneratorResponse>(Arena*); -template <> -PROTOC_EXPORT ::google::protobuf::compiler::CodeGeneratorResponse_File* Arena::CreateMaybeMessage<::google::protobuf::compiler::CodeGeneratorResponse_File>(Arena*); -template <> -PROTOC_EXPORT ::google::protobuf::compiler::Version* Arena::CreateMaybeMessage<::google::protobuf::compiler::Version>(Arena*); } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/cpp_features.pb.cc b/src/google/protobuf/cpp_features.pb.cc index 0bc05b172a..fe004416c2 100644 --- a/src/google/protobuf/cpp_features.pb.cc +++ b/src/google/protobuf/cpp_features.pb.cc @@ -296,10 +296,6 @@ PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 } // namespace pb namespace google { namespace protobuf { -template<> PROTOBUF_NOINLINE ::pb::CppFeatures* -Arena::CreateMaybeMessage< ::pb::CppFeatures >(Arena* arena) { - return Arena::CreateMessageInternal< ::pb::CppFeatures >(arena); -} } // namespace protobuf } // namespace google // @@protoc_insertion_point(global_scope) diff --git a/src/google/protobuf/cpp_features.pb.h b/src/google/protobuf/cpp_features.pb.h index 948569b192..0d98464c96 100644 --- a/src/google/protobuf/cpp_features.pb.h +++ b/src/google/protobuf/cpp_features.pb.h @@ -61,8 +61,6 @@ PROTOBUF_EXPORT extern CppFeaturesDefaultTypeInternal _CppFeatures_default_insta } // namespace pb namespace google { namespace protobuf { -template <> -PROTOBUF_EXPORT ::pb::CppFeatures* Arena::CreateMaybeMessage<::pb::CppFeatures>(Arena*); } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc index f2221a6ea2..5fdfde4d21 100644 --- a/src/google/protobuf/descriptor.pb.cc +++ b/src/google/protobuf/descriptor.pb.cc @@ -13122,126 +13122,6 @@ void GeneratedCodeInfo::InternalSwap(GeneratedCodeInfo* other) { } // namespace google namespace google { namespace protobuf { -template<> PROTOBUF_NOINLINE ::google::protobuf::FileDescriptorSet* -Arena::CreateMaybeMessage< ::google::protobuf::FileDescriptorSet >(Arena* arena) { - return Arena::CreateMessageInternal< ::google::protobuf::FileDescriptorSet >(arena); -} -template<> PROTOBUF_NOINLINE ::google::protobuf::FileDescriptorProto* -Arena::CreateMaybeMessage< ::google::protobuf::FileDescriptorProto >(Arena* arena) { - return Arena::CreateMessageInternal< ::google::protobuf::FileDescriptorProto >(arena); -} -template<> PROTOBUF_NOINLINE ::google::protobuf::DescriptorProto_ExtensionRange* -Arena::CreateMaybeMessage< ::google::protobuf::DescriptorProto_ExtensionRange >(Arena* arena) { - return Arena::CreateMessageInternal< ::google::protobuf::DescriptorProto_ExtensionRange >(arena); -} -template<> PROTOBUF_NOINLINE ::google::protobuf::DescriptorProto_ReservedRange* -Arena::CreateMaybeMessage< ::google::protobuf::DescriptorProto_ReservedRange >(Arena* arena) { - return Arena::CreateMessageInternal< ::google::protobuf::DescriptorProto_ReservedRange >(arena); -} -template<> PROTOBUF_NOINLINE ::google::protobuf::DescriptorProto* -Arena::CreateMaybeMessage< ::google::protobuf::DescriptorProto >(Arena* arena) { - return Arena::CreateMessageInternal< ::google::protobuf::DescriptorProto >(arena); -} -template<> PROTOBUF_NOINLINE ::google::protobuf::ExtensionRangeOptions_Declaration* -Arena::CreateMaybeMessage< ::google::protobuf::ExtensionRangeOptions_Declaration >(Arena* arena) { - return Arena::CreateMessageInternal< ::google::protobuf::ExtensionRangeOptions_Declaration >(arena); -} -template<> PROTOBUF_NOINLINE ::google::protobuf::ExtensionRangeOptions* -Arena::CreateMaybeMessage< ::google::protobuf::ExtensionRangeOptions >(Arena* arena) { - return Arena::CreateMessageInternal< ::google::protobuf::ExtensionRangeOptions >(arena); -} -template<> PROTOBUF_NOINLINE ::google::protobuf::FieldDescriptorProto* -Arena::CreateMaybeMessage< ::google::protobuf::FieldDescriptorProto >(Arena* arena) { - return Arena::CreateMessageInternal< ::google::protobuf::FieldDescriptorProto >(arena); -} -template<> PROTOBUF_NOINLINE ::google::protobuf::OneofDescriptorProto* -Arena::CreateMaybeMessage< ::google::protobuf::OneofDescriptorProto >(Arena* arena) { - return Arena::CreateMessageInternal< ::google::protobuf::OneofDescriptorProto >(arena); -} -template<> PROTOBUF_NOINLINE ::google::protobuf::EnumDescriptorProto_EnumReservedRange* -Arena::CreateMaybeMessage< ::google::protobuf::EnumDescriptorProto_EnumReservedRange >(Arena* arena) { - return Arena::CreateMessageInternal< ::google::protobuf::EnumDescriptorProto_EnumReservedRange >(arena); -} -template<> PROTOBUF_NOINLINE ::google::protobuf::EnumDescriptorProto* -Arena::CreateMaybeMessage< ::google::protobuf::EnumDescriptorProto >(Arena* arena) { - return Arena::CreateMessageInternal< ::google::protobuf::EnumDescriptorProto >(arena); -} -template<> PROTOBUF_NOINLINE ::google::protobuf::EnumValueDescriptorProto* -Arena::CreateMaybeMessage< ::google::protobuf::EnumValueDescriptorProto >(Arena* arena) { - return Arena::CreateMessageInternal< ::google::protobuf::EnumValueDescriptorProto >(arena); -} -template<> PROTOBUF_NOINLINE ::google::protobuf::ServiceDescriptorProto* -Arena::CreateMaybeMessage< ::google::protobuf::ServiceDescriptorProto >(Arena* arena) { - return Arena::CreateMessageInternal< ::google::protobuf::ServiceDescriptorProto >(arena); -} -template<> PROTOBUF_NOINLINE ::google::protobuf::MethodDescriptorProto* -Arena::CreateMaybeMessage< ::google::protobuf::MethodDescriptorProto >(Arena* arena) { - return Arena::CreateMessageInternal< ::google::protobuf::MethodDescriptorProto >(arena); -} -template<> PROTOBUF_NOINLINE ::google::protobuf::FileOptions* -Arena::CreateMaybeMessage< ::google::protobuf::FileOptions >(Arena* arena) { - return Arena::CreateMessageInternal< ::google::protobuf::FileOptions >(arena); -} -template<> PROTOBUF_NOINLINE ::google::protobuf::MessageOptions* -Arena::CreateMaybeMessage< ::google::protobuf::MessageOptions >(Arena* arena) { - return Arena::CreateMessageInternal< ::google::protobuf::MessageOptions >(arena); -} -template<> PROTOBUF_NOINLINE ::google::protobuf::FieldOptions_EditionDefault* -Arena::CreateMaybeMessage< ::google::protobuf::FieldOptions_EditionDefault >(Arena* arena) { - return Arena::CreateMessageInternal< ::google::protobuf::FieldOptions_EditionDefault >(arena); -} -template<> PROTOBUF_NOINLINE ::google::protobuf::FieldOptions* -Arena::CreateMaybeMessage< ::google::protobuf::FieldOptions >(Arena* arena) { - return Arena::CreateMessageInternal< ::google::protobuf::FieldOptions >(arena); -} -template<> PROTOBUF_NOINLINE ::google::protobuf::OneofOptions* -Arena::CreateMaybeMessage< ::google::protobuf::OneofOptions >(Arena* arena) { - return Arena::CreateMessageInternal< ::google::protobuf::OneofOptions >(arena); -} -template<> PROTOBUF_NOINLINE ::google::protobuf::EnumOptions* -Arena::CreateMaybeMessage< ::google::protobuf::EnumOptions >(Arena* arena) { - return Arena::CreateMessageInternal< ::google::protobuf::EnumOptions >(arena); -} -template<> PROTOBUF_NOINLINE ::google::protobuf::EnumValueOptions* -Arena::CreateMaybeMessage< ::google::protobuf::EnumValueOptions >(Arena* arena) { - return Arena::CreateMessageInternal< ::google::protobuf::EnumValueOptions >(arena); -} -template<> PROTOBUF_NOINLINE ::google::protobuf::ServiceOptions* -Arena::CreateMaybeMessage< ::google::protobuf::ServiceOptions >(Arena* arena) { - return Arena::CreateMessageInternal< ::google::protobuf::ServiceOptions >(arena); -} -template<> PROTOBUF_NOINLINE ::google::protobuf::MethodOptions* -Arena::CreateMaybeMessage< ::google::protobuf::MethodOptions >(Arena* arena) { - return Arena::CreateMessageInternal< ::google::protobuf::MethodOptions >(arena); -} -template<> PROTOBUF_NOINLINE ::google::protobuf::UninterpretedOption_NamePart* -Arena::CreateMaybeMessage< ::google::protobuf::UninterpretedOption_NamePart >(Arena* arena) { - return Arena::CreateMessageInternal< ::google::protobuf::UninterpretedOption_NamePart >(arena); -} -template<> PROTOBUF_NOINLINE ::google::protobuf::UninterpretedOption* -Arena::CreateMaybeMessage< ::google::protobuf::UninterpretedOption >(Arena* arena) { - return Arena::CreateMessageInternal< ::google::protobuf::UninterpretedOption >(arena); -} -template<> PROTOBUF_NOINLINE ::google::protobuf::FeatureSet* -Arena::CreateMaybeMessage< ::google::protobuf::FeatureSet >(Arena* arena) { - return Arena::CreateMessageInternal< ::google::protobuf::FeatureSet >(arena); -} -template<> PROTOBUF_NOINLINE ::google::protobuf::SourceCodeInfo_Location* -Arena::CreateMaybeMessage< ::google::protobuf::SourceCodeInfo_Location >(Arena* arena) { - return Arena::CreateMessageInternal< ::google::protobuf::SourceCodeInfo_Location >(arena); -} -template<> PROTOBUF_NOINLINE ::google::protobuf::SourceCodeInfo* -Arena::CreateMaybeMessage< ::google::protobuf::SourceCodeInfo >(Arena* arena) { - return Arena::CreateMessageInternal< ::google::protobuf::SourceCodeInfo >(arena); -} -template<> PROTOBUF_NOINLINE ::google::protobuf::GeneratedCodeInfo_Annotation* -Arena::CreateMaybeMessage< ::google::protobuf::GeneratedCodeInfo_Annotation >(Arena* arena) { - return Arena::CreateMessageInternal< ::google::protobuf::GeneratedCodeInfo_Annotation >(arena); -} -template<> PROTOBUF_NOINLINE ::google::protobuf::GeneratedCodeInfo* -Arena::CreateMaybeMessage< ::google::protobuf::GeneratedCodeInfo >(Arena* arena) { - return Arena::CreateMessageInternal< ::google::protobuf::GeneratedCodeInfo >(arena); -} } // namespace protobuf } // namespace google // @@protoc_insertion_point(global_scope) diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h index 68073b97a7..9483f3baae 100644 --- a/src/google/protobuf/descriptor.pb.h +++ b/src/google/protobuf/descriptor.pb.h @@ -146,66 +146,6 @@ PROTOBUF_EXPORT extern UninterpretedOptionDefaultTypeInternal _UninterpretedOpti class UninterpretedOption_NamePart; struct UninterpretedOption_NamePartDefaultTypeInternal; PROTOBUF_EXPORT extern UninterpretedOption_NamePartDefaultTypeInternal _UninterpretedOption_NamePart_default_instance_; -template <> -PROTOBUF_EXPORT ::google::protobuf::DescriptorProto* Arena::CreateMaybeMessage<::google::protobuf::DescriptorProto>(Arena*); -template <> -PROTOBUF_EXPORT ::google::protobuf::DescriptorProto_ExtensionRange* Arena::CreateMaybeMessage<::google::protobuf::DescriptorProto_ExtensionRange>(Arena*); -template <> -PROTOBUF_EXPORT ::google::protobuf::DescriptorProto_ReservedRange* Arena::CreateMaybeMessage<::google::protobuf::DescriptorProto_ReservedRange>(Arena*); -template <> -PROTOBUF_EXPORT ::google::protobuf::EnumDescriptorProto* Arena::CreateMaybeMessage<::google::protobuf::EnumDescriptorProto>(Arena*); -template <> -PROTOBUF_EXPORT ::google::protobuf::EnumDescriptorProto_EnumReservedRange* Arena::CreateMaybeMessage<::google::protobuf::EnumDescriptorProto_EnumReservedRange>(Arena*); -template <> -PROTOBUF_EXPORT ::google::protobuf::EnumOptions* Arena::CreateMaybeMessage<::google::protobuf::EnumOptions>(Arena*); -template <> -PROTOBUF_EXPORT ::google::protobuf::EnumValueDescriptorProto* Arena::CreateMaybeMessage<::google::protobuf::EnumValueDescriptorProto>(Arena*); -template <> -PROTOBUF_EXPORT ::google::protobuf::EnumValueOptions* Arena::CreateMaybeMessage<::google::protobuf::EnumValueOptions>(Arena*); -template <> -PROTOBUF_EXPORT ::google::protobuf::ExtensionRangeOptions* Arena::CreateMaybeMessage<::google::protobuf::ExtensionRangeOptions>(Arena*); -template <> -PROTOBUF_EXPORT ::google::protobuf::ExtensionRangeOptions_Declaration* Arena::CreateMaybeMessage<::google::protobuf::ExtensionRangeOptions_Declaration>(Arena*); -template <> -PROTOBUF_EXPORT ::google::protobuf::FeatureSet* Arena::CreateMaybeMessage<::google::protobuf::FeatureSet>(Arena*); -template <> -PROTOBUF_EXPORT ::google::protobuf::FieldDescriptorProto* Arena::CreateMaybeMessage<::google::protobuf::FieldDescriptorProto>(Arena*); -template <> -PROTOBUF_EXPORT ::google::protobuf::FieldOptions* Arena::CreateMaybeMessage<::google::protobuf::FieldOptions>(Arena*); -template <> -PROTOBUF_EXPORT ::google::protobuf::FieldOptions_EditionDefault* Arena::CreateMaybeMessage<::google::protobuf::FieldOptions_EditionDefault>(Arena*); -template <> -PROTOBUF_EXPORT ::google::protobuf::FileDescriptorProto* Arena::CreateMaybeMessage<::google::protobuf::FileDescriptorProto>(Arena*); -template <> -PROTOBUF_EXPORT ::google::protobuf::FileDescriptorSet* Arena::CreateMaybeMessage<::google::protobuf::FileDescriptorSet>(Arena*); -template <> -PROTOBUF_EXPORT ::google::protobuf::FileOptions* Arena::CreateMaybeMessage<::google::protobuf::FileOptions>(Arena*); -template <> -PROTOBUF_EXPORT ::google::protobuf::GeneratedCodeInfo* Arena::CreateMaybeMessage<::google::protobuf::GeneratedCodeInfo>(Arena*); -template <> -PROTOBUF_EXPORT ::google::protobuf::GeneratedCodeInfo_Annotation* Arena::CreateMaybeMessage<::google::protobuf::GeneratedCodeInfo_Annotation>(Arena*); -template <> -PROTOBUF_EXPORT ::google::protobuf::MessageOptions* Arena::CreateMaybeMessage<::google::protobuf::MessageOptions>(Arena*); -template <> -PROTOBUF_EXPORT ::google::protobuf::MethodDescriptorProto* Arena::CreateMaybeMessage<::google::protobuf::MethodDescriptorProto>(Arena*); -template <> -PROTOBUF_EXPORT ::google::protobuf::MethodOptions* Arena::CreateMaybeMessage<::google::protobuf::MethodOptions>(Arena*); -template <> -PROTOBUF_EXPORT ::google::protobuf::OneofDescriptorProto* Arena::CreateMaybeMessage<::google::protobuf::OneofDescriptorProto>(Arena*); -template <> -PROTOBUF_EXPORT ::google::protobuf::OneofOptions* Arena::CreateMaybeMessage<::google::protobuf::OneofOptions>(Arena*); -template <> -PROTOBUF_EXPORT ::google::protobuf::ServiceDescriptorProto* Arena::CreateMaybeMessage<::google::protobuf::ServiceDescriptorProto>(Arena*); -template <> -PROTOBUF_EXPORT ::google::protobuf::ServiceOptions* Arena::CreateMaybeMessage<::google::protobuf::ServiceOptions>(Arena*); -template <> -PROTOBUF_EXPORT ::google::protobuf::SourceCodeInfo* Arena::CreateMaybeMessage<::google::protobuf::SourceCodeInfo>(Arena*); -template <> -PROTOBUF_EXPORT ::google::protobuf::SourceCodeInfo_Location* Arena::CreateMaybeMessage<::google::protobuf::SourceCodeInfo_Location>(Arena*); -template <> -PROTOBUF_EXPORT ::google::protobuf::UninterpretedOption* Arena::CreateMaybeMessage<::google::protobuf::UninterpretedOption>(Arena*); -template <> -PROTOBUF_EXPORT ::google::protobuf::UninterpretedOption_NamePart* Arena::CreateMaybeMessage<::google::protobuf::UninterpretedOption_NamePart>(Arena*); namespace internal { #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) PROTOBUF_EXPORT void InitializeFileDescriptorDefaultInstancesSlow();