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