// 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>
#ifdef max
#undef max  // Visual Studio defines this macro
#endif
#if __cplusplus >= 201103L
#include <google/protobuf/stubs/type_traits.h>
#endif
#if defined(_MSC_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 <google/protobuf/stubs/atomic_sequence_num.h>
#include <google/protobuf/stubs/atomicops.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/mutex.h>
#include <google/protobuf/stubs/type_traits.h>


namespace google {
namespace protobuf {

class Arena;       // defined below
class Message;     // message.h

namespace internal {
class ArenaString; // arenastring.h
class LazyField;   // lazy_field.h

template<typename Type>
class GenericTypeHandler; // repeated_field.h

// Templated cleanup methods.
template<typename T> void arena_destruct_object(void* object) {
  reinterpret_cast<T*>(object)->~T();
}
template<typename T> void arena_delete_object(void* object) {
  delete reinterpret_cast<T*>(object);
}
inline void arena_free(void* object, size_t size) {
#if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation)
  ::operator delete(object, size);
#else
  (void)size;
  ::operator delete(object);
#endif
}

}  // namespace internal

// ArenaOptions provides optional additional parameters to arena construction
// that control its block-allocation behavior.
struct ArenaOptions {
  // This defines the size of the first block requested from the system malloc.
  // Subsequent block sizes will increase in a geometric series up to a maximum.
  size_t start_block_size;

  // This defines the maximum block size requested from system malloc (unless an
  // individual arena allocation request occurs with a size larger than this
  // maximum). Requested block sizes increase up to this value, then remain
  // here.
  size_t max_block_size;

  // An initial block of memory for the arena to use, or NULL for none. If
  // provided, the block must live at least as long as the arena itself. The
  // creator of the Arena retains ownership of the block after the Arena is
  // destroyed.
  char* initial_block;

  // The size of the initial block, if provided.
  size_t initial_block_size;

  // A function pointer to an alloc method that returns memory blocks of size
  // requested. By default, it contains a ptr to the malloc function.
  //
  // NOTE: block_alloc and dealloc functions are expected to behave like
  // malloc and free, including Asan poisoning.
  void* (*block_alloc)(size_t);
  // A function pointer to a dealloc method that takes ownership of the blocks
  // from the arena. By default, it contains a ptr to a wrapper function that
  // calls free.
  void (*block_dealloc)(void*, size_t);

  // Hooks for adding external functionality such as user-specific metrics
  // collection, specific debugging abilities, etc.
  // Init hook may return a pointer to a cookie to be stored in the arena.
  // reset and destruction hooks will then be called with the same cookie
  // pointer. This allows us to save an external object per arena instance and
  // use it on the other hooks (Note: It is just as legal for init to return
  // NULL and not use the cookie feature).
  // on_arena_reset and on_arena_destruction also receive the space used in
  // the arena just before the reset.
  void* (*on_arena_init)(Arena* arena);
  void (*on_arena_reset)(Arena* arena, void* cookie, uint64 space_used);
  void (*on_arena_destruction)(Arena* arena, void* cookie, uint64 space_used);

  // type_info is promised to be static - its lifetime extends to
  // match program's lifetime (It is given by typeid operator).
  // Note: typeid(void) will be passed as allocated_type every time we
  // intentionally want to avoid monitoring an allocation. (i.e. internal
  // allocations for managing the arena)
  void (*on_arena_allocation)(const std::type_info* allocated_type,
      uint64 alloc_size, void* cookie);

  ArenaOptions()
      : start_block_size(kDefaultStartBlockSize),
        max_block_size(kDefaultMaxBlockSize),
        initial_block(NULL),
        initial_block_size(0),
        block_alloc(&::operator new),
        block_dealloc(&internal::arena_free),
        on_arena_init(NULL),
        on_arena_reset(NULL),
        on_arena_destruction(NULL),
        on_arena_allocation(NULL) {}

