提交 cbb21f3c 编写于 作者: A Alexander Alekhin

Merge pull request #10595 from oqtvs:updateProtobuf

......@@ -11,12 +11,15 @@ if(MSVC)
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146
/wd4305 /wd4127 /wd4100 /wd4512 /wd4125 /wd4389 /wd4510 /wd4610
/wd4702 /wd4456 /wd4457 /wd4065 /wd4310 /wd4661 /wd4506
/wd4701 /wd4703 # potentially uninitialized local/pointer variable 'value' used
/wd4505 # unreferenced local function has been removed
)
else()
#NOTE: -Wno-invalid-offsetof was used as solution for invalid offset warning on protobuf #3450
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wno-deprecated -Wmissing-prototypes -Wmissing-declarations -Wshadow
-Wunused-parameter -Wunused-local-typedefs -Wsign-compare -Wsign-promo
-Wundef -Wtautological-undefined-compare -Wignored-qualifiers -Wextra
-Wunused-function -Wunused-const-variable -Wshorten-64-to-32
-Wunused-function -Wunused-const-variable -Wshorten-64-to-32 -Wno-invalid-offsetof
)
endif()
if(CV_ICC)
......@@ -52,6 +55,7 @@ append_if_exist(Protobuf_SRCS
${PROTOBUF_ROOT}/src/google/protobuf/arena.cc
${PROTOBUF_ROOT}/src/google/protobuf/arenastring.cc
${PROTOBUF_ROOT}/src/google/protobuf/extension_set.cc
${PROTOBUF_ROOT}/src/google/protobuf/generated_message_table_driven_lite.cc
${PROTOBUF_ROOT}/src/google/protobuf/generated_message_util.cc
${PROTOBUF_ROOT}/src/google/protobuf/io/coded_stream.cc
${PROTOBUF_ROOT}/src/google/protobuf/io/zero_copy_stream.cc
......@@ -62,6 +66,7 @@ append_if_exist(Protobuf_SRCS
${PROTOBUF_ROOT}/src/google/protobuf/stubs/bytestream.cc
${PROTOBUF_ROOT}/src/google/protobuf/stubs/common.cc
${PROTOBUF_ROOT}/src/google/protobuf/stubs/int128.cc
${PROTOBUF_ROOT}/src/google/protobuf/stubs/io_win32.cc
${PROTOBUF_ROOT}/src/google/protobuf/stubs/once.cc
${PROTOBUF_ROOT}/src/google/protobuf/stubs/status.cc
${PROTOBUF_ROOT}/src/google/protobuf/stubs/statusor.cc
......@@ -86,6 +91,7 @@ append_if_exist(Protobuf_SRCS
${PROTOBUF_ROOT}/src/google/protobuf/extension_set_heavy.cc
${PROTOBUF_ROOT}/src/google/protobuf/field_mask.pb.cc
${PROTOBUF_ROOT}/src/google/protobuf/generated_message_reflection.cc
${PROTOBUF_ROOT}/src/google/protobuf/generated_message_table_driven.cc
${PROTOBUF_ROOT}/src/google/protobuf/io/gzip_stream.cc
${PROTOBUF_ROOT}/src/google/protobuf/io/printer.cc
${PROTOBUF_ROOT}/src/google/protobuf/io/strtod.cc
......@@ -103,6 +109,7 @@ append_if_exist(Protobuf_SRCS
${PROTOBUF_ROOT}/src/google/protobuf/timestamp.pb.cc
${PROTOBUF_ROOT}/src/google/protobuf/type.pb.cc
${PROTOBUF_ROOT}/src/google/protobuf/unknown_field_set.cc
${PROTOBUF_ROOT}/src/google/protobuf/util/delimited_message_util.cc
${PROTOBUF_ROOT}/src/google/protobuf/util/field_comparator.cc
${PROTOBUF_ROOT}/src/google/protobuf/util/field_mask_util.cc
${PROTOBUF_ROOT}/src/google/protobuf/util/internal/datapiece.cc
......
......@@ -30,6 +30,8 @@
#include <google/protobuf/any.h>
#include <google/protobuf/generated_message_util.h>
namespace google {
namespace protobuf {
namespace internal {
......@@ -70,13 +72,11 @@ bool AnyMetadata::UnpackTo(Message* message) const {
if (!InternalIs(message->GetDescriptor())) {
return false;
}
return message->ParseFromString(
value_->GetNoArena(&::google::protobuf::internal::GetEmptyString()));
return message->ParseFromString(value_->GetNoArena());
}
bool AnyMetadata::InternalIs(const Descriptor* descriptor) const {
const string type_url = type_url_->GetNoArena(
&::google::protobuf::internal::GetEmptyString());
const string type_url = type_url_->GetNoArena();
string full_name;
if (!ParseAnyTypeUrl(type_url, &full_name)) {
return false;
......
......@@ -63,7 +63,7 @@ class LIBPROTOBUF_EXPORT AnyMetadata {
// Unpacks the payload into the given message. Returns false if the message's
// type doesn't match the type specified in the type URL (i.e., the full
// name after the last "/" of the type URL doesn't match the message's actaul
// name after the last "/" of the type URL doesn't match the message's actual
// full name) or parsing the payload has failed.
bool UnpackTo(Message* message) const;
......@@ -90,8 +90,8 @@ extern const char kTypeGoogleProdComPrefix[]; // "type.googleprod.com/".
// Get the proto type name from Any::type_url value. For example, passing
// "type.googleapis.com/rpc.QueryOrigin" will return "rpc.QueryOrigin" in
// *full_type_name. Returns false if type_url does not start with
// "type.googleapis.com" or "type.googleprod.com".
// *full_type_name. Returns false if the type_url does not have a "/"
// in the type url separating the full type name.
bool ParseAnyTypeUrl(const string& type_url, string* full_type_name);
// See if message is of type google.protobuf.Any, if so, return the descriptors
......
......@@ -8,38 +8,56 @@
#include <google/protobuf/stubs/common.h>
#if GOOGLE_PROTOBUF_VERSION < 3001000
#if GOOGLE_PROTOBUF_VERSION < 3005000
#error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update
#error your headers.
#endif
#if 3001000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
#if 3005001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc.
#endif
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/arena.h>
#include <google/protobuf/arenastring.h>
#include <google/protobuf/generated_message_table_driven.h>
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/metadata.h>
#include <google/protobuf/message.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/extension_set.h>
#include <google/protobuf/repeated_field.h> // IWYU pragma: export
#include <google/protobuf/extension_set.h> // IWYU pragma: export
#include <google/protobuf/unknown_field_set.h>
#include <google/protobuf/any.h>
// @@protoc_insertion_point(includes)
namespace protobuf_google_2fprotobuf_2fany_2eproto {
// Internal implementation detail -- do not use these members.
struct LIBPROTOBUF_EXPORT TableStruct {
static const ::google::protobuf::internal::ParseTableField entries[];
static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
static const ::google::protobuf::internal::ParseTable schema[1];
static const ::google::protobuf::internal::FieldMetadata field_metadata[];
static const ::google::protobuf::internal::SerializationTable serialization_table[];
static const ::google::protobuf::uint32 offsets[];
};
void LIBPROTOBUF_EXPORT AddDescriptors();
void LIBPROTOBUF_EXPORT InitDefaultsAnyImpl();
void LIBPROTOBUF_EXPORT InitDefaultsAny();
inline void LIBPROTOBUF_EXPORT InitDefaults() {
InitDefaultsAny();
}
} // namespace protobuf_google_2fprotobuf_2fany_2eproto
namespace google {
namespace protobuf {
// Internal implementation detail -- do not call these.
void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fany_2eproto();
void LIBPROTOBUF_EXPORT protobuf_InitDefaults_google_2fprotobuf_2fany_2eproto();
void protobuf_AssignDesc_google_2fprotobuf_2fany_2eproto();
void protobuf_ShutdownFile_google_2fprotobuf_2fany_2eproto();
class Any;
class AnyDefaultTypeInternal;
LIBPROTOBUF_EXPORT extern AnyDefaultTypeInternal _Any_default_instance_;
} // namespace protobuf
} // namespace google
namespace google {
namespace protobuf {
// ===================================================================
......@@ -54,11 +72,31 @@ class LIBPROTOBUF_EXPORT Any : public ::google::protobuf::Message /* @@protoc_in
CopyFrom(from);
return *this;
}
#if LANG_CXX11
Any(Any&& from) noexcept
: Any() {
*this = ::std::move(from);
}
inline Any& operator=(Any&& from) noexcept {
if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
if (this != &from) InternalSwap(&from);
} else {
CopyFrom(from);
}
return *this;
}
#endif
static const ::google::protobuf::Descriptor* descriptor();
static const Any& default_instance();
static const Any* internal_default_instance();
static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY
static inline const Any* internal_default_instance() {
return reinterpret_cast<const Any*>(
&_Any_default_instance_);
}
static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
0;
// implements Any -----------------------------------------------
......@@ -71,67 +109,72 @@ class LIBPROTOBUF_EXPORT Any : public ::google::protobuf::Message /* @@protoc_in
}
void Swap(Any* other);
friend void swap(Any& a, Any& b) {
a.Swap(&b);
}
// implements Message ----------------------------------------------
inline Any* New() const { return New(NULL); }
inline Any* New() const PROTOBUF_FINAL { return New(NULL); }
Any* New(::google::protobuf::Arena* arena) const;
void CopyFrom(const ::google::protobuf::Message& from);
void MergeFrom(const ::google::protobuf::Message& from);
Any* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
void CopyFrom(const Any& from);
void MergeFrom(const Any& from);
void Clear();
bool IsInitialized() const;
void Clear() PROTOBUF_FINAL;
bool IsInitialized() const PROTOBUF_FINAL;
size_t ByteSizeLong() const;
size_t ByteSizeLong() const PROTOBUF_FINAL;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input);
::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
bool deterministic, ::google::protobuf::uint8* output) const;
::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
return InternalSerializeWithCachedSizesToArray(false, output);
}
int GetCachedSize() const { return _cached_size_; }
bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const;
void SetCachedSize(int size) const PROTOBUF_FINAL;
void InternalSwap(Any* other);
void UnsafeMergeFrom(const Any& from);
private:
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
return _internal_metadata_.arena();
return NULL;
}
inline void* MaybeArenaPtr() const {
return _internal_metadata_.raw_arena_ptr();
return NULL;
}
public:
::google::protobuf::Metadata GetMetadata() const;
::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL;
// nested types ----------------------------------------------------
// accessors -------------------------------------------------------
// optional string type_url = 1;
// string type_url = 1;
void clear_type_url();
static const int kTypeUrlFieldNumber = 1;
const ::std::string& type_url() const;
void set_type_url(const ::std::string& value);
#if LANG_CXX11
void set_type_url(::std::string&& value);
#endif
void set_type_url(const char* value);
void set_type_url(const char* value, size_t size);
::std::string* mutable_type_url();
::std::string* release_type_url();
void set_allocated_type_url(::std::string* type_url);
// optional bytes value = 2;
// bytes value = 2;
void clear_value();
static const int kValueFieldNumber = 2;
const ::std::string& value() const;
void set_value(const ::std::string& value);
#if LANG_CXX11
void set_value(::std::string&& value);
#endif
void set_value(const char* value);
void set_value(const void* value, size_t size);
::std::string* mutable_value();
......@@ -146,37 +189,43 @@ class LIBPROTOBUF_EXPORT Any : public ::google::protobuf::Message /* @@protoc_in
::google::protobuf::internal::ArenaStringPtr value_;
mutable int _cached_size_;
::google::protobuf::internal::AnyMetadata _any_metadata_;
friend void LIBPROTOBUF_EXPORT protobuf_InitDefaults_google_2fprotobuf_2fany_2eproto_impl();
friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fany_2eproto_impl();
friend void protobuf_AssignDesc_google_2fprotobuf_2fany_2eproto();
friend void protobuf_ShutdownFile_google_2fprotobuf_2fany_2eproto();
void InitAsDefaultInstance();
friend struct ::protobuf_google_2fprotobuf_2fany_2eproto::TableStruct;
friend void ::protobuf_google_2fprotobuf_2fany_2eproto::InitDefaultsAnyImpl();
};
extern ::google::protobuf::internal::ExplicitlyConstructed<Any> Any_default_instance_;
// ===================================================================
// ===================================================================
#if !PROTOBUF_INLINE_NOT_IN_HEADERS
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif // __GNUC__
// Any
// optional string type_url = 1;
// string type_url = 1;
inline void Any::clear_type_url() {
type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& Any::type_url() const {
// @@protoc_insertion_point(field_get:google.protobuf.Any.type_url)
return type_url_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
return type_url_.GetNoArena();
}
inline void Any::set_type_url(const ::std::string& value) {
type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
// @@protoc_insertion_point(field_set:google.protobuf.Any.type_url)
}
#if LANG_CXX11
inline void Any::set_type_url(::std::string&& value) {
type_url_.SetNoArena(
&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
// @@protoc_insertion_point(field_set_rvalue:google.protobuf.Any.type_url)
}
#endif
inline void Any::set_type_url(const char* value) {
GOOGLE_DCHECK(value != NULL);
type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
// @@protoc_insertion_point(field_set_char:google.protobuf.Any.type_url)
......@@ -207,20 +256,29 @@ inline void Any::set_allocated_type_url(::std::string* type_url) {
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Any.type_url)
}
// optional bytes value = 2;
// bytes value = 2;
inline void Any::clear_value() {
value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& Any::value() const {
// @@protoc_insertion_point(field_get:google.protobuf.Any.value)
return value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
return value_.GetNoArena();
}
inline void Any::set_value(const ::std::string& value) {
value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
// @@protoc_insertion_point(field_set:google.protobuf.Any.value)
}
#if LANG_CXX11
inline void Any::set_value(::std::string&& value) {
value_.SetNoArena(
&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
// @@protoc_insertion_point(field_set_rvalue:google.protobuf.Any.value)
}
#endif
inline void Any::set_value(const char* value) {
GOOGLE_DCHECK(value != NULL);
value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
// @@protoc_insertion_point(field_set_char:google.protobuf.Any.value)
......@@ -251,10 +309,9 @@ inline void Any::set_allocated_value(::std::string* value) {
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Any.value)
}
inline const Any* Any::internal_default_instance() {
return &Any_default_instance_.get();
}
#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif // __GNUC__
// @@protoc_insertion_point(namespace_scope)
......
......@@ -36,280 +36,349 @@
#ifdef ADDRESS_SANITIZER
#include <sanitizer/asan_interface.h>
#endif
#endif // ADDRESS_SANITIZER
#include <google/protobuf/stubs/port.h>
namespace google {
static const size_t kMinCleanupListElements = 8;
static const size_t kMaxCleanupListElements = 64; // 1kB on 64-bit.
namespace protobuf {
namespace internal {
google::protobuf::internal::SequenceNumber Arena::lifecycle_id_generator_;
google::protobuf::internal::SequenceNumber ArenaImpl::lifecycle_id_generator_;
#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL)
Arena::ThreadCache& Arena::thread_cache() {
ArenaImpl::ThreadCache& ArenaImpl::thread_cache() {
static internal::ThreadLocalStorage<ThreadCache>* thread_cache_ =
new internal::ThreadLocalStorage<ThreadCache>();
return *thread_cache_->Get();
}
#elif defined(PROTOBUF_USE_DLLS)
Arena::ThreadCache& Arena::thread_cache() {
ArenaImpl::ThreadCache& ArenaImpl::thread_cache() {
static GOOGLE_THREAD_LOCAL ThreadCache thread_cache_ = { -1, NULL };
return thread_cache_;
}
#else
GOOGLE_THREAD_LOCAL Arena::ThreadCache Arena::thread_cache_ = { -1, NULL };
GOOGLE_THREAD_LOCAL ArenaImpl::ThreadCache ArenaImpl::thread_cache_ = {-1, NULL};
#endif
void Arena::Init() {
void ArenaImpl::Init() {
lifecycle_id_ = lifecycle_id_generator_.GetNext();
blocks_ = 0;
hint_ = 0;
owns_first_block_ = true;
cleanup_list_ = 0;
if (options_.initial_block != NULL && options_.initial_block_size > 0) {
GOOGLE_CHECK_GE(options_.initial_block_size, sizeof(Block))
<< ": Initial block size too small for header.";
// Add first unowned block to list.
Block* first_block = reinterpret_cast<Block*>(options_.initial_block);
first_block->size = options_.initial_block_size;
first_block->pos = kHeaderSize;
first_block->next = NULL;
// Thread which calls Init() owns the first block. This allows the
// single-threaded case to allocate on the first block without taking any
// locks.
first_block->owner = &thread_cache();
SetThreadCacheBlock(first_block);
AddBlockInternal(first_block);
owns_first_block_ = false;
}
google::protobuf::internal::NoBarrier_Store(&hint_, 0);
google::protobuf::internal::NoBarrier_Store(&threads_, 0);
// Call the initialization hook
if (options_.on_arena_init != NULL) {
hooks_cookie_ = options_.on_arena_init(this);
if (initial_block_) {
// Thread which calls Init() owns the first block. This allows the
// single-threaded case to allocate on the first block without having to
// perform atomic operations.
InitBlock(initial_block_, &thread_cache(), options_.initial_block_size);
ThreadInfo* info = NewThreadInfo(initial_block_);
info->next = NULL;
google::protobuf::internal::NoBarrier_Store(&threads_,
reinterpret_cast<google::protobuf::internal::AtomicWord>(info));
google::protobuf::internal::NoBarrier_Store(&space_allocated_,
options_.initial_block_size);
CacheBlock(initial_block_);
} else {
hooks_cookie_ = NULL;
}
}
Arena::~Arena() {
uint64 space_allocated = ResetInternal();
// Call the destruction hook
if (options_.on_arena_destruction != NULL) {
options_.on_arena_destruction(this, hooks_cookie_, space_allocated);
google::protobuf::internal::NoBarrier_Store(&space_allocated_, 0);
}
}
uint64 Arena::Reset() {
// Invalidate any ThreadCaches pointing to any blocks we just destroyed.
lifecycle_id_ = lifecycle_id_generator_.GetNext();
return ResetInternal();
ArenaImpl::~ArenaImpl() {
// Have to do this in a first pass, because some of the destructors might
// refer to memory in other blocks.
CleanupList();
FreeBlocks();
}
uint64 Arena::ResetInternal() {
uint64 ArenaImpl::Reset() {
// Have to do this in a first pass, because some of the destructors might
// refer to memory in other blocks.
CleanupList();
uint64 space_allocated = FreeBlocks();
// Call the reset hook
if (options_.on_arena_reset != NULL) {
options_.on_arena_reset(this, hooks_cookie_, space_allocated);
}
Init();
return space_allocated;
}
Arena::Block* Arena::NewBlock(void* me, Block* my_last_block, size_t n,
size_t start_block_size, size_t max_block_size) {
ArenaImpl::Block* ArenaImpl::NewBlock(void* me, Block* my_last_block,
size_t min_bytes) {
size_t size;
if (my_last_block != NULL) {
// Double the current block size, up to a limit.
size = 2 * (my_last_block->size);
if (size > max_block_size) size = max_block_size;
size = std::min(2 * my_last_block->size, options_.max_block_size);
} else {
size = start_block_size;
size = options_.start_block_size;
}
// Verify that n + kHeaderSize won't overflow.
GOOGLE_CHECK_LE(n, std::numeric_limits<size_t>::max() - kHeaderSize);
size = std::max(size, kHeaderSize + n);
// Verify that min_bytes + kHeaderSize won't overflow.
GOOGLE_CHECK_LE(min_bytes, std::numeric_limits<size_t>::max() - kHeaderSize);
size = std::max(size, kHeaderSize + min_bytes);
Block* b = reinterpret_cast<Block*>(options_.block_alloc(size));
b->pos = kHeaderSize + n;
InitBlock(b, me, size);
google::protobuf::internal::NoBarrier_AtomicIncrement(&space_allocated_, size);
return b;
}
void ArenaImpl::InitBlock(Block* b, void *me, size_t size) {
b->pos = kHeaderSize;
b->size = size;
b->owner = me;
b->next = NULL;
#ifdef ADDRESS_SANITIZER
// Poison the rest of the block for ASAN. It was unpoisoned by the underlying
// malloc but it's not yet usable until we return it as part of an allocation.
ASAN_POISON_MEMORY_REGION(
reinterpret_cast<char*>(b) + b->pos, b->size - b->pos);
#endif
return b;
#endif // ADDRESS_SANITIZER
}
void Arena::AddBlock(Block* b) {
MutexLock l(&blocks_lock_);
AddBlockInternal(b);
ArenaImpl::CleanupChunk* ArenaImpl::ExpandCleanupList(CleanupChunk* cleanup,
Block* b) {
size_t size = cleanup ? cleanup->size * 2 : kMinCleanupListElements;
size = std::min(size, kMaxCleanupListElements);
size_t bytes = internal::AlignUpTo8(CleanupChunk::SizeOf(size));
if (b->avail() < bytes) {
b = GetBlock(bytes);
}
CleanupChunk* list =
reinterpret_cast<CleanupChunk*>(AllocFromBlock(b, bytes));
list->next = b->thread_info->cleanup;
list->size = size;
list->len = 0;
b->thread_info->cleanup = list;
return list;
}
void Arena::AddBlockInternal(Block* b) {
b->next = reinterpret_cast<Block*>(google::protobuf::internal::NoBarrier_Load(&blocks_));
google::protobuf::internal::Release_Store(&blocks_, reinterpret_cast<google::protobuf::internal::AtomicWord>(b));
if (b->avail() != 0) {
// Direct future allocations to this block.
google::protobuf::internal::Release_Store(&hint_, reinterpret_cast<google::protobuf::internal::AtomicWord>(b));
inline GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
void ArenaImpl::AddCleanupInBlock(
Block* b, void* elem, void (*func)(void*)) {
CleanupChunk* cleanup = b->thread_info->cleanup;
if (cleanup == NULL || cleanup->len == cleanup->size) {
cleanup = ExpandCleanupList(cleanup, b);
}
}
void Arena::AddListNode(void* elem, void (*cleanup)(void*)) {
Node* node = reinterpret_cast<Node*>(AllocateAligned(sizeof(Node)));
CleanupNode* node = &cleanup->nodes[cleanup->len++];
node->elem = elem;
node->cleanup = cleanup;
node->next = reinterpret_cast<Node*>(
google::protobuf::internal::NoBarrier_AtomicExchange(&cleanup_list_,
reinterpret_cast<google::protobuf::internal::AtomicWord>(node)));
node->cleanup = func;
}
void* Arena::AllocateAligned(const std::type_info* allocated, size_t n) {
// Align n to next multiple of 8 (from Hacker's Delight, Chapter 3.)
n = (n + 7) & -8;
void ArenaImpl::AddCleanup(void* elem, void (*cleanup)(void*)) {
return AddCleanupInBlock(GetBlock(0), elem, cleanup);
}
// Monitor allocation if needed.
if (GOOGLE_PREDICT_FALSE(hooks_cookie_ != NULL) &&
options_.on_arena_allocation != NULL) {
options_.on_arena_allocation(allocated, n, hooks_cookie_);
}
void* ArenaImpl::AllocateAligned(size_t n) {
GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned.
return AllocFromBlock(GetBlock(n), n);
}
void* ArenaImpl::AllocateAlignedAndAddCleanup(size_t n,
void (*cleanup)(void*)) {
GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned.
Block* b = GetBlock(n);
void* mem = AllocFromBlock(b, n);
AddCleanupInBlock(b, mem, cleanup);
return mem;
}
inline GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
ArenaImpl::Block* ArenaImpl::GetBlock(size_t n) {
Block* my_block = NULL;
// If this thread already owns a block in this arena then try to use that.
// This fast path optimizes the case where multiple threads allocate from the
// same arena.
if (thread_cache().last_lifecycle_id_seen == lifecycle_id_ &&
thread_cache().last_block_used_ != NULL) {
if (thread_cache().last_block_used_->avail() < n) {
return SlowAlloc(n);
ThreadCache* tc = &thread_cache();
if (tc->last_lifecycle_id_seen == lifecycle_id_) {
my_block = tc->last_block_used_;
if (my_block->avail() >= n) {
return my_block;
}
return AllocFromBlock(thread_cache().last_block_used_, n);
}
// Check whether we own the last accessed block on this arena.
// This fast path optimizes the case where a single thread uses multiple
// arenas.
void* me = &thread_cache();
Block* b = reinterpret_cast<Block*>(google::protobuf::internal::Acquire_Load(&hint_));
if (!b || b->owner != me || b->avail() < n) {
return SlowAlloc(n);
if (b != NULL && b->owner == tc) {
my_block = b;
if (my_block->avail() >= n) {
return my_block;
}
}
return AllocFromBlock(b, n);
return GetBlockSlow(tc, my_block, n);
}
void* Arena::AllocFromBlock(Block* b, size_t n) {
inline GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
void* ArenaImpl::AllocFromBlock(Block* b, size_t n) {
GOOGLE_DCHECK_EQ(internal::AlignUpTo8(b->pos), b->pos); // Must be already aligned.
GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned.
GOOGLE_DCHECK_GE(b->avail(), n);
size_t p = b->pos;
b->pos = p + n;
#ifdef ADDRESS_SANITIZER
ASAN_UNPOISON_MEMORY_REGION(reinterpret_cast<char*>(b) + p, n);
#endif
#endif // ADDRESS_SANITIZER
return reinterpret_cast<char*>(b) + p;
}
void* Arena::SlowAlloc(size_t n) {
void* me = &thread_cache();
Block* b = FindBlock(me); // Find block owned by me.
// See if allocation fits in my latest block.
if (b != NULL && b->avail() >= n) {
SetThreadCacheBlock(b);
google::protobuf::internal::NoBarrier_Store(&hint_, reinterpret_cast<google::protobuf::internal::AtomicWord>(b));
return AllocFromBlock(b, n);
ArenaImpl::Block* ArenaImpl::GetBlockSlow(void* me, Block* my_full_block,
size_t n) {
ThreadInfo* info =
my_full_block ? my_full_block->thread_info : GetThreadInfo(me, n);
GOOGLE_DCHECK(info != NULL);
Block* b = info->head;
if (b->avail() < n) {
Block* new_b = NewBlock(me, b, n);
new_b->thread_info = info;
new_b->next = b;
info->head = new_b;
b = new_b;
}
b = NewBlock(me, b, n, options_.start_block_size, options_.max_block_size);
AddBlock(b);
SetThreadCacheBlock(b);
return reinterpret_cast<char*>(b) + kHeaderSize;
CacheBlock(b);
return b;
}
uint64 Arena::SpaceAllocated() const {
uint64 space_allocated = 0;
Block* b = reinterpret_cast<Block*>(google::protobuf::internal::NoBarrier_Load(&blocks_));
while (b != NULL) {
space_allocated += (b->size);
b = b->next;
}
return space_allocated;
uint64 ArenaImpl::SpaceAllocated() const {
return google::protobuf::internal::NoBarrier_Load(&space_allocated_);
}
uint64 Arena::SpaceUsed() const {
uint64 ArenaImpl::SpaceUsed() const {
ThreadInfo* info =
reinterpret_cast<ThreadInfo*>(google::protobuf::internal::Acquire_Load(&threads_));
uint64 space_used = 0;
Block* b = reinterpret_cast<Block*>(google::protobuf::internal::NoBarrier_Load(&blocks_));
while (b != NULL) {
space_used += (b->pos - kHeaderSize);
b = b->next;
for ( ; info; info = info->next) {
// Remove the overhead of the ThreadInfo itself.
space_used -= sizeof(ThreadInfo);
for (Block* b = info->head; b; b = b->next) {
space_used += (b->pos - kHeaderSize);
}
}
return space_used;
}
pair<uint64, uint64> Arena::SpaceAllocatedAndUsed() const {
uint64 allocated = 0;
uint64 used = 0;
uint64 ArenaImpl::FreeBlocks() {
uint64 space_allocated = 0;
// By omitting an Acquire barrier we ensure that any user code that doesn't
// properly synchronize Reset() or the destructor will throw a TSAN warning.
ThreadInfo* info =
reinterpret_cast<ThreadInfo*>(google::protobuf::internal::NoBarrier_Load(&threads_));
while (info) {
// This is inside the block we are freeing, so we need to read it now.
ThreadInfo* next_info = info->next;
for (Block* b = info->head; b; ) {
// This is inside the block we are freeing, so we need to read it now.
Block* next_block = b->next;
space_allocated += (b->size);
#ifdef ADDRESS_SANITIZER
// This memory was provided by the underlying allocator as unpoisoned, so
// return it in an unpoisoned state.
ASAN_UNPOISON_MEMORY_REGION(reinterpret_cast<char*>(b), b->size);
#endif // ADDRESS_SANITIZER
Block* b = reinterpret_cast<Block*>(google::protobuf::internal::NoBarrier_Load(&blocks_));
while (b != NULL) {
allocated += b->size;
used += (b->pos - kHeaderSize);
b = b->next;
if (b != initial_block_) {
options_.block_dealloc(b, b->size);
}
b = next_block;
}
info = next_info;
}
return std::make_pair(allocated, used);
return space_allocated;
}
uint64 Arena::FreeBlocks() {
uint64 space_allocated = 0;
Block* b = reinterpret_cast<Block*>(google::protobuf::internal::NoBarrier_Load(&blocks_));
Block* first_block = NULL;
while (b != NULL) {
space_allocated += (b->size);
Block* next = b->next;
if (next != NULL) {
options_.block_dealloc(b, b->size);
} else {
if (owns_first_block_) {
options_.block_dealloc(b, b->size);
} else {
// User passed in the first block, skip free'ing the memory.
first_block = b;
void ArenaImpl::CleanupList() {
// By omitting an Acquire barrier we ensure that any user code that doesn't
// properly synchronize Reset() or the destructor will throw a TSAN warning.
ThreadInfo* info =
reinterpret_cast<ThreadInfo*>(google::protobuf::internal::NoBarrier_Load(&threads_));
for ( ; info; info = info->next) {
CleanupChunk* list = info->cleanup;
while (list) {
size_t n = list->len;
CleanupNode* node = &list->nodes[list->len - 1];
for (size_t i = 0; i < n; i++, node--) {
node->cleanup(node->elem);
}
list = list->next;
}
b = next;
}
blocks_ = 0;
hint_ = 0;
if (!owns_first_block_) {
// Make the first block that was passed in through ArenaOptions
// available for reuse.
first_block->pos = kHeaderSize;
// Thread which calls Reset() owns the first block. This allows the
// single-threaded case to allocate on the first block without taking any
// locks.
first_block->owner = &thread_cache();
SetThreadCacheBlock(first_block);
AddBlockInternal(first_block);
}
ArenaImpl::ThreadInfo* ArenaImpl::NewThreadInfo(Block* b) {
GOOGLE_DCHECK(FindThreadInfo(b->owner) == NULL);
ThreadInfo* info =
reinterpret_cast<ThreadInfo*>(AllocFromBlock(b, sizeof(ThreadInfo)));
b->thread_info = info;
info->owner = b->owner;
info->head = b;
info->cleanup = NULL;
return info;
}
ArenaImpl::ThreadInfo* ArenaImpl::FindThreadInfo(void* me) {
ThreadInfo* info =
reinterpret_cast<ThreadInfo*>(google::protobuf::internal::Acquire_Load(&threads_));
for ( ; info; info = info->next) {
if (info->owner == me) {
return info;
}
}
return space_allocated;
return NULL;
}
void Arena::CleanupList() {
Node* head =
reinterpret_cast<Node*>(google::protobuf::internal::NoBarrier_Load(&cleanup_list_));
while (head != NULL) {
head->cleanup(head->elem);
head = head->next;
ArenaImpl::ThreadInfo* ArenaImpl::GetThreadInfo(void* me, size_t n) {
ThreadInfo* info = FindThreadInfo(me);
if (!info) {
// This thread doesn't have any ThreadInfo, which also means it doesn't have
// any blocks yet. So we'll allocate its first block now.
Block* b = NewBlock(me, NULL, sizeof(ThreadInfo) + n);
info = NewThreadInfo(b);
google::protobuf::internal::AtomicWord head;
do {
head = google::protobuf::internal::NoBarrier_Load(&threads_);
info->next = reinterpret_cast<ThreadInfo*>(head);
} while (google::protobuf::internal::Release_CompareAndSwap(
&threads_, head, reinterpret_cast<google::protobuf::internal::AtomicWord>(info)) != head);
}
cleanup_list_ = 0;
return info;
}
Arena::Block* Arena::FindBlock(void* me) {
// TODO(sanjay): We might want to keep a separate list with one
// entry per thread.
Block* b = reinterpret_cast<Block*>(google::protobuf::internal::Acquire_Load(&blocks_));
while (b != NULL && b->owner != me) {
b = b->next;
} // namespace internal
void Arena::CallDestructorHooks() {
uint64 space_allocated = impl_.SpaceAllocated();
// Call the reset hook
if (on_arena_reset_ != NULL) {
on_arena_reset_(this, hooks_cookie_, space_allocated);
}
// Call the destruction hook
if (on_arena_destruction_ != NULL) {
on_arena_destruction_(this, hooks_cookie_, space_allocated);
}
}
void Arena::OnArenaAllocation(const std::type_info* allocated_type,
size_t n) const {
if (on_arena_allocation_ != NULL) {
on_arena_allocation_(allocated_type, n, hooks_cookie_);
}
return b;
}
} // namespace protobuf
......
此差异已折叠。
......@@ -38,16 +38,6 @@ namespace protobuf {
namespace internal {
void ArenaStringPtr::AssignWithDefault(const ::std::string* default_value,
ArenaStringPtr value) {
const ::std::string* me = *UnsafeRawStringPointer();
const ::std::string* other = *value.UnsafeRawStringPointer();
// If the pointers are the same then do nothing.
if (me != other) {
SetNoArena(default_value, value.GetNoArena(default_value));
}
}
} // namespace internal
} // namespace protobuf
} // namespace google
此差异已折叠。
......@@ -76,7 +76,7 @@ inline bool is_packable(WireFormatLite::WireType type) {
}
// Registry stuff.
typedef hash_map<pair<const MessageLite*, int>,
typedef hash_map<std::pair<const MessageLite*, int>,
ExtensionInfo> ExtensionRegistry;
ExtensionRegistry* registry_ = NULL;
GOOGLE_PROTOBUF_DECLARE_ONCE(registry_init_);
......@@ -221,7 +221,7 @@ int ExtensionSet::NumExtensions() const {
int ExtensionSet::ExtensionSize(int number) const {
ExtensionMap::const_iterator iter = extensions_.find(number);
if (iter == extensions_.end()) return false;
if (iter == extensions_.end()) return 0;
return iter->second.GetSize();
}
......@@ -1371,7 +1371,7 @@ size_t ExtensionSet::ByteSize() const {
bool ExtensionSet::MaybeNewExtension(int number,
const FieldDescriptor* descriptor,
Extension** result) {
pair<ExtensionMap::iterator, bool> insert_result =
std::pair<ExtensionMap::iterator, bool> insert_result =
extensions_.insert(std::make_pair(number, Extension()));
*result = &insert_result.first->second;
(*result)->descriptor = descriptor;
......
......@@ -168,7 +168,7 @@ void GzipInputStream::BackUp(int count) {
}
bool GzipInputStream::Skip(int count) {
const void* data;
int size;
int size = 0;
bool ok = Next(&data, &size);
while (ok && (size < count)) {
count -= size;
......
......@@ -665,7 +665,7 @@ namespace {
class CommentCollector {
public:
CommentCollector(string* prev_trailing_comments,
vector<string>* detached_comments,
std::vector<string>* detached_comments,
string* next_leading_comments)
: prev_trailing_comments_(prev_trailing_comments),
detached_comments_(detached_comments),
......@@ -737,7 +737,7 @@ class CommentCollector {
private:
string* prev_trailing_comments_;
vector<string>* detached_comments_;
std::vector<string>* detached_comments_;
string* next_leading_comments_;
string comment_buffer_;
......@@ -757,7 +757,7 @@ class CommentCollector {
} // namespace
bool Tokenizer::NextWithComments(string* prev_trailing_comments,
vector<string>* detached_comments,
std::vector<string>* detached_comments,
string* next_leading_comments) {
CommentCollector collector(prev_trailing_comments, detached_comments,
next_leading_comments);
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册