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
pull/15648/head
Protobuf Team Bot 1 year ago committed by Copybara-Service
parent 758f5cbe19
commit 58b582ba31
  1. 11
      src/google/protobuf/compiler/cpp/helpers.cc
  2. 18
      src/google/protobuf/compiler/cpp/helpers.h
  3. 3
      src/google/protobuf/compiler/cpp/message.cc
  4. 25
      src/google/protobuf/compiler/cpp/parse_function_generator.cc
  5. 4
      src/google/protobuf/compiler/cpp/parse_function_generator.h

@ -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,

@ -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,

@ -573,7 +573,8 @@ MessageGenerator::MessageGenerator(
parse_function_generator_ = std::make_unique<ParseFunctionGenerator>(
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 {

@ -103,14 +103,16 @@ ParseFunctionGenerator::ParseFunctionGenerator(
const std::vector<int>& has_bit_indices,
const std::vector<int>& inlined_string_indices, const Options& options,
MessageSCCAnalyzer* scc_analyzer,
const absl::flat_hash_map<absl::string_view, std::string>& vars)
const absl::flat_hash_map<absl::string_view, std::string>& 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()},

@ -33,7 +33,8 @@ class ParseFunctionGenerator {
const std::vector<int>& has_bit_indices,
const std::vector<int>& inlined_string_indices, const Options& options,
MessageSCCAnalyzer* scc_analyzer,
const absl::flat_hash_map<absl::string_view, std::string>& vars);
const absl::flat_hash_map<absl::string_view, std::string>& 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<int> inlined_string_indices_;
const std::vector<const FieldDescriptor*> ordered_fields_;
int num_hasbits_;
int index_in_file_messages_;
};
} // namespace cpp

Loading…
Cancel
Save