Use virtual destructor for Protobuf Messages.
PiperOrigin-RevId: 560717708
diff --git a/src/google/protobuf/repeated_ptr_field.cc b/src/google/protobuf/repeated_ptr_field.cc
index e51c1a1..36dac0e 100644
--- a/src/google/protobuf/repeated_ptr_field.cc
+++ b/src/google/protobuf/repeated_ptr_field.cc
@@ -185,6 +185,10 @@
return result;
}
+void InternalOutOfLineDeleteMessageLite(MessageLite* message) {
+ delete message;
+}
+
} // namespace internal
} // namespace protobuf
diff --git a/src/google/protobuf/repeated_ptr_field.h b/src/google/protobuf/repeated_ptr_field.h
index 5b5d770..9839852 100644
--- a/src/google/protobuf/repeated_ptr_field.h
+++ b/src/google/protobuf/repeated_ptr_field.h
@@ -843,6 +843,8 @@
void* tagged_rep_or_elem_;
};
+void InternalOutOfLineDeleteMessageLite(MessageLite* message);
+
template <typename GenericType>
class GenericTypeHandler {
public:
@@ -860,9 +862,18 @@
return New(arena);
}
static inline void Delete(GenericType* value, Arena* arena) {
- if (arena == nullptr) {
+ if (arena != nullptr) return;
+#ifdef __cpp_if_constexpr
+ if constexpr (std::is_base_of<MessageLite, GenericType>::value) {
+ // Using virtual destructor to reduce generated code size that would have
+ // happened otherwise due to inlined `~GenericType`.
+ InternalOutOfLineDeleteMessageLite(value);
+ } else {
delete value;
}
+#else
+ delete value;
+#endif
}
static inline Arena* GetOwningArena(GenericType* value) {
return Arena::InternalGetOwningArena(value);