// Protocol Buffers - Google's data interchange format // Copyright 2008 Google Inc. All rights reserved. // https://developers.google.com/protocol-buffers/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // This file defines an Arena allocator for better allocation performance. #ifndef GOOGLE_PROTOBUF_ARENA_H__ #define GOOGLE_PROTOBUF_ARENA_H__ #include <limits> #include <type_traits> #include <utility> #if defined(_MSC_VER) && !defined(_LIBCPP_STD_VER) && !_HAS_EXCEPTIONS // Work around bugs in MSVC <typeinfo> header when _HAS_EXCEPTIONS=0. #include <exception> #include <typeinfo> namespace std { using type_info = ::type_info; } #else #include <typeinfo> #endif #include <type_traits> #include <google/protobuf/arena_impl.h> #include <google/protobuf/port.h> // Must be included last. #include <google/protobuf/port_def.inc> #ifdef SWIG #error "You cannot SWIG proto headers" #endif namespace google { namespace protobuf { struct ArenaOptions; // defined below class Arena; // defined below class Message; // defined in message.h class MessageLite; template <typename Key, typename T> class Map; namespace arena_metrics { void EnableArenaMetrics(ArenaOptions* options); } // namespace arena_metrics namespace TestUtil { class ReflectionTester; // defined in test_util.h } // namespace TestUtil namespace internal { struct ArenaTestPeer; // defined in arena_test_util.h class InternalMetadata; // defined in metadata_lite.h class LazyField; // defined in lazy_field.h class EpsCopyInputStream; // defined in parse_context.h class RepeatedPtrFieldBase; // defined in repeated_ptr_field.h template <typename Type> class GenericTypeHandler; // defined in repeated_field.h inline PROTOBUF_ALWAYS_INLINE void* AlignTo(void* ptr, size_t align) { … } // Templated cleanup methods. template <typename T> void arena_destruct_object(void* object) { … } template <bool destructor_skippable, typename T> struct ObjectDestructor { … }; ObjectDestructor<true, T>; template <typename T> void arena_delete_object(void* object) { … } } // namespace internal // ArenaOptions provides optional additional parameters to arena construction // that control its block-allocation behavior. struct ArenaOptions { … }; // Support for non-RTTI environments. (The metrics hooks API uses type // information.) #if PROTOBUF_RTTI #define RTTI_TYPE_ID … #else #define RTTI_TYPE_ID … #endif // Arena allocator. Arena allocation replaces ordinary (heap-based) allocation // with new/delete, and improves performance by aggregating allocations into // larger blocks and freeing allocations all at once. Protocol messages are // allocated on an arena by using Arena::CreateMessage<T>(Arena*), below, and // are automatically freed when the arena is destroyed. // // This is a thread-safe implementation: multiple threads may allocate from the // arena concurrently. Destruction is not thread-safe and the destructing // thread must synchronize with users of the arena first. // // An arena provides two allocation interfaces: CreateMessage<T>, which works // for arena-enabled proto2 message types as well as other types that satisfy // the appropriate protocol (described below), and Create<T>, which works for // any arbitrary type T. CreateMessage<T> is better when the type T supports it, // because this interface (i) passes the arena pointer to the created object so // that its sub-objects and internal allocations can use the arena too, and (ii) // elides the object's destructor call when possible. Create<T> does not place // any special requirements on the type T, and will invoke the object's // destructor when the arena is destroyed. // // The arena message allocation protocol, required by // CreateMessage<T>(Arena* arena, Args&&... args), is as follows: // // - The type T must have (at least) two constructors: a constructor callable // with `args` (without `arena`), called when a T is allocated on the heap; // and a constructor callable with `Arena* arena, Args&&... args`, called when // a T is allocated on an arena. If the second constructor is called with a // NULL arena pointer, it must be equivalent to invoking the first // (`args`-only) constructor. // // - The type T must have a particular type trait: a nested type // |InternalArenaConstructable_|. This is usually a typedef to |void|. If no // such type trait exists, then the instantiation CreateMessage<T> will fail // to compile. // // - The type T *may* have the type trait |DestructorSkippable_|. If this type // trait is present in the type, then its destructor will not be called if and // only if it was passed a non-NULL arena pointer. If this type trait is not // present on the type, then its destructor is always called when the // containing arena is destroyed. // // This protocol is implemented by all arena-enabled proto2 message classes as // well as protobuf container types like RepeatedPtrField and Map. The protocol // is internal to protobuf and is not guaranteed to be stable. Non-proto types // should not rely on this protocol. class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { … }; // Defined above for supporting environments without RTTI. #undef RTTI_TYPE_ID } // namespace protobuf } // namespace google #include <google/protobuf/port_undef.inc> #endif // GOOGLE_PROTOBUF_ARENA_H__