/src/LPM/external.protobuf/include/google/protobuf/arena_cleanup.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Protocol Buffers - Google's data interchange format |
2 | | // Copyright 2008 Google Inc. All rights reserved. |
3 | | // |
4 | | // Use of this source code is governed by a BSD-style |
5 | | // license that can be found in the LICENSE file or at |
6 | | // https://developers.google.com/open-source/licenses/bsd |
7 | | |
8 | | #ifndef GOOGLE_PROTOBUF_ARENA_CLEANUP_H__ |
9 | | #define GOOGLE_PROTOBUF_ARENA_CLEANUP_H__ |
10 | | |
11 | | #include <cstddef> |
12 | | #include <cstring> |
13 | | #include <vector> |
14 | | |
15 | | #include "absl/base/attributes.h" |
16 | | #include "absl/base/prefetch.h" |
17 | | |
18 | | // Must be included last. |
19 | | #include "google/protobuf/port_def.inc" |
20 | | |
21 | | namespace google { |
22 | | namespace protobuf { |
23 | | namespace internal { |
24 | | |
25 | | class SerialArena; |
26 | | |
27 | | namespace cleanup { |
28 | | |
29 | | // Helper function invoking the destructor of `object` |
30 | | template <typename T> |
31 | 0 | void arena_destruct_object(void* object) { |
32 | 0 | reinterpret_cast<T*>(object)->~T(); |
33 | 0 | } Unexecuted instantiation: void google::protobuf::internal::cleanup::arena_destruct_object<google::protobuf::internal::InternalMetadata::Container<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >(void*) Unexecuted instantiation: void google::protobuf::internal::cleanup::arena_destruct_object<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(void*) |
34 | | |
35 | | // CleanupNode contains the object (`elem`) that needs to be |
36 | | // destroyed, and the function to destroy it (`destructor`) |
37 | | // elem must be aligned at minimum on a 4 byte boundary. |
38 | | struct CleanupNode { |
39 | | // Optimization: performs a prefetch on the elem for the cleanup node. We |
40 | | // explicitly use NTA prefetch here to avoid polluting remote caches: we are |
41 | | // destroying these instances, there is no purpose for these cache lines to |
42 | | // linger around in remote caches. |
43 | 0 | ABSL_ATTRIBUTE_ALWAYS_INLINE void Prefetch() { |
44 | 0 | // TODO: we should also prefetch the destructor code once |
45 | 0 | // processors support code prefetching. |
46 | 0 | absl::PrefetchToLocalCacheNta(elem); |
47 | 0 | } |
48 | | |
49 | | // Destroys the object referenced by the cleanup node. |
50 | 0 | ABSL_ATTRIBUTE_ALWAYS_INLINE void Destroy() { destructor(elem); } |
51 | | |
52 | | void* elem; |
53 | | void (*destructor)(void*); |
54 | | }; |
55 | | |
56 | | // Manages the list of cleanup nodes in a chunked linked list. Chunks grow by |
57 | | // factors of two up to a limit. Trivially destructible, but Cleanup() must be |
58 | | // called before destruction. |
59 | | class ChunkList { |
60 | | public: |
61 | | PROTOBUF_ALWAYS_INLINE void Add(void* elem, void (*destructor)(void*), |
62 | 0 | SerialArena& arena) { |
63 | 0 | if (PROTOBUF_PREDICT_TRUE(next_ < limit_)) { |
64 | 0 | AddFromExisting(elem, destructor); |
65 | 0 | return; |
66 | 0 | } |
67 | 0 | AddFallback(elem, destructor, arena); |
68 | 0 | } |
69 | | |
70 | | // Runs all inserted cleanups and frees allocated chunks. Must be called |
71 | | // before destruction. |
72 | | void Cleanup(const SerialArena& arena); |
73 | | |
74 | | private: |
75 | | struct Chunk; |
76 | | friend class internal::SerialArena; |
77 | | |
78 | | void AddFallback(void* elem, void (*destructor)(void*), SerialArena& arena); |
79 | | ABSL_ATTRIBUTE_ALWAYS_INLINE void AddFromExisting(void* elem, |
80 | 0 | void (*destructor)(void*)) { |
81 | 0 | *next_++ = CleanupNode{elem, destructor}; |
82 | 0 | } |
83 | | |
84 | | // Returns the pointers to the to-be-cleaned objects. |
85 | | std::vector<void*> PeekForTesting(); |
86 | | |
87 | | Chunk* head_ = nullptr; |
88 | | CleanupNode* next_ = nullptr; |
89 | | CleanupNode* limit_ = nullptr; |
90 | | // Current prefetch position. Data from `next_` up to but not including |
91 | | // `prefetch_ptr_` is software prefetched. Used in SerialArena prefetching. |
92 | | const char* prefetch_ptr_ = nullptr; |
93 | | }; |
94 | | |
95 | | } // namespace cleanup |
96 | | } // namespace internal |
97 | | } // namespace protobuf |
98 | | } // namespace google |
99 | | |
100 | | #include "google/protobuf/port_undef.inc" |
101 | | |
102 | | #endif // GOOGLE_PROTOBUF_ARENA_CLEANUP_H__ |