From d36c0c538a545fac5d9db6ba65c525246d4efa95 Mon Sep 17 00:00:00 2001 From: Feng Xiao Date: Wed, 29 Mar 2017 14:32:48 -0700 Subject: Down-integrate from google3. --- src/google/protobuf/metadata.h | 153 +---------------------------------------- 1 file changed, 1 insertion(+), 152 deletions(-) (limited to 'src/google/protobuf/metadata.h') diff --git a/src/google/protobuf/metadata.h b/src/google/protobuf/metadata.h index dca1fa45..0a6507c0 100644 --- a/src/google/protobuf/metadata.h +++ b/src/google/protobuf/metadata.h @@ -38,134 +38,13 @@ #ifndef GOOGLE_PROTOBUF_METADATA_H__ #define GOOGLE_PROTOBUF_METADATA_H__ -#include -#include -#include -#include +#include #include namespace google { namespace protobuf { namespace internal { -// This is the representation for messages that support arena allocation. It -// uses a tagged pointer to either store the Arena pointer, if there are no -// unknown fields, or a pointer to a block of memory with both the Arena pointer -// and the UnknownFieldSet, if there are unknown fields. This optimization -// allows for "zero-overhead" storage of the Arena pointer, relative to the -// above baseline implementation. -// -// The tagged pointer uses the LSB to disambiguate cases, and uses bit 0 == 0 to -// indicate an arena pointer and bit 0 == 1 to indicate a UFS+Arena-container -// pointer. -template -class InternalMetadataWithArenaBase { - public: - InternalMetadataWithArenaBase() : ptr_(NULL) {} - explicit InternalMetadataWithArenaBase(Arena* arena) : ptr_(arena) {} - - ~InternalMetadataWithArenaBase() { - if (have_unknown_fields() && arena() == NULL) { - delete PtrValue(); - } - ptr_ = NULL; - } - - GOOGLE_ATTRIBUTE_ALWAYS_INLINE const T& unknown_fields() const { - if (GOOGLE_PREDICT_FALSE(have_unknown_fields())) { - return PtrValue()->unknown_fields; - } else { - return Derived::default_instance(); - } - } - - GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* mutable_unknown_fields() { - if (GOOGLE_PREDICT_TRUE(have_unknown_fields())) { - return &PtrValue()->unknown_fields; - } else { - return mutable_unknown_fields_slow(); - } - } - - GOOGLE_ATTRIBUTE_ALWAYS_INLINE Arena* arena() const { - if (GOOGLE_PREDICT_FALSE(have_unknown_fields())) { - return PtrValue()->arena; - } else { - return PtrValue(); - } - } - - GOOGLE_ATTRIBUTE_ALWAYS_INLINE bool have_unknown_fields() const { - return PtrTag() == kTagContainer; - } - - GOOGLE_ATTRIBUTE_ALWAYS_INLINE void Swap(Derived* other) { - // Semantics here are that we swap only the unknown fields, not the arena - // pointer. We cannot simply swap ptr_ with other->ptr_ because we need to - // maintain our own arena ptr. Also, our ptr_ and other's ptr_ may be in - // different states (direct arena pointer vs. container with UFS) so we - // cannot simply swap ptr_ and then restore the arena pointers. We reuse - // UFS's swap implementation instead. - if (have_unknown_fields() || other->have_unknown_fields()) { - static_cast(this)->DoSwap(other->mutable_unknown_fields()); - } - } - - GOOGLE_ATTRIBUTE_ALWAYS_INLINE void MergeFrom(const Derived& other) { - if (other.have_unknown_fields()) { - static_cast(this)->DoMergeFrom(other.unknown_fields()); - } - } - - GOOGLE_ATTRIBUTE_ALWAYS_INLINE void Clear() { - if (have_unknown_fields()) { - static_cast(this)->DoClear(); - } - } - - GOOGLE_ATTRIBUTE_ALWAYS_INLINE void* raw_arena_ptr() const { - return ptr_; - } - - private: - void* ptr_; - - // Tagged pointer implementation. - enum { - // ptr_ is an Arena*. - kTagArena = 0, - // ptr_ is a Container*. - kTagContainer = 1, - }; - static const intptr_t kPtrTagMask = 1; - static const intptr_t kPtrValueMask = ~kPtrTagMask; - - // Accessors for pointer tag and pointer value. - GOOGLE_ATTRIBUTE_ALWAYS_INLINE int PtrTag() const { - return reinterpret_cast(ptr_) & kPtrTagMask; - } - - template U* PtrValue() const { - return reinterpret_cast( - reinterpret_cast(ptr_) & kPtrValueMask); - } - - // If ptr_'s tag is kTagContainer, it points to an instance of this struct. - struct Container { - T unknown_fields; - Arena* arena; - }; - - GOOGLE_ATTRIBUTE_NOINLINE T* mutable_unknown_fields_slow() { - Arena* my_arena = arena(); - Container* container = Arena::Create(my_arena); - ptr_ = reinterpret_cast( - reinterpret_cast(container) | kTagContainer); - container->arena = my_arena; - return &(container->unknown_fields); - } -}; - class InternalMetadataWithArena : public InternalMetadataWithArenaBase { @@ -192,36 +71,6 @@ class InternalMetadataWithArena } }; -// We store unknown fields as a string right now, because there is currently no -// good interface for reading unknown fields into an ArenaString. We may want -// to revisit this to allow unknown fields to be parsed onto the Arena. -class InternalMetadataWithArenaLite - : public InternalMetadataWithArenaBase { - public: - InternalMetadataWithArenaLite() {} - - explicit InternalMetadataWithArenaLite(Arena* arena) - : InternalMetadataWithArenaBase(arena) {} - - void DoSwap(string* other) { - mutable_unknown_fields()->swap(*other); - } - - void DoMergeFrom(const string& other) { - mutable_unknown_fields()->append(other); - } - - void DoClear() { - mutable_unknown_fields()->clear(); - } - - static const string& default_instance() { - return GetEmptyStringAlreadyInited(); - } -}; - } // namespace internal } // namespace protobuf -- cgit v1.2.3