OLD | NEW |
1 // Protocol Buffers - Google's data interchange format | 1 // Protocol Buffers - Google's data interchange format |
2 // Copyright 2008 Google Inc. All rights reserved. | 2 // Copyright 2008 Google Inc. All rights reserved. |
3 // https://developers.google.com/protocol-buffers/ | 3 // https://developers.google.com/protocol-buffers/ |
4 // | 4 // |
5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
7 // met: | 7 // met: |
8 // | 8 // |
9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
(...skipping 10 matching lines...) Expand all Loading... |
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
30 | 30 |
31 // This file defines an Arena allocator for better allocation performance. | |
32 | |
33 #ifndef GOOGLE_PROTOBUF_ARENA_H__ | 31 #ifndef GOOGLE_PROTOBUF_ARENA_H__ |
34 #define GOOGLE_PROTOBUF_ARENA_H__ | 32 #define GOOGLE_PROTOBUF_ARENA_H__ |
35 | 33 |
36 #include <limits> | 34 #include <limits> |
37 #ifdef max | 35 #ifdef max |
38 #undef max // Visual Studio defines this macro | 36 #undef max // Visual Studio defines this macro |
39 #endif | 37 #endif |
40 #if __cplusplus >= 201103L | 38 #if __cplusplus >= 201103L |
41 #include <google/protobuf/stubs/type_traits.h> | 39 #include <google/protobuf/stubs/type_traits.h> |
42 #endif | 40 #endif |
(...skipping 29 matching lines...) Expand all Loading... |
72 template<typename Type> | 70 template<typename Type> |
73 class GenericTypeHandler; // repeated_field.h | 71 class GenericTypeHandler; // repeated_field.h |
74 | 72 |
75 // Templated cleanup methods. | 73 // Templated cleanup methods. |
76 template<typename T> void arena_destruct_object(void* object) { | 74 template<typename T> void arena_destruct_object(void* object) { |
77 reinterpret_cast<T*>(object)->~T(); | 75 reinterpret_cast<T*>(object)->~T(); |
78 } | 76 } |
79 template<typename T> void arena_delete_object(void* object) { | 77 template<typename T> void arena_delete_object(void* object) { |
80 delete reinterpret_cast<T*>(object); | 78 delete reinterpret_cast<T*>(object); |
81 } | 79 } |
82 inline void arena_free(void* object, size_t size) { | 80 inline void arena_free(void* object, size_t /* size */) { |
83 #if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation) | 81 free(object); |
84 ::operator delete(object, size); | |
85 #else | |
86 (void)size; | |
87 ::operator delete(object); | |
88 #endif | |
89 } | 82 } |
90 | 83 |
91 } // namespace internal | 84 } // namespace internal |
92 | 85 |
93 // ArenaOptions provides optional additional parameters to arena construction | 86 // ArenaOptions provides optional additional parameters to arena construction |
94 // that control its block-allocation behavior. | 87 // that control its block-allocation behavior. |
95 struct ArenaOptions { | 88 struct ArenaOptions { |
96 // This defines the size of the first block requested from the system malloc. | 89 // This defines the size of the first block requested from the system malloc. |
97 // Subsequent block sizes will increase in a geometric series up to a maximum. | 90 // Subsequent block sizes will increase in a geometric series up to a maximum. |
98 size_t start_block_size; | 91 size_t start_block_size; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 // intentionally want to avoid monitoring an allocation. (i.e. internal | 135 // intentionally want to avoid monitoring an allocation. (i.e. internal |
143 // allocations for managing the arena) | 136 // allocations for managing the arena) |
144 void (*on_arena_allocation)(const std::type_info* allocated_type, | 137 void (*on_arena_allocation)(const std::type_info* allocated_type, |
145 uint64 alloc_size, void* cookie); | 138 uint64 alloc_size, void* cookie); |
146 | 139 |
147 ArenaOptions() | 140 ArenaOptions() |
148 : start_block_size(kDefaultStartBlockSize), | 141 : start_block_size(kDefaultStartBlockSize), |
149 max_block_size(kDefaultMaxBlockSize), | 142 max_block_size(kDefaultMaxBlockSize), |
150 initial_block(NULL), | 143 initial_block(NULL), |
151 initial_block_size(0), | 144 initial_block_size(0), |
152 block_alloc(&::operator new), | 145 block_alloc(&malloc), |
153 block_dealloc(&internal::arena_free), | 146 block_dealloc(&internal::arena_free), |
154 on_arena_init(NULL), | 147 on_arena_init(NULL), |
155 on_arena_reset(NULL), | 148 on_arena_reset(NULL), |
156 on_arena_destruction(NULL), | 149 on_arena_destruction(NULL), |
157 on_arena_allocation(NULL) {} | 150 on_arena_allocation(NULL) {} |
158 | 151 |
159 private: | 152 private: |
160 // Constants define default starting block size and max block size for | 153 // Constants define default starting block size and max block size for |
161 // arena allocator behavior -- see descriptions above. | 154 // arena allocator behavior -- see descriptions above. |
162 static const size_t kDefaultStartBlockSize = 256; | 155 static const size_t kDefaultStartBlockSize = 256; |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 // present on the type, then its destructor is always called when the | 204 // present on the type, then its destructor is always called when the |
212 // containing arena is destroyed. | 205 // containing arena is destroyed. |
213 // | 206 // |
214 // - One- and two-user-argument forms of CreateMessage<T>() also exist that | 207 // - One- and two-user-argument forms of CreateMessage<T>() also exist that |
215 // forward these constructor arguments to T's constructor: for example, | 208 // forward these constructor arguments to T's constructor: for example, |
216 // CreateMessage<T>(Arena*, arg1, arg2) forwards to a constructor T(Arena*, | 209 // CreateMessage<T>(Arena*, arg1, arg2) forwards to a constructor T(Arena*, |
217 // arg1, arg2). | 210 // arg1, arg2). |
218 // | 211 // |
219 // This protocol is implemented by all arena-enabled proto2 message classes as | 212 // This protocol is implemented by all arena-enabled proto2 message classes as |
220 // well as RepeatedPtrField. | 213 // well as RepeatedPtrField. |
221 // | 214 |
222 // Do NOT subclass Arena. This class will be marked as final when C++11 is | 215 #if __cplusplus >= 201103L |
223 // enabled. | 216 class LIBPROTOBUF_EXPORT Arena final { |
| 217 #else |
224 class LIBPROTOBUF_EXPORT Arena { | 218 class LIBPROTOBUF_EXPORT Arena { |
| 219 #endif |
225 public: | 220 public: |
226 // Arena constructor taking custom options. See ArenaOptions below for | 221 // Arena constructor taking custom options. See ArenaOptions below for |
227 // descriptions of the options available. | 222 // descriptions of the options available. |
228 explicit Arena(const ArenaOptions& options) : options_(options) { | 223 explicit Arena(const ArenaOptions& options) : options_(options) { |
229 Init(); | 224 Init(); |
230 } | 225 } |
231 | 226 |
232 // Default constructor with sensible default options, tuned for average | 227 // Default constructor with sensible default options, tuned for average |
233 // use-cases. | 228 // use-cases. |
234 Arena() { | 229 Arena() { |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
452 // Returns the total space used by the arena, which is the sums of the sizes | 447 // Returns the total space used by the arena, which is the sums of the sizes |
453 // of the underlying blocks. The total space used may not include the new | 448 // of the underlying blocks. The total space used may not include the new |
454 // blocks that are allocated by this arena from other threads concurrently | 449 // blocks that are allocated by this arena from other threads concurrently |
455 // with the call to this method. | 450 // with the call to this method. |
456 GOOGLE_ATTRIBUTE_NOINLINE uint64 SpaceAllocated() const; | 451 GOOGLE_ATTRIBUTE_NOINLINE uint64 SpaceAllocated() const; |
457 // As above, but does not include any free space in underlying blocks. | 452 // As above, but does not include any free space in underlying blocks. |
458 GOOGLE_ATTRIBUTE_NOINLINE uint64 SpaceUsed() const; | 453 GOOGLE_ATTRIBUTE_NOINLINE uint64 SpaceUsed() const; |
459 | 454 |
460 // Combines SpaceAllocated and SpaceUsed. Returns a pair of | 455 // Combines SpaceAllocated and SpaceUsed. Returns a pair of |
461 // <space_allocated, space_used>. | 456 // <space_allocated, space_used>. |
462 GOOGLE_ATTRIBUTE_NOINLINE std::pair<uint64, uint64> SpaceAllocatedAndUsed() co
nst; | 457 GOOGLE_ATTRIBUTE_NOINLINE pair<uint64, uint64> SpaceAllocatedAndUsed() const; |
463 | 458 |
464 // Frees all storage allocated by this arena after calling destructors | 459 // Frees all storage allocated by this arena after calling destructors |
465 // registered with OwnDestructor() and freeing objects registered with Own(). | 460 // registered with OwnDestructor() and freeing objects registered with Own(). |
466 // Any objects allocated on this arena are unusable after this call. It also | 461 // Any objects allocated on this arena are unusable after this call. It also |
467 // returns the total space used by the arena which is the sums of the sizes | 462 // returns the total space used by the arena which is the sums of the sizes |
468 // of the allocated blocks. This method is not thread-safe. | 463 // of the allocated blocks. This method is not thread-safe. |
469 GOOGLE_ATTRIBUTE_NOINLINE uint64 Reset(); | 464 GOOGLE_ATTRIBUTE_NOINLINE uint64 Reset(); |
470 | 465 |
471 // Adds |object| to a list of heap-allocated objects to be freed with |delete| | 466 // Adds |object| to a list of heap-allocated objects to be freed with |delete| |
472 // when the arena is destroyed or reset. | 467 // when the arena is destroyed or reset. |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
606 // This is inside Arena because only Arena has the friend relationships | 601 // This is inside Arena because only Arena has the friend relationships |
607 // necessary to see the underlying generated code traits. | 602 // necessary to see the underlying generated code traits. |
608 template<typename T> | 603 template<typename T> |
609 struct is_destructor_skippable | 604 struct is_destructor_skippable |
610 : public google::protobuf::internal::integral_constant< | 605 : public google::protobuf::internal::integral_constant< |
611 bool, | 606 bool, |
612 sizeof(InternalIsDestructorSkippableHelper::DestructorSkippable< | 607 sizeof(InternalIsDestructorSkippableHelper::DestructorSkippable< |
613 const T>(static_cast<const T*>(0))) == sizeof(char) || | 608 const T>(static_cast<const T*>(0))) == sizeof(char) || |
614 google::protobuf::internal::has_trivial_destructor<T>::value> {}
; | 609 google::protobuf::internal::has_trivial_destructor<T>::value> {}
; |
615 | 610 |
616 private: | |
617 // CreateMessage<T> requires that T supports arenas, but this private method | 611 // CreateMessage<T> requires that T supports arenas, but this private method |
618 // works whether or not T supports arenas. These are not exposed to user code | 612 // works whether or not T supports arenas. These are not exposed to user code |
619 // as it can cause confusing API usages, and end up having double free in | 613 // as it can cause confusing API usages, and end up having double free in |
620 // user code. These are used only internally from LazyField and Repeated | 614 // user code. These are used only internally from LazyField and Repeated |
621 // fields, since they are designed to work in all mode combinations. | 615 // fields, since they are designed to work in all mode combinations. |
622 template<typename Msg> GOOGLE_ATTRIBUTE_ALWAYS_INLINE | 616 template<typename Msg> GOOGLE_ATTRIBUTE_ALWAYS_INLINE |
623 static Msg* CreateMaybeMessage( | 617 static Msg* CreateMaybeMessage( |
624 Arena* arena, typename Msg::InternalArenaConstructable_*) { | 618 Arena* arena, typename Msg::InternalArenaConstructable_*) { |
625 return CreateMessage<Msg>(arena); | 619 return CreateMessage<Msg>(arena); |
626 } | 620 } |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
800 } | 794 } |
801 | 795 |
802 template <typename T> | 796 template <typename T> |
803 static void CreateInArenaStorageInternal( | 797 static void CreateInArenaStorageInternal( |
804 T* ptr, Arena* arena, google::protobuf::internal::true_type) { | 798 T* ptr, Arena* arena, google::protobuf::internal::true_type) { |
805 new (ptr) T(arena); | 799 new (ptr) T(arena); |
806 } | 800 } |
807 template <typename T> | 801 template <typename T> |
808 static void CreateInArenaStorageInternal( | 802 static void CreateInArenaStorageInternal( |
809 T* ptr, Arena* arena, google::protobuf::internal::false_type) { | 803 T* ptr, Arena* arena, google::protobuf::internal::false_type) { |
810 new (ptr) T(); | 804 new (ptr) T; |
811 } | 805 } |
812 | 806 |
813 template <typename T> | 807 template <typename T> |
814 static void RegisterDestructorInternal( | 808 static void RegisterDestructorInternal( |
815 T* ptr, Arena* arena, google::protobuf::internal::true_type) {} | 809 T* ptr, Arena* arena, google::protobuf::internal::true_type) {} |
816 template <typename T> | 810 template <typename T> |
817 static void RegisterDestructorInternal( | 811 static void RegisterDestructorInternal( |
818 T* ptr, Arena* arena, google::protobuf::internal::false_type) { | 812 T* ptr, Arena* arena, google::protobuf::internal::false_type) { |
819 arena->OwnDestructor(ptr); | 813 arena->OwnDestructor(ptr); |
820 } | 814 } |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
922 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Arena); | 916 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Arena); |
923 }; | 917 }; |
924 | 918 |
925 // Defined above for supporting environments without RTTI. | 919 // Defined above for supporting environments without RTTI. |
926 #undef RTTI_TYPE_ID | 920 #undef RTTI_TYPE_ID |
927 | 921 |
928 } // namespace protobuf | 922 } // namespace protobuf |
929 | 923 |
930 } // namespace google | 924 } // namespace google |
931 #endif // GOOGLE_PROTOBUF_ARENA_H__ | 925 #endif // GOOGLE_PROTOBUF_ARENA_H__ |
OLD | NEW |