Change AllocateInternal to allow us to easy specialize for std::string or absl::Cord

PiperOrigin-RevId: 504441955
pull/11623/head
Martijn Vels 2 years ago committed by Copybara-Service
parent 9416dca8bf
commit 233aa47c7d
  1. 25
      src/google/protobuf/arena.h

@ -274,11 +274,7 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final {
if (PROTOBUF_PREDICT_FALSE(arena == nullptr)) { if (PROTOBUF_PREDICT_FALSE(arena == nullptr)) {
return new T(std::forward<Args>(args)...); return new T(std::forward<Args>(args)...);
} }
auto destructor = return new (arena->AllocateInternal<T>()) T(std::forward<Args>(args)...);
internal::ObjectDestructor<std::is_trivially_destructible<T>::value,
T>::destructor;
return new (arena->AllocateInternal(sizeof(T), alignof(T), destructor))
T(std::forward<Args>(args)...);
} }
// API to delete any objects not on an arena. This can be used to safely // API to delete any objects not on an arena. This can be used to safely
@ -565,13 +561,13 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final {
} }
} }
PROTOBUF_NDEBUG_INLINE void* AllocateInternal(size_t size, size_t align, template <typename T, bool trivial = std::is_trivially_destructible<T>::value>
void (*destructor)(void*)) { PROTOBUF_NDEBUG_INLINE void* AllocateInternal() {
// Monitor allocation if needed. if (trivial) {
if (destructor == nullptr) { return AllocateAligned(sizeof(T), alignof(T));
return AllocateAligned(size, align);
} else { } else {
return AllocateAlignedWithCleanup(size, align, destructor); constexpr auto dtor = &internal::cleanup::arena_destruct_object<T>;
return AllocateAlignedWithCleanup(sizeof(T), alignof(T), dtor);
} }
} }
@ -604,11 +600,8 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final {
template <typename T, typename... Args> template <typename T, typename... Args>
PROTOBUF_NDEBUG_INLINE T* DoCreateMessage(Args&&... args) { PROTOBUF_NDEBUG_INLINE T* DoCreateMessage(Args&&... args) {
return InternalHelper<T>::Construct( return InternalHelper<T>::Construct(
AllocateInternal(sizeof(T), alignof(T), AllocateInternal<T, is_destructor_skippable<T>::value>(), this,
internal::ObjectDestructor< std::forward<Args>(args)...);
InternalHelper<T>::is_destructor_skippable::value,
T>::destructor),
this, std::forward<Args>(args)...);
} }
// CreateInArenaStorage is used to implement map field. Without it, // CreateInArenaStorage is used to implement map field. Without it,

Loading…
Cancel
Save