Skip to content

Commit

Permalink
Merge pull request #17295 from protocolbuffers/cp-strongpointer
Browse files Browse the repository at this point in the history
Refactor the way we turn on the optimization in StrongPointer.
  • Loading branch information
zhangskz authored Jul 1, 2024
2 parents 11307ca + a15c9c5 commit 2440498
Showing 1 changed file with 18 additions and 14 deletions.
32 changes: 18 additions & 14 deletions src/google/protobuf/port.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,31 +49,35 @@ inline PROTOBUF_ALWAYS_INLINE void StrongPointer(T* var) {
#endif
}

// Similar to the overload above, but optimized for constant inputs.
#if defined(__x86_64__) && defined(__linux__) && !defined(__APPLE__) && \
!defined(__ANDROID__) && defined(__clang__) && __clang_major__ >= 19
// Optimized implementation for clang where we can generate a relocation without
// adding runtime instructions.
template <typename T, T ptr>
inline PROTOBUF_ALWAYS_INLINE void StrongPointer() {
#if defined(__x86_64__) && defined(__linux__) && !defined(__APPLE__) && \
!defined(__ANDROID__) && 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
static constexpr auto ptr = T::template GetStrongPointerForType<T>();
return StrongPointer<decltype(ptr), ptr>();
#else
return StrongPointer(ptr);
#endif
}
#else // .reloc
// Portable fallback. It usually generates a single LEA instruction or
// equivalent.
template <typename T, T ptr>
inline PROTOBUF_ALWAYS_INLINE void StrongPointer() {
StrongPointer(ptr);
}

template <typename T>
inline PROTOBUF_ALWAYS_INLINE void StrongReferenceToType() {
return StrongPointer(T::template GetStrongPointerForType<T>());
}
#endif // .reloc


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

0 comments on commit 2440498

Please sign in to comment.