File indexing completed on 2025-01-31 10:12:06
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef GOOGLE_PROTOBUF_ARENA_CLEANUP_H__
0009 #define GOOGLE_PROTOBUF_ARENA_CLEANUP_H__
0010
0011 #include <cstddef>
0012 #include <cstring>
0013 #include <vector>
0014
0015 #include "absl/base/attributes.h"
0016 #include "absl/base/prefetch.h"
0017
0018
0019 #include "google/protobuf/port_def.inc"
0020
0021 namespace google {
0022 namespace protobuf {
0023 namespace internal {
0024
0025 class SerialArena;
0026
0027 namespace cleanup {
0028
0029
0030 template <typename T>
0031 void arena_destruct_object(void* object) {
0032 reinterpret_cast<T*>(object)->~T();
0033 }
0034
0035
0036
0037
0038 struct CleanupNode {
0039
0040
0041
0042
0043 ABSL_ATTRIBUTE_ALWAYS_INLINE void Prefetch() {
0044
0045
0046 absl::PrefetchToLocalCacheNta(elem);
0047 }
0048
0049
0050 ABSL_ATTRIBUTE_ALWAYS_INLINE void Destroy() { destructor(elem); }
0051
0052 void* elem;
0053 void (*destructor)(void*);
0054 };
0055
0056
0057
0058
0059 class ChunkList {
0060 public:
0061 PROTOBUF_ALWAYS_INLINE void Add(void* elem, void (*destructor)(void*),
0062 SerialArena& arena) {
0063 if (PROTOBUF_PREDICT_TRUE(next_ < limit_)) {
0064 AddFromExisting(elem, destructor);
0065 return;
0066 }
0067 AddFallback(elem, destructor, arena);
0068 }
0069
0070
0071
0072 void Cleanup(const SerialArena& arena);
0073
0074 private:
0075 struct Chunk;
0076 friend class internal::SerialArena;
0077
0078 void AddFallback(void* elem, void (*destructor)(void*), SerialArena& arena);
0079 ABSL_ATTRIBUTE_ALWAYS_INLINE void AddFromExisting(void* elem,
0080 void (*destructor)(void*)) {
0081 *next_++ = CleanupNode{elem, destructor};
0082 }
0083
0084
0085 std::vector<void*> PeekForTesting();
0086
0087 Chunk* head_ = nullptr;
0088 CleanupNode* next_ = nullptr;
0089 CleanupNode* limit_ = nullptr;
0090
0091
0092 const char* prefetch_ptr_ = nullptr;
0093 };
0094
0095 }
0096 }
0097 }
0098 }
0099
0100 #include "google/protobuf/port_undef.inc"
0101
0102 #endif