| 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 |