Change AllocateInternal to allow us to easy specialize for std::string or absl::Cord
PiperOrigin-RevId: 504441955
diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h
index 010b758..5c553cb 100644
--- a/src/google/protobuf/arena.h
+++ b/src/google/protobuf/arena.h
@@ -274,11 +274,7 @@
if (PROTOBUF_PREDICT_FALSE(arena == nullptr)) {
return new T(std::forward<Args>(args)...);
}
- auto destructor =
- internal::ObjectDestructor<std::is_trivially_destructible<T>::value,
- T>::destructor;
- return new (arena->AllocateInternal(sizeof(T), alignof(T), destructor))
- T(std::forward<Args>(args)...);
+ return new (arena->AllocateInternal<T>()) T(std::forward<Args>(args)...);
}
// API to delete any objects not on an arena. This can be used to safely
@@ -565,13 +561,13 @@
}
}
- 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 <typename T, bool trivial = std::is_trivially_destructible<T>::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<T>;
+ return AllocateAlignedWithCleanup(sizeof(T), alignof(T), dtor);
}
}
@@ -604,11 +600,8 @@
template <typename T, typename... Args>
PROTOBUF_NDEBUG_INLINE T* DoCreateMessage(Args&&... args) {
return InternalHelper<T>::Construct(
- AllocateInternal(sizeof(T), alignof(T),
- internal::ObjectDestructor<
- InternalHelper<T>::is_destructor_skippable::value,
- T>::destructor),
- this, std::forward<Args>(args)...);
+ AllocateInternal<T, is_destructor_skippable<T>::value>(), this,
+ std::forward<Args>(args)...);
}
// CreateInArenaStorage is used to implement map field. Without it,