Skip to content

Commit a15c9c5

Browse files
protobuf-github-botzhangskz
authored andcommitted
Refactor the way we turn on the optimization in StrongPointer.
Some versions of gcc seem to advertise __cpp_nontype_template_args but not support the argument in some cases. Only attempt the template parameter if we are using the optimized .reloc approach. Fixes #16868 PiperOrigin-RevId: 634787159
1 parent 11307ca commit a15c9c5

File tree

1 file changed

+18
-14
lines changed

1 file changed

+18
-14
lines changed

src/google/protobuf/port.h

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -49,31 +49,35 @@ inline PROTOBUF_ALWAYS_INLINE void StrongPointer(T* var) {
4949
#endif
5050
}
5151

52-
// Similar to the overload above, but optimized for constant inputs.
52+
#if defined(__x86_64__) && defined(__linux__) && !defined(__APPLE__) && \
53+
!defined(__ANDROID__) && defined(__clang__) && __clang_major__ >= 19
54+
// Optimized implementation for clang where we can generate a relocation without
55+
// adding runtime instructions.
5356
template <typename T, T ptr>
5457
inline PROTOBUF_ALWAYS_INLINE void StrongPointer() {
55-
#if defined(__x86_64__) && defined(__linux__) && !defined(__APPLE__) && \
56-
!defined(__ANDROID__) && defined(__clang__) && __clang_major__ >= 19 && \
57-
!defined(PROTOBUF_INTERNAL_TEMPORARY_STRONG_POINTER_OPT_OUT)
5858
// This injects a relocation in the code path without having to run code, but
5959
// we can only do it with a newer clang.
6060
asm(".reloc ., BFD_RELOC_NONE, %p0" ::"Ws"(ptr));
61-
#else
62-
StrongPointer(ptr);
63-
#endif
6461
}
6562

6663
template <typename T>
6764
inline PROTOBUF_ALWAYS_INLINE void StrongReferenceToType() {
68-
constexpr auto ptr = T::template GetStrongPointerForType<T>();
69-
#if defined(__cpp_nontype_template_args) && \
70-
__cpp_nontype_template_args >= 201411L
71-
// We can only use `ptr` as a template parameter since C++17
65+
static constexpr auto ptr = T::template GetStrongPointerForType<T>();
7266
return StrongPointer<decltype(ptr), ptr>();
73-
#else
74-
return StrongPointer(ptr);
75-
#endif
7667
}
68+
#else // .reloc
69+
// Portable fallback. It usually generates a single LEA instruction or
70+
// equivalent.
71+
template <typename T, T ptr>
72+
inline PROTOBUF_ALWAYS_INLINE void StrongPointer() {
73+
StrongPointer(ptr);
74+
}
75+
76+
template <typename T>
77+
inline PROTOBUF_ALWAYS_INLINE void StrongReferenceToType() {
78+
return StrongPointer(T::template GetStrongPointerForType<T>());
79+
}
80+
#endif // .reloc
7781

7882

7983
// See comments on `AllocateAtLeast` for information on size returning new.

0 commit comments

Comments
 (0)