Improve pinning assembly when using a clang that supports it.

The new technique adds the relocation without adding an instruction that has to be executed in the code path.

PiperOrigin-RevId: 609437563
pull/15818/head
Protobuf Team Bot 9 months ago committed by Copybara-Service
parent b33682537b
commit 6722988db6
  1. 4
      src/google/protobuf/compiler/cpp/field.cc
  2. 5
      src/google/protobuf/compiler/cpp/field_generators/message_field.cc
  3. 11
      src/google/protobuf/compiler/cpp/file.cc
  4. 7
      src/google/protobuf/compiler/cpp/helpers.cc
  5. 6
      src/google/protobuf/compiler/cpp/helpers.h
  6. 24
      src/google/protobuf/compiler/cpp/message.cc
  7. 4
      src/google/protobuf/compiler/java/java_features.pb.h
  8. 16
      src/google/protobuf/compiler/plugin.pb.h
  9. 4
      src/google/protobuf/cpp_features.pb.h
  10. 128
      src/google/protobuf/descriptor.pb.h
  11. 3
      src/google/protobuf/generated_message_util.cc
  12. 6
      src/google/protobuf/message.h
  13. 20
      src/google/protobuf/message_lite.h
  14. 28
      src/google/protobuf/port.h

@ -87,8 +87,8 @@ std::vector<Sub> FieldVars(const FieldDescriptor* field, const Options& opts) {
{"deprecated_attr", DeprecatedAttribute(opts, field)}, {"deprecated_attr", DeprecatedAttribute(opts, field)},
Sub("WeakDescriptorSelfPin", Sub("WeakDescriptorSelfPin",
UsingImplicitWeakDescriptor(field->file(), opts) UsingImplicitWeakDescriptor(field->file(), opts)
? absl::StrCat("::", ProtobufNamespace(opts), ? absl::StrCat(
"::internal::StrongReference(default_instance());") StrongReferenceToType(field->containing_type(), opts), ";")
: "") : "")
.WithSuffix(";"), .WithSuffix(";"),
}; };

@ -72,9 +72,8 @@ std::vector<Sub> Vars(const FieldDescriptor* field, const Options& opts,
{"_weak", weak ? "_weak" : ""}, {"_weak", weak ? "_weak" : ""},
Sub("StrongRef", Sub("StrongRef",
!weak ? "" !weak ? ""
: absl::Substitute("::google::protobuf::internal::StrongReference(" : absl::StrCat(
"reinterpret_cast<const $0&>($1));\n", StrongReferenceToType(field->message_type(), opts), ";"))
qualified_type, default_ref))
.WithSuffix(";"), .WithSuffix(";"),
}; };
} }

