diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h index 010b7582ef1e..5c553cb7370d 100644 --- a/src/google/protobuf/arena.h +++ b/src/google/protobuf/arena.h @@ -274,11 +274,7 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { if (PROTOBUF_PREDICT_FALSE(arena == nullptr)) { return new T(std::forward(args)...); } - auto destructor = - internal::ObjectDestructor::value, - T>::destructor; - return new (arena->AllocateInternal(sizeof(T), alignof(T), destructor)) - T(std::forward(args)...); + return new (arena->AllocateInternal()) T(std::forward(args)...); } // 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, - void (*destructor)(void*)) { - // Monitor allocation if needed. - if (destructor == nullptr) { - return AllocateAligned(size, align); + template ::value> + PROTOBUF_NDEBUG_INLINE void* AllocateInternal() { + if (trivial) { + return AllocateAligned(sizeof(T), alignof(T)); } else { - return AllocateAlignedWithCleanup(size, align, destructor); + constexpr auto dtor = &internal::cleanup::arena_destruct_object; + return AllocateAlignedWithCleanup(sizeof(T), alignof(T), dtor); } } @@ -604,11 +600,8 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { template PROTOBUF_NDEBUG_INLINE T* DoCreateMessage(Args&&... args) { return InternalHelper::Construct( - AllocateInternal(sizeof(T), alignof(T), - internal::ObjectDestructor< - InternalHelper::is_destructor_skippable::value, - T>::destructor), - this, std::forward(args)...); + AllocateInternal::value>(), this, + std::forward(args)...); } // CreateInArenaStorage is used to implement map field. Without it,