 private:
  // Constants define default starting block size and max block size for
  // arena allocator behavior -- see descriptions above.
  static const size_t kDefaultStartBlockSize = 256;
  static const size_t kDefaultMaxBlockSize   = 8192;
};

// Support for non-RTTI environments. (The metrics hooks API uses type
// information.)
#ifndef GOOGLE_PROTOBUF_NO_RTTI
#define RTTI_TYPE_ID(type) (&typeid(type))
#else
#define RTTI_TYPE_ID(type) (NULL)
#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>, is as
// follows:
//
// - The type T must have (at least) two constructors: a constructor with no
//   arguments, called when a T is allocated on the heap; and a constructor with
//   a google::protobuf::Arena* argument, 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 (no-argument) 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.
//
// - One- and two-user-argument forms of CreateMessage<T>() also exist that
//   forward these constructor arguments to T's constructor: for example,
//   CreateMessage<T>(Arena*, arg1, arg2) forwards to a constructor T(Arena*,
//   arg1, arg2).
//
// This protocol is implemented by all arena-enabled proto2 message classes as
// well as RepeatedPtrField.
//
// Do NOT subclass Arena. This class will be marked as final when C++11 is
// enabled.
class LIBPROTOBUF_EXPORT Arena {
 public:
  // Arena constructor taking custom options. See ArenaOptions below for
  // descriptions of the options available.
  explicit Arena(const ArenaOptions& options) : options_(options) {
    Init();
  }

  // Default constructor with sensible default options, tuned for average
  // use-cases.
  Arena() {
    Init();
  }

  // Destructor deletes all owned heap allocated objects, and destructs objects
  // that have non-trivial destructors, except for proto2 message objects whose
  // destructors can be skipped. Also, frees all blocks except the initial block
  // if it was passed in.
  ~Arena();

  // API to create proto2 message objects on the arena. If the arena passed in
  // is NULL, then a heap allocated object is returned. Type T must be a message
  // defined in a .proto file with cc_enable_arenas set to true, otherwise a
  // compilation error will occur.
  //
  // RepeatedField and RepeatedPtrField may also be instantiated directly on an
  // arena with this method.
  //
  // This function also accepts any type T that satisfies the arena message
  // allocation protocol, documented above.
  template <typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
  static T* CreateMessage(::google::protobuf::Arena* arena) {
    if (arena == NULL) {
      return new T;
    } else {
      return arena->CreateMessageInternal<T>(static_cast<T*>(0));
    }
  }

  // One-argument form of CreateMessage. This is useful for constructing objects
  // that implement the arena message construction protocol described above but
  // take additional constructor arguments.
  template <typename T, typename Arg> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
  static T* CreateMessage(::google::protobuf::Arena* arena, const Arg& arg) {
    if (arena == NULL) {
      return new T(NULL, arg);
    } else {
      return arena->CreateMessageInternal<T>(static_cast<T*>(0),
                                             arg);
    }
  }

  // Two-argument form of CreateMessage. This is useful for constructing objects
  // that implement the arena message construction protocol described above but
  // take additional constructor arguments.
  template <typename T, typename Arg1, typename Arg2> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
  static T* CreateMessage(::google::protobuf::Arena* arena,
                          const Arg1& arg1,
                          const Arg2& arg2) {
    if (arena == NULL) {
      return new T(NULL, arg1, arg2);
    } else {
      return arena->CreateMessageInternal<T>(static_cast<T*>(0),
                                             arg1, arg2);
    }
  }

  // API to create any objects on the arena. Note that only the object will
  // be created on the arena; the underlying ptrs (in case of a proto2 message)
  // will be still heap allocated. Proto messages should usually be allocated
  // with CreateMessage<T>() instead.
  //
  // Note that even if T satisfies the arena message construction protocol
  // (InternalArenaConstructable_ trait and optional DestructorSkippable_
  // trait), as described above, this function does not follow the protocol;
  // instead, it treats T as a black-box type, just as if it did not have these
  // traits. Specifically, T's constructor arguments will always be only those
  // passed to Create<T>() -- no additional arena pointer is implicitly added.
  // Furthermore, the destructor will always be called at arena destruction time
  // (unless the destructor is trivial). Hence, from T's point of view, it is as
  // if the object were allocated on the heap (except that the underlying memory
  // is obtained from the arena).
#if LANG_CXX11
  template <typename T, typename... Args> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
  static T* Create(::google::protobuf::Arena* arena, Args&&... args) {
    if (arena == NULL) {
      return new T(std::forward<Args>(args)...);
    } else {
      return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value,
                                      std::forward<Args>(args)...);
    }
  }
#endif
  template <typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
  static T* Create(::google::protobuf::Arena* arena) {
    if (arena == NULL) {
      return new T();
    } else {
      return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value);
    }
  }