@ -1264,13 +1264,10 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* p) {
if (UsingImplicitWeakDescriptor(file_, options_)) { if (UsingImplicitWeakDescriptor(file_, options_)) {
for (auto* pinned : GetMessagesToPinGloballyForWeakDescriptors(file_)) { for (auto* pinned : GetMessagesToPinGloballyForWeakDescriptors(file_)) {
static_initializers_.push_back([this, pinned](auto* p) { static_initializers_.push_back([this, pinned](auto* p) {
p->Emit( p->Emit({{"pin", StrongReferenceToType(pinned, options_)}},
{ R"cc(
{"default", QualifiedDefaultInstanceName(pinned, options_)}, $pin$,
}, )cc");
R"cc(
::_pbi::StrongPointer(&$default$),
)cc");
}); });
} }
} }

@ -1489,6 +1489,13 @@ bool UsingImplicitWeakDescriptor(const FileDescriptor* file,
!options.opensource_runtime; !options.opensource_runtime;
} }
std::string StrongReferenceToType(const Descriptor* desc,
const Options& options) {
const auto name = QualifiedDefaultInstanceName(desc, options);
return absl::StrFormat("::%s::internal::StrongPointer<decltype(%s)*, &%s>()",
ProtobufNamespace(options), name, name);
}
std::string WeakDescriptorDataSection(absl::string_view prefix, std::string WeakDescriptorDataSection(absl::string_view prefix,
const Descriptor* descriptor, const Descriptor* descriptor,
int index_in_file_messages, int index_in_file_messages,

@ -786,7 +786,11 @@ void ListAllTypesForServices(const FileDescriptor* fd,
bool UsingImplicitWeakDescriptor(const FileDescriptor* file, bool UsingImplicitWeakDescriptor(const FileDescriptor* file,
const Options& options); const Options& options);
// Generate the section name to be used for a data object when using implicit // Generates a strong reference to the message in `desc`, as a statement.
std::string StrongReferenceToType(const Descriptor* desc,
const Options& options);
// Generates 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 // weak descriptors. The prefix determines the kind of object and the section it
// will be merged into afterwards. // will be merged into afterwards.
// See `UsingImplicitWeakDescriptor` above. // See `UsingImplicitWeakDescriptor` above.

@ -489,8 +489,7 @@ std::vector<Sub> ClassVars(const Descriptor* desc, Options opts) {
Sub("WeakDescriptorSelfPin", Sub("WeakDescriptorSelfPin",
UsingImplicitWeakDescriptor(desc->file(), opts) UsingImplicitWeakDescriptor(desc->file(), opts)
? absl::StrCat("::", ProtobufNamespace(opts), ? absl::StrCat(StrongReferenceToType(desc, opts), ";")
"::internal::StrongReference(default_instance());")
: "") : "")
.WithSuffix(";"), .WithSuffix(";"),
}; };
@ -2090,6 +2089,10 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* p) {
$decl_oneof_has$; $decl_oneof_has$;
$decl_data$; $decl_data$;
$post_loop_handler$; $post_loop_handler$;
static constexpr const void* _raw_default_instance_ =
&_$classname$_default_instance_;
friend class ::$proto_ns$::MessageLite; friend class ::$proto_ns$::MessageLite;
friend class ::$proto_ns$::Arena; friend class ::$proto_ns$::Arena;
template <typename T> template <typename T>
@ -3587,9 +3590,10 @@ void MessageGenerator::GenerateClassData(io::Printer* p) {
const auto pin_weak_descriptor = [&] { const auto pin_weak_descriptor = [&] {
if (!UsingImplicitWeakDescriptor(descriptor_->file(), options_)) return; if (!UsingImplicitWeakDescriptor(descriptor_->file(), options_)) return;
p->Emit(R"cc( p->Emit({{"pin", StrongReferenceToType(descriptor_, options_)}},
::_pbi::StrongPointer(&_$classname$_default_instance_); R"cc(
)cc"); $pin$;
)cc");
// For CODE_SIZE types, we need to pin the submessages too. // For CODE_SIZE types, we need to pin the submessages too.
// SPEED types will pin them via the TcParse table automatically. // SPEED types will pin them via the TcParse table automatically.
@ -3597,11 +3601,11 @@ void MessageGenerator::GenerateClassData(io::Printer* p) {
for (int i = 0; i < descriptor_->field_count(); ++i) { for (int i = 0; i < descriptor_->field_count(); ++i) {
auto* field = descriptor_->field(i); auto* field = descriptor_->field(i);
if (field->type() != field->TYPE_MESSAGE) continue; if (field->type() != field->TYPE_MESSAGE) continue;
p->Emit({{"sub_default_name", QualifiedDefaultInstanceName( p->Emit(
field->message_type(), options_)}}, {{"pin", StrongReferenceToType(field->message_type(), options_)}},
R"cc( R"cc(
::_pbi::StrongPointer(&$sub_default_name$); $pin$;
)cc"); )cc");
} }
}; };
p->Emit( p->Emit(

@ -275,6 +275,10 @@ class PROTOC_EXPORT JavaFeatures final : public ::google::protobuf::Message
1, 2, 1, 1, 2, 1,
0, 2> 0, 2>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_JavaFeatures_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>

@ -302,6 +302,10 @@ class PROTOC_EXPORT Version final : public ::google::protobuf::Message
2, 4, 0, 2, 4, 0,
47, 2> 47, 2>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_Version_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>
@ -531,6 +535,10 @@ class PROTOC_EXPORT CodeGeneratorResponse_File final : public ::google::protobuf
2, 4, 1, 2, 4, 1,
86, 2> 86, 2>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_CodeGeneratorResponse_File_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>
@ -783,6 +791,10 @@ class PROTOC_EXPORT CodeGeneratorResponse final : public ::google::protobuf::Mes
3, 5, 1, 3, 5, 1,
60, 2> 60, 2>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_CodeGeneratorResponse_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>
@ -1042,6 +1054,10 @@ class PROTOC_EXPORT CodeGeneratorRequest final : public ::google::protobuf::Mess
3, 5, 3, 3, 5, 3,
79, 2> 79, 2>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_CodeGeneratorRequest_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>

@ -277,6 +277,10 @@ class PROTOBUF_EXPORT CppFeatures final : public ::google::protobuf::Message
1, 2, 1, 1, 2, 1,
0, 2> 0, 2>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_CppFeatures_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>

@ -860,6 +860,10 @@ class PROTOBUF_EXPORT UninterpretedOption_NamePart final : public ::google::prot
1, 2, 0, 1, 2, 0,
62, 2> 62, 2>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_UninterpretedOption_NamePart_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>
@ -1120,6 +1124,10 @@ class PROTOBUF_EXPORT SourceCodeInfo_Location final : public ::google::protobuf:
3, 5, 0, 3, 5, 0,
106, 2> 106, 2>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_SourceCodeInfo_Location_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>
@ -1375,6 +1383,10 @@ class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation final : public ::google::prot
3, 5, 1, 3, 5, 1,
64, 2> 64, 2>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_GeneratedCodeInfo_Annotation_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>
@ -1566,6 +1578,10 @@ class PROTOBUF_EXPORT FieldOptions_EditionDefault final : public ::google::proto
1, 2, 1, 1, 2, 1,
57, 2> 57, 2>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_FieldOptions_EditionDefault_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>
@ -2095,6 +2111,10 @@ class PROTOBUF_EXPORT FeatureSet final : public ::google::protobuf::Message
3, 6, 6, 3, 6, 6,
0, 2> 0, 2>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_FeatureSet_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>
@ -2329,6 +2349,10 @@ class PROTOBUF_EXPORT ExtensionRangeOptions_Declaration final : public ::google:
3, 5, 0, 3, 5, 0,
71, 2> 71, 2>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_ExtensionRangeOptions_Declaration_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>
@ -2513,6 +2537,10 @@ class PROTOBUF_EXPORT EnumDescriptorProto_EnumReservedRange final : public ::goo
1, 2, 0, 1, 2, 0,
0, 2> 0, 2>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_EnumDescriptorProto_EnumReservedRange_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>
@ -2694,6 +2722,10 @@ class PROTOBUF_EXPORT DescriptorProto_ReservedRange final : public ::google::pro
1, 2, 0, 1, 2, 0,
0, 2> 0, 2>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_DescriptorProto_ReservedRange_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>
@ -2960,6 +2992,10 @@ class PROTOBUF_EXPORT UninterpretedOption final : public ::google::protobuf::Mes
3, 7, 1, 3, 7, 1,
75, 2> 75, 2>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_UninterpretedOption_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>
@ -3141,6 +3177,10 @@ class PROTOBUF_EXPORT SourceCodeInfo final : public ::google::protobuf::Message
0, 1, 1, 0, 1, 1,
0, 2> 0, 2>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_SourceCodeInfo_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>
@ -3315,6 +3355,10 @@ class PROTOBUF_EXPORT GeneratedCodeInfo final : public ::google::protobuf::Messa
0, 1, 1, 0, 1, 1,
0, 2> 0, 2>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_GeneratedCodeInfo_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>
@ -3498,6 +3542,10 @@ class PROTOBUF_EXPORT FeatureSetDefaults_FeatureSetEditionDefault final : public
1, 2, 2, 1, 2, 2,
0, 2> 0, 2>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_FeatureSetDefaults_FeatureSetEditionDefault_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>
@ -3880,6 +3928,10 @@ class PROTOBUF_EXPORT ServiceOptions final : public ::google::protobuf::Message
2, 3, 2, 2, 3, 2,
0, 12> 0, 12>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_ServiceOptions_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>
@ -4252,6 +4304,10 @@ class PROTOBUF_EXPORT OneofOptions final : public ::google::protobuf::Message
2, 2, 2, 2, 2, 2,
0, 7> 0, 7>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_OneofOptions_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>
@ -4667,6 +4723,10 @@ class PROTOBUF_EXPORT MethodOptions final : public ::google::protobuf::Message
3, 4, 3, 3, 4, 3,
0, 12> 0, 12>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_MethodOptions_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>
@ -5100,6 +5160,10 @@ class PROTOBUF_EXPORT MessageOptions final : public ::google::protobuf::Message
3, 7, 2, 3, 7, 2,
0, 7> 0, 7>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_MessageOptions_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>
@ -5784,6 +5848,10 @@ class PROTOBUF_EXPORT FileOptions final : public ::google::protobuf::Message
5, 21, 3, 5, 21, 3,
202, 12> 202, 12>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_FileOptions_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>
@ -6408,6 +6476,10 @@ class PROTOBUF_EXPORT FieldOptions final : public ::google::protobuf::Message
4, 13, 7, 4, 13, 7,
0, 7> 0, 7>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_FieldOptions_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>
@ -6620,6 +6692,10 @@ class PROTOBUF_EXPORT FeatureSetDefaults final : public ::google::protobuf::Mess
1, 3, 3, 1, 3, 3,
0, 2> 0, 2>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_FeatureSetDefaults_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>
@ -7041,6 +7117,10 @@ class PROTOBUF_EXPORT ExtensionRangeOptions final : public ::google::protobuf::M
3, 4, 4, 3, 4, 4,
0, 12> 0, 12>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_ExtensionRangeOptions_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>
@ -7438,6 +7518,10 @@ class PROTOBUF_EXPORT EnumValueOptions final : public ::google::protobuf::Messag
3, 4, 2, 3, 4, 2,
0, 7> 0, 7>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_EnumValueOptions_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>
@ -7847,6 +7931,10 @@ class PROTOBUF_EXPORT EnumOptions final : public ::google::protobuf::Message
3, 5, 2, 3, 5, 2,
0, 7> 0, 7>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_EnumOptions_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>
@ -8042,6 +8130,10 @@ class PROTOBUF_EXPORT OneofDescriptorProto final : public ::google::protobuf::Me
1, 2, 1, 1, 2, 1,
49, 2> 49, 2>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_OneofDescriptorProto_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>
@ -8293,6 +8385,10 @@ class PROTOBUF_EXPORT MethodDescriptorProto final : public ::google::protobuf::M
3, 6, 1, 3, 6, 1,
71, 2> 71, 2>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_MethodDescriptorProto_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>
@ -8675,6 +8771,10 @@ class PROTOBUF_EXPORT FieldDescriptorProto final : public ::google::protobuf::Me
4, 11, 3, 4, 11, 3,
96, 2> 96, 2>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_FieldDescriptorProto_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>
@ -8887,6 +8987,10 @@ class PROTOBUF_EXPORT EnumValueDescriptorProto final : public ::google::protobuf
2, 3, 1, 2, 3, 1,
53, 2> 53, 2>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_EnumValueDescriptorProto_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>
@ -9085,6 +9189,10 @@ class PROTOBUF_EXPORT DescriptorProto_ExtensionRange final : public ::google::pr
2, 3, 1, 2, 3, 1,
0, 2> 0, 2>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_DescriptorProto_ExtensionRange_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>
@ -9295,6 +9403,10 @@ class PROTOBUF_EXPORT ServiceDescriptorProto final : public ::google::protobuf::
2, 3, 2, 2, 3, 2,
51, 2> 51, 2>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_ServiceDescriptorProto_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>
@ -9553,6 +9665,10 @@ class PROTOBUF_EXPORT EnumDescriptorProto final : public ::google::protobuf::Mes
3, 5, 3, 3, 5, 3,
61, 2> 61, 2>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_EnumDescriptorProto_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>
@ -9904,6 +10020,10 @@ class PROTOBUF_EXPORT DescriptorProto final : public ::google::protobuf::Message
4, 10, 8, 4, 10, 8,
65, 2> 65, 2>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_DescriptorProto_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>
@ -10306,6 +10426,10 @@ class PROTOBUF_EXPORT FileDescriptorProto final : public ::google::protobuf::Mes
4, 13, 7, 4, 13, 7,
79, 2> 79, 2>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_FileDescriptorProto_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>
@ -10492,6 +10616,10 @@ class PROTOBUF_EXPORT FileDescriptorSet final : public ::google::protobuf::Messa
0, 1, 1, 0, 1, 1,
0, 2> 0, 2>
_table_; _table_;
static constexpr const void* _raw_default_instance_ =
&_FileDescriptorSet_default_instance_;
friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::MessageLite;
friend class ::google::protobuf::Arena; friend class ::google::protobuf::Arena;
template <typename T> template <typename T>

@ -69,7 +69,8 @@ extern const char __start_pb_defaults;
extern const char __stop_pb_defaults; extern const char __stop_pb_defaults;
} }
static void InitWeakDefaults() { static void InitWeakDefaults() {
StrongPointer(&dummy_weak_default); // force link the dummy entry. // force link the dummy entry.
StrongPointer<DummyWeakDefault*, &dummy_weak_default>();
// We don't know the size of each object, but we know the layout of the tail. // We don't know the size of each object, but we know the layout of the tail.
// It contains a WeakDescriptorDefaultTail object. // It contains a WeakDescriptorDefaultTail object.
// As such, we iterate the section backwards. // As such, we iterate the section backwards.

@ -1412,7 +1412,7 @@ const T* DynamicCastToGenerated(const Message* from) {
(void)unused; (void)unused;
#if PROTOBUF_RTTI #if PROTOBUF_RTTI
internal::StrongReference(T::default_instance()); internal::StrongReferenceToType<T>();
return dynamic_cast<const T*>(from); return dynamic_cast<const T*>(from);
#else #else
bool ok = from != nullptr && bool ok = from != nullptr &&
@ -1451,7 +1451,7 @@ T& DynamicCastToGenerated(Message& from) {
// instance T and T is a type derived from base Message class. // instance T and T is a type derived from base Message class.
template <typename T> template <typename T>
const T* DownCastToGenerated(const Message* from) { const T* DownCastToGenerated(const Message* from) {
internal::StrongReference(T::default_instance()); internal::StrongReferenceToType<T>();
ABSL_DCHECK(DynamicCastToGenerated<T>(from) == from) ABSL_DCHECK(DynamicCastToGenerated<T>(from) == from)
<< "Cannot downcast " << from->GetTypeName() << " to " << "Cannot downcast " << from->GetTypeName() << " to "
<< T::default_instance().GetTypeName(); << T::default_instance().GetTypeName();
@ -1499,7 +1499,7 @@ T& DownCastToGenerated(Message& from) {
// of loops (on x86-64 it compiles into two "mov" instructions). // of loops (on x86-64 it compiles into two "mov" instructions).
template <typename T> template <typename T>
void LinkMessageReflection() { void LinkMessageReflection() {
internal::StrongReference(T::default_instance); internal::StrongReferenceToType<T>();
} }
// ============================================================================= // =============================================================================

@ -674,6 +674,26 @@ class PROTOBUF_EXPORT MessageLite {
void LogInitializationErrorMessage() const; void LogInitializationErrorMessage() const;
bool MergeFromImpl(io::CodedInputStream* input, ParseFlags parse_flags); bool MergeFromImpl(io::CodedInputStream* input, ParseFlags parse_flags);
template <typename T, const void* ptr = T::_raw_default_instance_>
static constexpr auto GetStrongPointerForTypeImpl(int) {
return ptr;
}
template <typename T>
static constexpr auto GetStrongPointerForTypeImpl(char) {
return &T::default_instance;
}
// Return a pointer we can use to make a strong reference to a type.
// Ideally, this is a pointer to the default instance.
// If we can't get that, then we use a pointer to the `default_instance`
// function. The latter always works but pins the function artificially into
// the binary so we avoid it.
template <typename T>
static constexpr auto GetStrongPointerForType() {
return GetStrongPointerForTypeImpl<T>(0);
}
template <typename T>
friend void internal::StrongReferenceToType();
}; };
namespace internal { namespace internal {

@ -39,7 +39,7 @@ class MessageLite;
namespace internal { namespace internal {
template <typename T> template <typename T>
void StrongPointer(T* var) { inline PROTOBUF_ALWAYS_INLINE void StrongPointer(T* var) {
#if defined(__GNUC__) #if defined(__GNUC__)
asm("" : : "r"(var)); asm("" : : "r"(var));
#else #else
@ -48,6 +48,32 @@ void StrongPointer(T* var) {
#endif #endif
} }
// Similar to the overload above, but optimized for constant inputs.
template <typename T, T ptr>
inline PROTOBUF_ALWAYS_INLINE void StrongPointer() {
#if defined(__x86_64__) && defined(__linux__) && !defined(__APPLE__) && \
defined(__clang__) && __clang_major__ >= 19 && \
!defined(PROTOBUF_INTERNAL_TEMPORARY_STRONG_POINTER_OPT_OUT)
// This injects a relocation in the code path without having to run code, but
// we can only do it with a newer clang.
asm(".reloc ., BFD_RELOC_NONE, %p0" ::"Ws"(ptr));
#else
StrongPointer(ptr);
#endif
}
template <typename T>
inline PROTOBUF_ALWAYS_INLINE void StrongReferenceToType() {
constexpr auto ptr = T::template GetStrongPointerForType<T>();
#if defined(__cpp_nontype_template_args) && \
__cpp_nontype_template_args >= 201411L
// We can only use `ptr` as a template parameter since C++17
return StrongPointer<decltype(ptr), ptr>();
#else
return StrongPointer(ptr);
#endif
}
// See comments on `AllocateAtLeast` for information on size returning new. // See comments on `AllocateAtLeast` for information on size returning new.
struct SizedPtr { struct SizedPtr {

Loading…
Cancel
Save