From 58b582ba310afda710585211cc75e7b140284593 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Tue, 30 Jan 2024 14:51:32 -0800 Subject: [PATCH] When using profiling information and weak descriptors use uniquely named sections to allow for GC in the linker. These sections can be merged again after GC. PiperOrigin-RevId: 602848779 --- src/google/protobuf/compiler/cpp/helpers.cc | 11 ++++---- src/google/protobuf/compiler/cpp/helpers.h | 18 ++++++++++--- src/google/protobuf/compiler/cpp/message.cc | 3 ++- .../compiler/cpp/parse_function_generator.cc | 25 +++++++++++++------ .../compiler/cpp/parse_function_generator.h | 4 ++- 5 files changed, 43 insertions(+), 18 deletions(-) diff --git a/src/google/protobuf/compiler/cpp/helpers.cc b/src/google/protobuf/compiler/cpp/helpers.cc index be9563933e..2cbe0a7fd4 100644 --- a/src/google/protobuf/compiler/cpp/helpers.cc +++ b/src/google/protobuf/compiler/cpp/helpers.cc @@ -1489,9 +1489,10 @@ bool UsingImplicitWeakDescriptor(const FileDescriptor* file, !options.opensource_runtime; } -std::string WeakDefaultInstanceSection(const Descriptor* descriptor, - int index_in_file_messages, - const Options& options) { +std::string WeakDescriptorDataSection(absl::string_view prefix, + const Descriptor* descriptor, + int index_in_file_messages, + const Options& options) { const auto* file = descriptor->file(); // To make a compact name we use the index of the object in its file @@ -1499,8 +1500,8 @@ std::string WeakDefaultInstanceSection(const Descriptor* descriptor, // So the name could be `pb_def_3_HASH` instead of // `pd_def_VeryLongClassName_WithNesting_AndMoreNames_HASH` // We need a know common prefix to merge the sections later on. - return UniqueName(absl::StrCat("pb_def_", index_in_file_messages), file, - options); + return UniqueName(absl::StrCat("pb_", prefix, "_", index_in_file_messages), + file, options); } bool UsingImplicitWeakFields(const FileDescriptor* file, diff --git a/src/google/protobuf/compiler/cpp/helpers.h b/src/google/protobuf/compiler/cpp/helpers.h index aa6e346173..6e8f7dce75 100644 --- a/src/google/protobuf/compiler/cpp/helpers.h +++ b/src/google/protobuf/compiler/cpp/helpers.h @@ -778,11 +778,23 @@ void ListAllTypesForServices(const FileDescriptor* fd, bool UsingImplicitWeakDescriptor(const FileDescriptor* file, const Options& options); +// Generate the section name to be used for a data object when using implicit +// weak descriptors. The prefix determines the kind of object and the section it +// will be merged into afterwards. +// See `UsingImplicitWeakDescriptor` above. +std::string WeakDescriptorDataSection(absl::string_view prefix, + const Descriptor* descriptor, + int index_in_file_messages, + const Options& options); + // Section name to be used for the default instance for implicit weak descriptor // objects. See `UsingImplicitWeakDescriptor` above. -std::string WeakDefaultInstanceSection(const Descriptor* descriptor, - int index_in_file_messages, - const Options& options); +inline std::string WeakDefaultInstanceSection(const Descriptor* descriptor, + int index_in_file_messages, + const Options& options) { + return WeakDescriptorDataSection("def", descriptor, index_in_file_messages, + options); +} // Indicates whether we should use implicit weak fields for this file. bool UsingImplicitWeakFields(const FileDescriptor* file, diff --git a/src/google/protobuf/compiler/cpp/message.cc b/src/google/protobuf/compiler/cpp/message.cc index 35a9fa9d71..6af2a44964 100644 --- a/src/google/protobuf/compiler/cpp/message.cc +++ b/src/google/protobuf/compiler/cpp/message.cc @@ -573,7 +573,8 @@ MessageGenerator::MessageGenerator( parse_function_generator_ = std::make_unique( descriptor_, max_has_bit_index_, has_bit_indices_, - inlined_string_indices_, options_, scc_analyzer_, variables_); + inlined_string_indices_, options_, scc_analyzer_, variables_, + index_in_file_messages_); } size_t MessageGenerator::HasBitsSize() const { diff --git a/src/google/protobuf/compiler/cpp/parse_function_generator.cc b/src/google/protobuf/compiler/cpp/parse_function_generator.cc index 7271815c6b..cf139a5591 100644 --- a/src/google/protobuf/compiler/cpp/parse_function_generator.cc +++ b/src/google/protobuf/compiler/cpp/parse_function_generator.cc @@ -103,14 +103,16 @@ ParseFunctionGenerator::ParseFunctionGenerator( const std::vector& has_bit_indices, const std::vector& inlined_string_indices, const Options& options, MessageSCCAnalyzer* scc_analyzer, - const absl::flat_hash_map& vars) + const absl::flat_hash_map& vars, + int index_in_file_messages) : descriptor_(descriptor), scc_analyzer_(scc_analyzer), options_(options), variables_(vars), inlined_string_indices_(inlined_string_indices), ordered_fields_(GetOrderedFields(descriptor_, options_)), - num_hasbits_(max_has_bit_index) { + num_hasbits_(max_has_bit_index), + index_in_file_messages_(index_in_file_messages) { if (should_generate_tctable()) { tc_table_info_.reset(new TailCallTableInfo( descriptor_, ordered_fields_, @@ -228,16 +230,23 @@ void ParseFunctionGenerator::GenerateDataDecls(io::Printer* p) { {"SECTION", [&] { if (!IsProfileDriven(options_)) return; + std::string section_name; // Since most (>80%) messages are never present, messages that are // present are considered hot enough to be clustered together. - if (IsPresentMessage(descriptor_, options_)) { - p->Emit( - "ABSL_ATTRIBUTE_SECTION_VARIABLE(proto_parse_table_hot)"); + // When using weak descriptors we use unique sections for each + // table to allow for GC to work. pth/ptl names must be in sync + // with the linker script. + if (UsingImplicitWeakDescriptor(descriptor_->file(), options_)) { + section_name = WeakDescriptorDataSection( + IsPresentMessage(descriptor_, options_) ? "pth" : "ptl", + descriptor_, index_in_file_messages_, options_); + } else if (IsPresentMessage(descriptor_, options_)) { + section_name = "proto_parse_table_hot"; } else { - p->Emit( - "ABSL_ATTRIBUTE_SECTION_VARIABLE(proto_parse_table_" - "lukewarm)"); + section_name = "proto_parse_table_lukewarm"; } + p->Emit({{"section_name", section_name}}, + "ABSL_ATTRIBUTE_SECTION_VARIABLE($section_name$)"); }}, {"table_size_log2", tc_table_info_->table_size_log2}, {"num_field_entries", ordered_fields_.size()}, diff --git a/src/google/protobuf/compiler/cpp/parse_function_generator.h b/src/google/protobuf/compiler/cpp/parse_function_generator.h index c7c2f9e944..4e76d30230 100644 --- a/src/google/protobuf/compiler/cpp/parse_function_generator.h +++ b/src/google/protobuf/compiler/cpp/parse_function_generator.h @@ -33,7 +33,8 @@ class ParseFunctionGenerator { const std::vector& has_bit_indices, const std::vector& inlined_string_indices, const Options& options, MessageSCCAnalyzer* scc_analyzer, - const absl::flat_hash_map& vars); + const absl::flat_hash_map& vars, + int index_in_file_messages); // Emits class-level method declarations to `printer`: void GenerateMethodDecls(io::Printer* printer); @@ -70,6 +71,7 @@ class ParseFunctionGenerator { std::vector inlined_string_indices_; const std::vector ordered_fields_; int num_hasbits_; + int index_in_file_messages_; }; } // namespace cpp