  // Version of the above with one constructor argument for the created object.
  template <typename T, typename Arg> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
  static T* Create(::google::protobuf::Arena* arena, const Arg& arg) {
    if (arena == NULL) {
      return new T(arg);
    } else {
      return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value,
                                      arg);
    }
  }

  // Version of the above with two constructor arguments for the created object.
  template <typename T, typename Arg1, typename Arg2> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
  static T* Create(::google::protobuf::Arena* arena, const Arg1& arg1, const Arg2& arg2) {
    if (arena == NULL) {
      return new T(arg1, arg2);
    } else {
      return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value,
                                      arg1, arg2);
    }
  }

  // Version of the above with three constructor arguments for the created
  // object.
  template <typename T, typename Arg1, typename Arg2, typename Arg3>
  GOOGLE_ATTRIBUTE_ALWAYS_INLINE static T* Create(::google::protobuf::Arena* arena,
                                           const Arg1& arg1, const Arg2& arg2,
                                           const Arg3& arg3) {
    if (arena == NULL) {
      return new T(arg1, arg2, arg3);
    } else {
      return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value,
                                      arg1, arg2, arg3);
    }
  }

  // Version of the above with four constructor arguments for the created
  // object.
  template <typename T, typename Arg1, typename Arg2, typename Arg3,
            typename Arg4>
  GOOGLE_ATTRIBUTE_ALWAYS_INLINE static T* Create(::google::protobuf::Arena* arena,
                                           const Arg1& arg1, const Arg2& arg2,
                                           const Arg3& arg3, const Arg4& arg4) {
    if (arena == NULL) {
      return new T(arg1, arg2, arg3, arg4);
    } else {
      return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value,
                                      arg1, arg2, arg3, arg4);
    }
  }

  // Version of the above with five constructor arguments for the created
  // object.
  template <typename T, typename Arg1, typename Arg2, typename Arg3,
            typename Arg4, typename Arg5>
  GOOGLE_ATTRIBUTE_ALWAYS_INLINE static T* Create(::google::protobuf::Arena* arena,
                                           const Arg1& arg1, const Arg2& arg2,
                                           const Arg3& arg3, const Arg4& arg4,
                                           const Arg5& arg5) {
    if (arena == NULL) {
      return new T(arg1, arg2, arg3, arg4, arg5);
    } else {
      return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value,
                                      arg1, arg2, arg3, arg4, arg5);
    }
  }

  // Version of the above with six constructor arguments for the created
  // object.
  template <typename T, typename Arg1, typename Arg2, typename Arg3,
            typename Arg4, typename Arg5, typename Arg6>
  GOOGLE_ATTRIBUTE_ALWAYS_INLINE static T* Create(::google::protobuf::Arena* arena,
                                           const Arg1& arg1, const Arg2& arg2,
                                           const Arg3& arg3, const Arg4& arg4,
                                           const Arg5& arg5, const Arg6& arg6) {
    if (arena == NULL) {
      return new T(arg1, arg2, arg3, arg4, arg5, arg6);
    } else {
      return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value,
                                      arg1, arg2, arg3, arg4, arg5, arg6);
    }
  }

  // Version of the above with seven constructor arguments for the created
  // object.
  template <typename T, typename Arg1, typename Arg2, typename Arg3,
            typename Arg4, typename Arg5, typename Arg6, typename Arg7>
  GOOGLE_ATTRIBUTE_ALWAYS_INLINE static T* Create(::google::protobuf::Arena* arena,
                                           const Arg1& arg1, const Arg2& arg2,
                                           const Arg3& arg3, const Arg4& arg4,
                                           const Arg5& arg5, const Arg6& arg6,
                                           const Arg7& arg7) {
    if (arena == NULL) {
      return new T(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
    } else {
      return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value,
                                      arg1, arg2, arg3, arg4, arg5, arg6, arg7);
    }
  }

  // Version of the above with eight constructor arguments for the created
  // object.
  template <typename T, typename Arg1, typename Arg2, typename Arg3,
            typename Arg4, typename Arg5, typename Arg6, typename Arg7,
            typename Arg8>
  GOOGLE_ATTRIBUTE_ALWAYS_INLINE static T* Create(::google::protobuf::Arena* arena,
                                           const Arg1& arg1, const Arg2& arg2,
                                           const Arg3& arg3, const Arg4& arg4,
                                           const Arg5& arg5, const Arg6& arg6,
                                           const Arg7& arg7, const Arg8& arg8) {
    if (arena == NULL) {
      return new T(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
    } else {
      return arena->CreateInternal<T>(
          google::protobuf::internal::has_trivial_destructor<T>::value,
          arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
    }
  }

  // Create an array of object type T on the arena *without* invoking the
  // constructor of T. If `arena` is null, then the return value should be freed
  // with `delete[] x;` (or `::operator delete[](x);`).
  // To ensure safe uses, this function checks at compile time
  // (when compiled as C++11) that T is trivially default-constructible and
  // trivially destructible.
  template <typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
  static T* CreateArray(::google::protobuf::Arena* arena, size_t num_elements) {
    GOOGLE_CHECK_LE(num_elements,
             std::numeric_limits<size_t>::max() / sizeof(T))
        << "Requested size is too large to fit into size_t.";
    if (arena == NULL) {
      return static_cast<T*>(::operator new[](num_elements * sizeof(T)));
    } else {
      return arena->CreateInternalRawArray<T>(num_elements);
    }
  }

  // Returns the total space allocated by the arena, which is the sum of the
  // sizes of the underlying blocks. This method is relatively fast; a counter
  // is kept as blocks are allocated.
  uint64 SpaceAllocated() const;
  // Returns the total space used by the arena. Similar to SpaceAllocated but
  // does not include free space and block overhead. The total space returned
  // may not include space used by other threads executing concurrently with
  // the call to this method.
  GOOGLE_ATTRIBUTE_NOINLINE uint64 SpaceUsed() const;
  // DEPRECATED. Please use SpaceAllocated() and SpaceUsed().
  //
  // Combines SpaceAllocated and SpaceUsed. Returns a pair of
  // <space_allocated, space_used>.
  GOOGLE_ATTRIBUTE_NOINLINE std::pair<uint64, uint64> SpaceAllocatedAndUsed() const;

  // Frees all storage allocated by this arena after calling destructors
  // registered with OwnDestructor() and freeing objects registered with Own().
  // Any objects allocated on this arena are unusable after this call. It also
  // returns the total space used by the arena which is the sums of the sizes
  // of the allocated blocks. This method is not thread-safe.
  GOOGLE_ATTRIBUTE_NOINLINE uint64 Reset();

  // Adds |object| to a list of heap-allocated objects to be freed with |delete|
  // when the arena is destroyed or reset.
  template <typename T> GOOGLE_ATTRIBUTE_NOINLINE
  void Own(T* object) {
    OwnInternal(object, google::protobuf::internal::is_convertible<T*, ::google::protobuf::Message*>());
  }

  // Adds |object| to a list of objects whose destructors will be manually
  // called when the arena is destroyed or reset. This differs from Own() in
  // that it does not free the underlying memory with |delete|; hence, it is
  // normally only used for objects that are placement-newed into
  // arena-allocated memory.
  template <typename T> GOOGLE_ATTRIBUTE_NOINLINE
  void OwnDestructor(T* object) {
    if (object != NULL) {
      AddListNode(object, &internal::arena_destruct_object<T>);
    }
  }

  // Adds a custom member function on an object to the list of destructors that
  // will be manually called when the arena is destroyed or reset. This differs
  // from OwnDestructor() in that any member function may be specified, not only
  // the class destructor.
  GOOGLE_ATTRIBUTE_NOINLINE void OwnCustomDestructor(void* object,
                                              void (*destruct)(void*)) {
    AddListNode(object, destruct);
  }

  // Retrieves the arena associated with |value| if |value| is an arena-capable
  // message, or NULL otherwise. This differs from value->GetArena() in that the
  // latter is a virtual call, while this method is a templated call that
  // resolves at compile-time.
  template<typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
  static ::google::protobuf::Arena* GetArena(const T* value) {
    return GetArenaInternal(value, static_cast<T*>(0));
  }

 private:
  struct InternalIsArenaConstructableHelper {
    template<typename U>
    static char ArenaConstructable(
        const typename U::InternalArenaConstructable_*);
    template<typename U>
    static double ArenaConstructable(...);
  };

 public:
  // Helper typetrait that indicates support for arenas in a type T at compile
  // time. This is public only to allow construction of higher-level templated
  // utilities. is_arena_constructable<T>::value is true if the message type T
  // has arena support enabled, and false otherwise.
  //
  // This is inside Arena because only Arena has the friend relationships
  // necessary to see the underlying generated code traits.
  template <typename T>
  struct is_arena_constructable
      : public google::protobuf::internal::integral_constant<
            bool, sizeof(InternalIsArenaConstructableHelper::ArenaConstructable<
                         const T>(static_cast<const T*>(0))) == sizeof(char)> {
  };

 private:
  // Blocks are variable length malloc-ed objects.  The following structure
  // describes the common header for all blocks.
  struct Block {
    void* owner;   // &ThreadCache of thread that owns this block, or
                   // &this->owner if not yet owned by a thread.
    Block* next;   // Next block in arena (may have different owner)
    // ((char*) &block) + pos is next available byte. It is always
    // aligned at a multiple of 8 bytes.
    size_t pos;
    size_t size;  // total size of the block.
    GOOGLE_ATTRIBUTE_ALWAYS_INLINE size_t avail() const { return size - pos; }
    // data follows
  };

  template<typename Type> friend class ::google::protobuf::internal::GenericTypeHandler;
  friend class MockArena;              // For unit-testing.
  friend class internal::ArenaString;  // For AllocateAligned.
  friend class internal::LazyField;    // For CreateMaybeMessage.

  struct ThreadCache {
    // The ThreadCache is considered valid as long as this matches the
    // lifecycle_id of the arena being used.
    int64 last_lifecycle_id_seen;
    Block* last_block_used_;
  };

  static const size_t kHeaderSize = sizeof(Block);
  static google::protobuf::internal::SequenceNumber lifecycle_id_generator_;
#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL)
  // Android ndk does not support GOOGLE_THREAD_LOCAL keyword so we use a custom thread
  // local storage class we implemented.
  // iOS also does not support the GOOGLE_THREAD_LOCAL keyword.
  static ThreadCache& thread_cache();
#elif defined(PROTOBUF_USE_DLLS)
  // Thread local variables cannot be exposed through DLL interface but we can
  // wrap them in static functions.
  static ThreadCache& thread_cache();
#else
  static GOOGLE_THREAD_LOCAL ThreadCache thread_cache_;
  static ThreadCache& thread_cache() { return thread_cache_; }
#endif

  // SFINAE for skipping addition to delete list for a message type when created
  // with CreateMessage. This is mainly to skip proto2/proto1 message objects
  // with cc_enable_arenas=true from being part of the delete list. Also, note,
  // compiler will optimize out the branch in CreateInternal<T>.
  template<typename T>
  static inline bool SkipDeleteList(typename T::DestructorSkippable_*) {
    return true;
  }

  // For message objects that don't have the DestructorSkippable_ trait, we
  // always add to the delete list.
  template<typename T>
  static inline bool SkipDeleteList(...) {
    return google::protobuf::internal::has_trivial_destructor<T>::value;
  }

 private:
  struct InternalIsDestructorSkippableHelper {
    template<typename U>
    static char DestructorSkippable(
        const typename U::DestructorSkippable_*);
    template<typename U>
    static double DestructorSkippable(...);
  };

 public:
  // Helper typetrait that indicates whether the desctructor of type T should be
  // called when arena is destroyed at compile time. This is only to allow
  // construction of higher-level templated utilities.
  // is_destructor_skippable<T>::value is true if the destructor of the message
  // type T should not be called when arena is destroyed or false otherwise.
  // This is inside Arena because only Arena has the friend relationships
  // necessary to see the underlying generated code traits.
  template<typename T>
  struct is_destructor_skippable
      : public google::protobuf::internal::integral_constant<
            bool,
            sizeof(InternalIsDestructorSkippableHelper::DestructorSkippable<
                   const T>(static_cast<const T*>(0))) == sizeof(char) ||
                google::protobuf::internal::has_trivial_destructor<T>::value> {};

 private:
  // CreateMessage<T> requires that T supports arenas, but this private method
  // works whether or not T supports arenas. These are not exposed to user code
  // as it can cause confusing API usages, and end up having double free in
  // user code. These are used only internally from LazyField and Repeated
  // fields, since they are designed to work in all mode combinations.
  template<typename Msg> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
  static Msg* CreateMaybeMessage(
      Arena* arena, typename Msg::InternalArenaConstructable_*) {
    return CreateMessage<Msg>(arena);
  }

  template<typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
  static T* CreateMaybeMessage(Arena* arena, ...) {
    return Create<T>(arena);
  }

  // Just allocate the required size for the given type assuming the
  // type has a trivial constructor.
  template<typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
  T* CreateInternalRawArray(size_t num_elements) {
    GOOGLE_CHECK_LE(num_elements,
             std::numeric_limits<size_t>::max() / sizeof(T))
        << "Requested size is too large to fit into size_t.";
    return static_cast<T*>(
        AllocateAligned(RTTI_TYPE_ID(T), sizeof(T) * num_elements));
  }

#if LANG_CXX11
  template <typename T, typename... Args> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
  T* CreateInternal(bool skip_explicit_ownership, Args&&... args) {
    T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T)))
        T(std::forward<Args>(args)...);
    if (!skip_explicit_ownership) {
      AddListNode(t, &internal::arena_destruct_object<T>);
    }
    return t;
  }
#endif
  template <typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
  T* CreateInternal(bool skip_explicit_ownership) {
    T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) T();
    if (!skip_explicit_ownership) {
      AddListNode(t, &internal::arena_destruct_object<T>);
    }
    return t;
  }

  template <typename T, typename Arg> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
  T* CreateInternal(bool skip_explicit_ownership, const Arg& arg) {
    T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) T(arg);
    if (!skip_explicit_ownership) {
      AddListNode(t, &internal::arena_destruct_object<T>);
    }
    return t;
  }

  template <typename T, typename Arg1, typename Arg2> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
  T* CreateInternal(
      bool skip_explicit_ownership, const Arg1& arg1, const Arg2& arg2) {
    T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) T(arg1, arg2);
    if (!skip_explicit_ownership) {
      AddListNode(t, &internal::arena_destruct_object<T>);
    }
    return t;
  }

  template <typename T, typename Arg1, typename Arg2, typename Arg3>
  GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* CreateInternal(bool skip_explicit_ownership,
                                            const Arg1& arg1,
                                            const Arg2& arg2,
                                            const Arg3& arg3) {
    T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T)))
        T(arg1, arg2, arg3);
    if (!skip_explicit_ownership) {
      AddListNode(t, &internal::arena_destruct_object<T>);
    }
    return t;
  }

  template <typename T, typename Arg1, typename Arg2, typename Arg3,
            typename Arg4>
  GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* CreateInternal(bool skip_explicit_ownership,
                                            const Arg1& arg1,
                                            const Arg2& arg2,
                                            const Arg3& arg3,
                                            const Arg4& arg4) {
    T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T)))
        T(arg1, arg2, arg3, arg4);
    if (!skip_explicit_ownership) {
      AddListNode(t, &internal::arena_destruct_object<T>);
    }
    return t;
  }

  template <typename T, typename Arg1, typename Arg2, typename Arg3,
            typename Arg4, typename Arg5>
  GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* CreateInternal(bool skip_explicit_ownership,
                                            const Arg1& arg1,
                                            const Arg2& arg2,
                                            const Arg3& arg3,
                                            const Arg4& arg4,
                                            const Arg5& arg5) {
    T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T)))
        T(arg1, arg2, arg3, arg4, arg5);
    if (!skip_explicit_ownership) {
      AddListNode(t, &internal::arena_destruct_object<T>);
    }
    return t;
  }

  template <typename T, typename Arg1, typename Arg2, typename Arg3,
            typename Arg4, typename Arg5, typename Arg6>
  GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* CreateInternal(bool skip_explicit_ownership,
                                            const Arg1& arg1,
                                            const Arg2& arg2,
                                            const Arg3& arg3,
                                            const Arg4& arg4,
                                            const Arg5& arg5,
                                            const Arg6& arg6) {
    T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T)))
        T(arg1, arg2, arg3, arg4, arg5, arg6);
    if (!skip_explicit_ownership) {
      AddListNode(t, &internal::arena_destruct_object<T>);
    }
    return t;
  }

  template <typename T, typename Arg1, typename Arg2, typename Arg3,
            typename Arg4, typename Arg5, typename Arg6, typename Arg7>
  GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* CreateInternal(bool skip_explicit_ownership,
                                            const Arg1& arg1,
                                            const Arg2& arg2,
                                            const Arg3& arg3,
                                            const Arg4& arg4,
                                            const Arg5& arg5,
                                            const Arg6& arg6,
                                            const Arg7& arg7) {
    T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T)))
        T(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
    if (!skip_explicit_ownership) {
      AddListNode(t, &internal::arena_destruct_object<T>);
    }
    return t;
  }

  template <typename T, typename Arg1, typename Arg2, typename Arg3,
            typename Arg4, typename Arg5, typename Arg6, typename Arg7,
            typename Arg8>
  GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* CreateInternal(bool skip_explicit_ownership,
                                            const Arg1& arg1,
                                            const Arg2& arg2,
                                            const Arg3& arg3,
                                            const Arg4& arg4,
                                            const Arg5& arg5,
                                            const Arg6& arg6,
                                            const Arg7& arg7,
                                            const Arg8& arg8) {
    T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T)))
        T(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
    if (!skip_explicit_ownership) {
      AddListNode(t, &internal::arena_destruct_object<T>);
    }
    return t;
  }

  template <typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
  T* CreateMessageInternal(typename T::InternalArenaConstructable_*) {
    return CreateInternal<T>(SkipDeleteList<T>(static_cast<T*>(0)), this);
  }

  template <typename T, typename Arg> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
  T* CreateMessageInternal(typename T::InternalArenaConstructable_*,
                           const Arg& arg) {
    return CreateInternal<T>(SkipDeleteList<T>(static_cast<T*>(0)), this, arg);
  }

  template <typename T, typename Arg1, typename Arg2> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
  T* CreateMessageInternal(typename T::InternalArenaConstructable_*,
                           const Arg1& arg1, const Arg2& arg2) {
    return CreateInternal<T>(SkipDeleteList<T>(static_cast<T*>(0)), this, arg1,
                             arg2);
  }

  // CreateInArenaStorage is used to implement map field. Without it,
  // google::protobuf::Map need to call generated message's protected arena constructor,
  // which needs to declare google::protobuf::Map as friend of generated message.
  template <typename T>
  static void CreateInArenaStorage(T* ptr, Arena* arena) {
    CreateInArenaStorageInternal(ptr, arena,
                                 typename is_arena_constructable<T>::type());
    RegisterDestructorInternal(ptr, arena,
                               typename is_destructor_skippable<T>::type());
  }

  template <typename T>
  static void CreateInArenaStorageInternal(
      T* ptr, Arena* arena, google::protobuf::internal::true_type) {
    new (ptr) T(arena);
  }
  template <typename T>
  static void CreateInArenaStorageInternal(
      T* ptr, Arena* arena, google::protobuf::internal::false_type) {
    new (ptr) T();
  }

  template <typename T>
  static void RegisterDestructorInternal(
      T* ptr, Arena* arena, google::protobuf::internal::true_type) {}
  template <typename T>
  static void RegisterDestructorInternal(
      T* ptr, Arena* arena, google::protobuf::internal::false_type) {
    arena->OwnDestructor(ptr);
  }

  // These implement Own(), which registers an object for deletion (destructor
  // call and operator delete()). The second parameter has type 'true_type' if T
  // is a subtype of ::google::protobuf::Message and 'false_type' otherwise. Collapsing
  // all template instantiations to one for generic Message reduces code size,
  // using the virtual destructor instead.
  template<typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
  void OwnInternal(T* object, google::protobuf::internal::true_type) {
    if (object != NULL) {
      AddListNode(object, &internal::arena_delete_object< ::google::protobuf::Message >);
    }
  }
  template<typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
  void OwnInternal(T* object, google::protobuf::internal::false_type) {
    if (object != NULL) {
      AddListNode(object, &internal::arena_delete_object<T>);
    }
  }

  // Implementation for GetArena(). Only message objects with
  // InternalArenaConstructable_ tags can be associated with an arena, and such
  // objects must implement a GetArenaNoVirtual() method.
  template<typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
  static ::google::protobuf::Arena* GetArenaInternal(
      const T* value, typename T::InternalArenaConstructable_*) {
    return value->GetArenaNoVirtual();
  }

  template<typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
  static ::google::protobuf::Arena* GetArenaInternal(const T* value, ...) {
    return NULL;
  }

  // Allocate and also optionally call on_arena_allocation callback with the
  // allocated type info when the hooks are in place in ArenaOptions and
  // the cookie is not null.
  void* AllocateAligned(const std::type_info* allocated, size_t n);

  // Allocate an internal allocation, avoiding optional typed monitoring.
  GOOGLE_ATTRIBUTE_ALWAYS_INLINE void* AllocateAligned(size_t n) {
    return AllocateAligned(NULL, n);
  }

  void Init();

  // Free all blocks and return the total space used which is the sums of sizes
  // of the all the allocated blocks.
  uint64 FreeBlocks();

  // Add object pointer and cleanup function pointer to the list.
  // TODO(rohananil, cfallin): We could pass in a sub-arena into this method
  // to avoid polluting blocks of this arena with list nodes. This would help in
  // mixed mode (where many protobufs have cc_enable_arenas=false), and is an
  // alternative to a chunked linked-list, but with extra overhead of *next.
  void AddListNode(void* elem, void (*cleanup)(void*));
  // Delete or Destruct all objects owned by the arena.
  void CleanupList();
  uint64 ResetInternal();

  inline void SetThreadCacheBlock(Block* block) {
    thread_cache().last_block_used_ = block;
    thread_cache().last_lifecycle_id_seen = lifecycle_id_;
  }

  int64 lifecycle_id_;  // Unique for each arena. Changes on Reset().

  google::protobuf::internal::AtomicWord blocks_;       // Head of linked list of all allocated blocks
  google::protobuf::internal::AtomicWord hint_;         // Fast thread-local block access
  uint64 space_allocated_;  // Sum of sizes of all allocated blocks.

  // Node contains the ptr of the object to be cleaned up and the associated
  // cleanup function ptr.
  struct Node {
    void* elem;              // Pointer to the object to be cleaned up.
    void (*cleanup)(void*);  // Function pointer to the destructor or deleter.
    Node* next;              // Next node in the list.
  };

  google::protobuf::internal::AtomicWord cleanup_list_;  // Head of a linked list of nodes containing object
                             // ptrs and cleanup methods.

  bool owns_first_block_;    // Indicates that arena owns the first block
  mutable Mutex blocks_lock_;

  void AddBlock(Block* b);
  // Access must be synchronized, either by blocks_lock_ or by being called from
  // Init()/Reset().
  void AddBlockInternal(Block* b);
  void* SlowAlloc(size_t n);
  Block* FindBlock(void* me);
  Block* NewBlock(void* me, Block* my_last_block, size_t n,
                  size_t start_block_size, size_t max_block_size);
  static void* AllocFromBlock(Block* b, size_t n);
  template <typename Key, typename T>
  friend class Map;

  // The arena may save a cookie it receives from the external on_init hook
  // and then use it when calling the on_reset and on_destruction hooks.
  void* hooks_cookie_;

  ArenaOptions options_;

  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Arena);
};

// Defined above for supporting environments without RTTI.
#undef RTTI_TYPE_ID

}  // namespace protobuf

}  // namespace google
#endif  // GOOGLE_PROTOBUF_ARENA_H__
