diff options
Diffstat (limited to 'src/google')
27 files changed, 139 insertions, 105 deletions
diff --git a/src/google/protobuf/arena.cc b/src/google/protobuf/arena.cc index 1cb6441e..18536781 100644 --- a/src/google/protobuf/arena.cc +++ b/src/google/protobuf/arena.cc @@ -38,7 +38,14 @@ namespace google { namespace protobuf { google::protobuf::internal::SequenceNumber Arena::lifecycle_id_generator_; -__thread Arena::ThreadCache Arena::thread_cache_ = { -1, NULL }; +#ifdef PROTOBUF_USE_DLLS +Arena::ThreadCache& Arena::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 }; +#endif void Arena::Init(const ArenaOptions& options) { lifecycle_id_ = lifecycle_id_generator_.GetNext(); @@ -130,18 +137,18 @@ void* Arena::AllocateAligned(size_t n) { // 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) { + 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); } - return AllocFromBlock(thread_cache_.last_block_used_, n); + 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_; + void* me = &thread_cache(); Block* b = reinterpret_cast<Block*>(google::protobuf::internal::Acquire_Load(&hint_)); if (!b || b->owner != me || b->avail() < n) { // If the next block to allocate from is the first block, try to claim it @@ -169,7 +176,7 @@ void* Arena::AllocFromBlock(Block* b, size_t n) { } void* Arena::SlowAlloc(size_t n) { - void* me = &thread_cache_; + 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) { diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h index 519e3569..d0cb163c 100644 --- a/src/google/protobuf/arena.h +++ b/src/google/protobuf/arena.h @@ -312,7 +312,12 @@ class LIBPROTOBUF_EXPORT Arena { static const size_t kHeaderSize = sizeof(Block); static google::protobuf::internal::SequenceNumber lifecycle_id_generator_; - static __thread ThreadCache thread_cache_; +#ifdef PROTOBUF_USE_DLLS + 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 Type. This is mainly to // skip proto2/proto1 message objects with cc_enable_arenas=true from being @@ -434,8 +439,8 @@ class LIBPROTOBUF_EXPORT Arena { void CleanupList(); inline void SetThreadCacheBlock(Block* block) { - thread_cache_.last_block_used_ = block; - thread_cache_.last_lifecycle_id_seen = lifecycle_id_; + thread_cache().last_block_used_ = block; + thread_cache().last_lifecycle_id_seen = lifecycle_id_; } int64 lifecycle_id_; // Unique for each arena. Changes on Reset(). diff --git a/src/google/protobuf/arena_unittest.cc b/src/google/protobuf/arena_unittest.cc index 76a4274f..9d3d3e3e 100644 --- a/src/google/protobuf/arena_unittest.cc +++ b/src/google/protobuf/arena_unittest.cc @@ -128,7 +128,7 @@ TEST(ArenaTest, InitialBlockTooSmall) { // initial block. std::vector<char> arena_block(64); ArenaOptions options; - options.initial_block = arena_block.data(); + options.initial_block = &arena_block[0]; options.initial_block_size = arena_block.size(); Arena arena(options); @@ -137,7 +137,7 @@ TEST(ArenaTest, InitialBlockTooSmall) { // Ensure that the arena allocator did not return memory pointing into the // initial block of memory. - uintptr_t arena_start = reinterpret_cast<uintptr_t>(arena_block.data()); + uintptr_t arena_start = reinterpret_cast<uintptr_t>(&arena_block[0]); uintptr_t arena_end = arena_start + arena_block.size(); EXPECT_FALSE(allocation >= arena_start && allocation < arena_end); @@ -771,7 +771,7 @@ TEST(ArenaTest, RepeatedFieldOnArena) { // Preallocate an initial arena block to avoid mallocs during hooked region. std::vector<char> arena_block(1024 * 1024); ArenaOptions options; - options.initial_block = arena_block.data(); + options.initial_block = &arena_block[0]; options.initial_block_size = arena_block.size(); Arena arena(options); @@ -898,7 +898,7 @@ TEST(ArenaTest, NoHeapAllocationsTest) { // Allocate a large initial block to avoid mallocs during hooked test. std::vector<char> arena_block(128 * 1024); ArenaOptions options; - options.initial_block = arena_block.data(); + options.initial_block = &arena_block[0]; options.initial_block_size = arena_block.size(); Arena arena(options); @@ -918,7 +918,7 @@ TEST(ArenaTest, NoHeapAllocationsTest) { TEST(ArenaTest, MessageLiteOnArena) { std::vector<char> arena_block(128 * 1024); ArenaOptions options; - options.initial_block = arena_block.data(); + options.initial_block = &arena_block[0]; options.initial_block_size = arena_block.size(); Arena arena(options); const google::protobuf::MessageLite* prototype = dynamic_cast< @@ -977,7 +977,7 @@ TEST(ArenaTest, SpaceUsed) { // Test with initial block. std::vector<char> arena_block(1024); - options.initial_block = arena_block.data(); + options.initial_block = &arena_block[0]; options.initial_block_size = arena_block.size(); Arena arena_2(options); EXPECT_EQ(1024, arena_2.SpaceUsed()); diff --git a/src/google/protobuf/arenastring.h b/src/google/protobuf/arenastring.h index 50f13837..d829ed91 100755 --- a/src/google/protobuf/arenastring.h +++ b/src/google/protobuf/arenastring.h @@ -31,7 +31,6 @@ #ifndef GOOGLE_PROTOBUF_ARENASTRING_H__ #define GOOGLE_PROTOBUF_ARENASTRING_H__ -#include <stdint.h> #include <string> #include <google/protobuf/stubs/common.h> @@ -54,7 +53,7 @@ namespace google { namespace protobuf { namespace internal { -struct ArenaStringPtr { +struct LIBPROTOBUF_EXPORT ArenaStringPtr { inline void Set(const ::std::string* default_value, const ::std::string& value, ::google::protobuf::Arena* arena) { if (ptr_ == default_value) { diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc index 212bc3e9..e71d35fa 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message.cc @@ -1226,7 +1226,7 @@ GenerateDescriptorDeclarations(io::Printer* printer) { for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); printer->Print(" "); - if (IsStringOrMessage(field)) { + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { printer->Print("const "); } field_generators_.get(field).GeneratePrivateMembers(printer); diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_unittest.cc index 20fcfa62..2a04b293 100644 --- a/src/google/protobuf/compiler/cpp/cpp_unittest.cc +++ b/src/google/protobuf/compiler/cpp/cpp_unittest.cc @@ -153,6 +153,7 @@ TEST(GeneratedMessageTest, Defaults) { &message.optional_import_message()); } +#ifndef PROTOBUF_USE_DLLS TEST(GeneratedMessageTest, Int32StringConversion) { EXPECT_EQ("971", Int32ToString(971)); EXPECT_EQ("(~0x7fffffff)", Int32ToString(kint32min)); @@ -165,6 +166,7 @@ TEST(GeneratedMessageTest, Int64StringConversion) { EXPECT_EQ("GOOGLE_LONGLONG(~0x7fffffffffffffff)", Int64ToString(kint64min)); EXPECT_EQ("GOOGLE_LONGLONG(9223372036854775807)", Int64ToString(kint64max)); } +#endif // !PROTOBUF_USE_DLLS TEST(GeneratedMessageTest, FloatingPointDefaults) { const unittest::TestExtremeDefaultValues& extreme_default = diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h index 35a0a899..ad017005 100644 --- a/src/google/protobuf/compiler/plugin.pb.h +++ b/src/google/protobuf/compiler/plugin.pb.h @@ -8,12 +8,12 @@ #include <google/protobuf/stubs/common.h> -#if GOOGLE_PROTOBUF_VERSION < 2006000 +#if GOOGLE_PROTOBUF_VERSION < 3000000 #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 2006002 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3000000 < 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. diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc index 19d49cab..b8dd198d 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc @@ -345,6 +345,10 @@ typedef hash_map<string, const SourceCodeInfo_Location*> LocationsByPathMap; set<string>* allowed_proto3_extendees_ = NULL; GOOGLE_PROTOBUF_DECLARE_ONCE(allowed_proto3_extendees_init_); +void DeleteAllowedProto3Extendee() { + delete allowed_proto3_extendees_; +} + void InitAllowedProto3Extendee() { allowed_proto3_extendees_ = new set<string>; allowed_proto3_extendees_->insert("google.protobuf.FileOptions"); @@ -354,6 +358,7 @@ void InitAllowedProto3Extendee() { allowed_proto3_extendees_->insert("google.protobuf.EnumValueOptions"); allowed_proto3_extendees_->insert("google.protobuf.ServiceOptions"); allowed_proto3_extendees_->insert("google.protobuf.MethodOptions"); + google::protobuf::internal::OnShutdown(&DeleteAllowedProto3Extendee); } // Checks whether the extendee type is allowed in proto3. diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h index 6bb5c6a6..cda25982 100644 --- a/src/google/protobuf/descriptor.pb.h +++ b/src/google/protobuf/descriptor.pb.h @@ -8,12 +8,12 @@ #include <google/protobuf/stubs/common.h> -#if GOOGLE_PROTOBUF_VERSION < 2006000 +#if GOOGLE_PROTOBUF_VERSION < 3000000 #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 2006002 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3000000 < 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. diff --git a/src/google/protobuf/map.h b/src/google/protobuf/map.h index f6ae3e52..6d8a9d03 100644 --- a/src/google/protobuf/map.h +++ b/src/google/protobuf/map.h @@ -110,7 +110,7 @@ class Map { ~Map() { clear(); } // Iterators - class LIBPROTOBUF_EXPORT const_iterator + class const_iterator : public std::iterator<std::forward_iterator_tag, value_type, ptrdiff_t, const value_type*, const value_type&> { typedef typename hash_map<Key, value_type*>::const_iterator InnerIt; @@ -139,7 +139,7 @@ class Map { InnerIt it_; }; - class LIBPROTOBUF_EXPORT iterator : public std::iterator<std::forward_iterator_tag, value_type> { + class iterator : public std::iterator<std::forward_iterator_tag, value_type> { typedef typename hash_map<Key, value_type*>::iterator InnerIt; public: @@ -302,7 +302,7 @@ class Map { template <typename K, typename V, FieldDescriptor::Type KeyProto, FieldDescriptor::Type ValueProto, int default_enum> - friend class LIBPROTOBUF_EXPORT internal::MapField; + friend class internal::MapField; }; } // namespace protobuf diff --git a/src/google/protobuf/map_entry.h b/src/google/protobuf/map_entry.h index 6971c763..217b15f6 100644 --- a/src/google/protobuf/map_entry.h +++ b/src/google/protobuf/map_entry.h @@ -43,6 +43,10 @@ class Arena; namespace protobuf { namespace internal { +// Register all MapEntry default instances so we can delete them in +// ShutdownProtobufLibrary(). +void LIBPROTOBUF_EXPORT RegisterMapEntryDefaultInstance(MessageLite* default_instance); + // This is the common base class for MapEntry. It is used by MapFieldBase in // reflection api, in which the static type of key and value is unknown. class LIBPROTOBUF_EXPORT MapEntryBase : public Message { @@ -80,7 +84,7 @@ class LIBPROTOBUF_EXPORT MapEntryBase : public Message { // Moreover, default_enum_value is used to initialize enum field in proto2. template <typename Key, typename Value, FieldDescriptor::Type KeyProtoType, FieldDescriptor::Type ValueProtoType, int default_enum_value> -class LIBPROTOBUF_EXPORT MapEntry : public MapEntryBase { +class MapEntry : public MapEntryBase { // Handlers for key/value's proto field type. Used to infer internal layout // and provide parsing/serialization support. typedef MapProtoTypeHandler<KeyProtoType> KeyProtoHandler; @@ -317,6 +321,7 @@ class LIBPROTOBUF_EXPORT MapEntry : public MapEntryBase { entry->reflection_ = reflection; entry->default_instance_ = entry; entry->InitAsDefaultInstance(); + RegisterMapEntryDefaultInstance(entry); return entry; } @@ -358,7 +363,7 @@ class LIBPROTOBUF_EXPORT MapEntry : public MapEntryBase { template <typename KeyNested, typename ValueNested, FieldDescriptor::Type KeyProtoNested, FieldDescriptor::Type ValueProtoNested, int default_enum> - class LIBPROTOBUF_EXPORT MapEntryWrapper + class MapEntryWrapper : public MapEntry<KeyNested, ValueNested, KeyProtoNested, ValueProtoNested, default_enum> { typedef MapEntry<KeyNested, ValueNested, KeyProtoNested, ValueProtoNested, @@ -389,7 +394,7 @@ class LIBPROTOBUF_EXPORT MapEntry : public MapEntryBase { template <typename KeyNested, typename ValueNested, FieldDescriptor::Type KeyProtoNested, FieldDescriptor::Type ValueProtoNested, int default_enum> - class LIBPROTOBUF_EXPORT MapEnumEntryWrapper + class MapEnumEntryWrapper : public MapEntry<KeyNested, ValueNested, KeyProtoNested, ValueProtoNested, default_enum> { typedef MapEntry<KeyNested, ValueNested, KeyProtoNested, ValueProtoNested, @@ -428,7 +433,7 @@ class LIBPROTOBUF_EXPORT MapEntry : public MapEntryBase { template <typename K, typename V, FieldDescriptor::Type KType, FieldDescriptor::Type VType, int default_enum> - friend class LIBPROTOBUF_EXPORT internal::MapField; + friend class internal::MapField; friend class LIBPROTOBUF_EXPORT internal::GeneratedMessageReflection; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntry); diff --git a/src/google/protobuf/map_field.cc b/src/google/protobuf/map_field.cc index 74431628..b535ec28 100644 --- a/src/google/protobuf/map_field.cc +++ b/src/google/protobuf/map_field.cc @@ -30,10 +30,37 @@ #include <google/protobuf/map_field.h> +#include <vector> + namespace google { namespace protobuf { namespace internal { +ProtobufOnceType map_entry_default_instances_once_; +Mutex* map_entry_default_instances_mutex_; +vector<MessageLite*>* map_entry_default_instances_; + +void DeleteMapEntryDefaultInstances() { + for (int i = 0; i < map_entry_default_instances_->size(); ++i) { + delete map_entry_default_instances_->at(i); + } + delete map_entry_default_instances_mutex_; + delete map_entry_default_instances_; +} + +void InitMapEntryDefaultInstances() { + map_entry_default_instances_mutex_ = new Mutex(); + map_entry_default_instances_ = new vector<MessageLite*>(); + OnShutdown(&DeleteMapEntryDefaultInstances); +} + +void RegisterMapEntryDefaultInstance(MessageLite* default_instance) { + GoogleOnceInit(&map_entry_default_instances_once_, + &InitMapEntryDefaultInstances); + MutexLock lock(map_entry_default_instances_mutex_); + map_entry_default_instances_->push_back(default_instance); +} + MapFieldBase::~MapFieldBase() { if (repeated_field_ != NULL) delete repeated_field_; } diff --git a/src/google/protobuf/map_field.h b/src/google/protobuf/map_field.h index 0fad1351..8516d74e 100644 --- a/src/google/protobuf/map_field.h +++ b/src/google/protobuf/map_field.h @@ -137,7 +137,7 @@ class LIBPROTOBUF_EXPORT MapFieldBase { template<typename Key, typename T, FieldDescriptor::Type KeyProto, FieldDescriptor::Type ValueProto, int default_enum_value = 0> -class LIBPROTOBUF_EXPORT MapField : public MapFieldBase { +class MapField : public MapFieldBase { // Handlers for key/value's proto field type. typedef MapProtoTypeHandler<KeyProto> KeyProtoHandler; typedef MapProtoTypeHandler<ValueProto> ValueProtoHandler; diff --git a/src/google/protobuf/map_field_test.cc b/src/google/protobuf/map_field_test.cc index 98551839..045f8f2c 100644 --- a/src/google/protobuf/map_field_test.cc +++ b/src/google/protobuf/map_field_test.cc @@ -430,41 +430,6 @@ TEST_P(MapFieldStateTest, MutableMapField) { } } -class MapFieldBaseStateStub : public MapFieldBaseStub { - public: - MapFieldBaseStateStub(Mutex* mutex, int* clean_counter, - int* completed_counter) - : mutex_(mutex), - clean_counter_(clean_counter), - completed_counter_(completed_counter) {} - ~MapFieldBaseStateStub() {} - - protected: - void SyncRepeatedFieldWithMapNoLock() const { Clean(); } - void SyncMapWithRepeatedFieldNoLock() const { Clean(); } - - private: - void Clean() const { - { - MutexLock lock(mutex_); - ++(*clean_counter_); - } - struct timespec tm; - tm.tv_sec = 0; - tm.tv_nsec = 100000000; // 100ms - nanosleep(&tm, NULL); - { - MutexLock lock(mutex_); - // No other thread should have completed while this one was initializing. - EXPECT_EQ(0, *completed_counter_); - } - } - Mutex* mutex_; - int* clean_counter_; - int* completed_counter_; -}; - - } // namespace internal } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/map_test.cc b/src/google/protobuf/map_test.cc index c680ccb2..9db67523 100644 --- a/src/google/protobuf/map_test.cc +++ b/src/google/protobuf/map_test.cc @@ -190,6 +190,7 @@ TEST_F(MapImplTest, MutableAt) { ExpectSingleElement(key, value2); } +#ifdef PROTOBUF_HAS_DEATH_TEST TEST_F(MapImplTest, MutableAtNonExistDeathTest) { EXPECT_DEATH(map_.at(0), ""); } @@ -197,6 +198,7 @@ TEST_F(MapImplTest, MutableAtNonExistDeathTest) { TEST_F(MapImplTest, ImmutableAtNonExistDeathTest) { EXPECT_DEATH(const_map_.at(0), ""); } +#endif // PROTOBUF_HAS_DEATH_TEST TEST_F(MapImplTest, CountNonExist) { EXPECT_EQ(0, map_.count(0)); diff --git a/src/google/protobuf/map_test_util.cc b/src/google/protobuf/map_test_util.cc index b27c8f19..eb7ea511 100644 --- a/src/google/protobuf/map_test_util.cc +++ b/src/google/protobuf/map_test_util.cc @@ -1020,7 +1020,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection( *sub_message, map_int32_int32_key_); int32 val = sub_message->GetReflection()->GetInt32( *sub_message, map_int32_int32_val_); - EXPECT_EQ(map.at(key), val); + EXPECT_EQ(map[key], val); } } { @@ -1034,7 +1034,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection( *sub_message, map_int64_int64_key_); int64 val = sub_message->GetReflection()->GetInt64( *sub_message, map_int64_int64_val_); - EXPECT_EQ(map.at(key), val); + EXPECT_EQ(map[key], val); } } { @@ -1048,7 +1048,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection( *sub_message, map_uint32_uint32_key_); uint32 val = sub_message->GetReflection()->GetUInt32( *sub_message, map_uint32_uint32_val_); - EXPECT_EQ(map.at(key), val); + EXPECT_EQ(map[key], val); } } { @@ -1062,7 +1062,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection( *sub_message, map_uint64_uint64_key_); uint64 val = sub_message->GetReflection()->GetUInt64( *sub_message, map_uint64_uint64_val_); - EXPECT_EQ(map.at(key), val); + EXPECT_EQ(map[key], val); } } { @@ -1076,7 +1076,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection( *sub_message, map_sint32_sint32_key_); int32 val = sub_message->GetReflection()->GetInt32( *sub_message, map_sint32_sint32_val_); - EXPECT_EQ(map.at(key), val); + EXPECT_EQ(map[key], val); } } { @@ -1090,7 +1090,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection( *sub_message, map_sint64_sint64_key_); int64 val = sub_message->GetReflection()->GetInt64( *sub_message, map_sint64_sint64_val_); - EXPECT_EQ(map.at(key), val); + EXPECT_EQ(map[key], val); } } { @@ -1104,7 +1104,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection( *sub_message, map_fixed32_fixed32_key_); uint32 val = sub_message->GetReflection()->GetUInt32( *sub_message, map_fixed32_fixed32_val_); - EXPECT_EQ(map.at(key), val); + EXPECT_EQ(map[key], val); } } { @@ -1118,7 +1118,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection( *sub_message, map_fixed64_fixed64_key_); uint64 val = sub_message->GetReflection()->GetUInt64( *sub_message, map_fixed64_fixed64_val_); - EXPECT_EQ(map.at(key), val); + EXPECT_EQ(map[key], val); } } { @@ -1132,7 +1132,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection( *sub_message, map_sfixed32_sfixed32_key_); int32 val = sub_message->GetReflection()->GetInt32( *sub_message, map_sfixed32_sfixed32_val_); - EXPECT_EQ(map.at(key), val); + EXPECT_EQ(map[key], val); } } { @@ -1146,7 +1146,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection( *sub_message, map_sfixed64_sfixed64_key_); int64 val = sub_message->GetReflection()->GetInt64( *sub_message, map_sfixed64_sfixed64_val_); - EXPECT_EQ(map.at(key), val); + EXPECT_EQ(map[key], val); } } { @@ -1160,7 +1160,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection( *sub_message, map_int32_float_key_); float val = sub_message->GetReflection()->GetFloat( *sub_message, map_int32_float_val_); - EXPECT_EQ(map.at(key), val); + EXPECT_EQ(map[key], val); } } { @@ -1174,7 +1174,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection( *sub_message, map_int32_double_key_); double val = sub_message->GetReflection()->GetDouble( *sub_message, map_int32_double_val_); - EXPECT_EQ(map.at(key), val); + EXPECT_EQ(map[key], val); } } { @@ -1188,7 +1188,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection( *sub_message, map_bool_bool_key_); bool val = sub_message->GetReflection()->GetBool( *sub_message, map_bool_bool_val_); - EXPECT_EQ(map.at(key), val); + EXPECT_EQ(map[key], val); } } { @@ -1202,7 +1202,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection( *sub_message, map_string_string_key_); string val = sub_message->GetReflection()->GetString( *sub_message, map_string_string_val_); - EXPECT_EQ(map.at(key), val); + EXPECT_EQ(map[key], val); } } { @@ -1216,7 +1216,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection( *sub_message, map_int32_bytes_key_); string val = sub_message->GetReflection()->GetString( *sub_message, map_int32_bytes_val_); - EXPECT_EQ(map.at(key), val); + EXPECT_EQ(map[key], val); } } { @@ -1230,7 +1230,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection( *sub_message, map_int32_enum_key_); const EnumValueDescriptor* val = sub_message->GetReflection()->GetEnum( *sub_message, map_int32_enum_val_); - EXPECT_EQ(map.at(key), val); + EXPECT_EQ(map[key], val); } } { @@ -1246,7 +1246,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection( *sub_message, map_int32_foreign_message_val_); int32 val = foreign_message.GetReflection()->GetInt32( foreign_message, foreign_c_); - EXPECT_EQ(map.at(key), val); + EXPECT_EQ(map[key], val); } } } diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h index 1d8f2499..a200bc92 100644 --- a/src/google/protobuf/message.h +++ b/src/google/protobuf/message.h @@ -967,6 +967,7 @@ const RepeatedField<TYPE>& Reflection::GetRepeatedField<TYPE>( \ const Message& message, const FieldDescriptor* field) const; \ \ template<> \ +LIBPROTOBUF_EXPORT \ RepeatedField<TYPE>* Reflection::MutableRepeatedField<TYPE>( \ Message* message, const FieldDescriptor* field) const; diff --git a/src/google/protobuf/preserve_unknown_enum_test.cc b/src/google/protobuf/preserve_unknown_enum_test.cc index 33e9ea10..816e52ca 100644 --- a/src/google/protobuf/preserve_unknown_enum_test.cc +++ b/src/google/protobuf/preserve_unknown_enum_test.cc @@ -200,6 +200,7 @@ TEST(PreserveUnknownEnumTest, Proto2CatchesUnknownValues) { EXPECT_TRUE(enum_value != NULL); r->AddEnum(&message, repeated_field, enum_value); +#ifdef PROTOBUF_HAS_DEATH_TEST // Enum-field integer-based setters GOOGLE_DCHECK-fail on invalid values, in order to // remain consistent with proto2 generated code. EXPECT_DEBUG_DEATH({ @@ -214,6 +215,7 @@ TEST(PreserveUnknownEnumTest, Proto2CatchesUnknownValues) { r->AddEnumValue(&message, repeated_field, 4242); r->GetRepeatedEnum(message, repeated_field, 1); }, "AddEnumValue accepts only valid integer values"); +#endif // PROTOBUF_HAS_DEATH_TEST } TEST(PreserveUnknownEnumTest, SupportsUnknownEnumValuesAPI) { diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h index e14dcc62..4798eeda 100644 --- a/src/google/protobuf/repeated_field.h +++ b/src/google/protobuf/repeated_field.h @@ -236,10 +236,11 @@ class RepeatedField { Arena* arena; Element elements[1]; }; - // Why not sizeof(Rep) - sizeof(Element)? Because this is not accurate w.r.t. - // trailing padding on the struct -- e.g. if Element is int, this would yield - // 12 on x86-64, not 8 as we want. - static const size_t kRepHeaderSize = sizeof(Arena*); + // We can not use sizeof(Rep) - sizeof(Element) due to the trailing padding on + // the struct. We can not use sizeof(Arena*) as well because there might be + // a "gap" after the field arena and before the field elements (e.g., when + // Element is double and pointer is 32bit). + static const size_t kRepHeaderSize; // Contains arena ptr and the elements array. We also keep the invariant that // if rep_ is NULL, then arena is NULL. Rep* rep_; @@ -263,6 +264,10 @@ class RepeatedField { } }; +template<typename Element> +const size_t RepeatedField<Element>::kRepHeaderSize = + reinterpret_cast<size_t>(&reinterpret_cast<Rep*>(16)->elements[0]) - 16; + namespace internal { template <typename It> class RepeatedPtrIterator; template <typename It, typename VoidPtr> class RepeatedPtrOverPtrsIterator; diff --git a/src/google/protobuf/repeated_field_reflection.h b/src/google/protobuf/repeated_field_reflection.h index 42f7be20..44d14d5b 100644 --- a/src/google/protobuf/repeated_field_reflection.h +++ b/src/google/protobuf/repeated_field_reflection.h @@ -38,6 +38,8 @@ #include <google/protobuf/stubs/shared_ptr.h> #endif +#include <google/protobuf/generated_enum_reflection.h> + namespace google { namespace protobuf { namespace internal { @@ -273,7 +275,7 @@ struct RefTypeTraits< template<typename T> struct RefTypeTraits< - T, typename internal::enable_if<internal::is_enum<T>::value>::type> { + T, typename internal::enable_if<is_proto_enum<T>::value>::type> { typedef RepeatedFieldRefIterator<T> iterator; typedef RepeatedFieldAccessor AccessorType; // We use int32 for repeated enums in RepeatedFieldAccessor. diff --git a/src/google/protobuf/repeated_field_reflection_unittest.cc b/src/google/protobuf/repeated_field_reflection_unittest.cc index ae43dfab..8b821806 100644 --- a/src/google/protobuf/repeated_field_reflection_unittest.cc +++ b/src/google/protobuf/repeated_field_reflection_unittest.cc @@ -196,8 +196,7 @@ void TestRepeatedFieldRefIterator( int index = 0; for (typename Ref::const_iterator it = handle.begin(); it != handle.end(); ++it) { - ValueType value = static_cast<ValueType>(*it); - EXPECT_EQ((message.*GetFunc)(index), value); + EXPECT_EQ((message.*GetFunc)(index), *it); ++index; } EXPECT_EQ(handle.size(), index); @@ -410,6 +409,7 @@ TEST(RepeatedFieldReflectionTest, RepeatedFieldRefForRegularFields) { EXPECT_TRUE(rf_message.empty()); EXPECT_TRUE(mrf_message.empty()); +#ifdef PROTOBUF_HAS_DEATH_TEST // Make sure types are checked correctly at runtime. const FieldDescriptor* fd_optional_int32 = desc->FindFieldByName("optional_int32"); @@ -419,6 +419,7 @@ TEST(RepeatedFieldReflectionTest, RepeatedFieldRefForRegularFields) { message, fd_repeated_int32), ""); EXPECT_DEATH(refl->GetRepeatedFieldRef<TestAllTypes>( message, fd_repeated_foreign_message), ""); +#endif // PROTOBUF_HAS_DEATH_TEST } TEST(RepeatedFieldReflectionTest, RepeatedFieldRefForEnums) { diff --git a/src/google/protobuf/repeated_field_unittest.cc b/src/google/protobuf/repeated_field_unittest.cc index 9942af50..15c0c93e 100644 --- a/src/google/protobuf/repeated_field_unittest.cc +++ b/src/google/protobuf/repeated_field_unittest.cc @@ -92,8 +92,8 @@ TEST(RepeatedField, Small) { EXPECT_TRUE(field.empty()); EXPECT_EQ(field.size(), 0); - // Additional 8 bytes are for 'struct Rep' header. - int expected_usage = 4 * sizeof(int) + 8; + // Additional bytes are for 'struct Rep' header. + int expected_usage = 4 * sizeof(int) + sizeof(Arena*); EXPECT_EQ(field.SpaceUsedExcludingSelf(), expected_usage); } diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h index c0cfd414..c3f735a2 100644 --- a/src/google/protobuf/stubs/common.h +++ b/src/google/protobuf/stubs/common.h @@ -113,24 +113,24 @@ namespace internal { // The current version, represented as a single integer to make comparison // easier: major * 10^6 + minor * 10^3 + micro -#define GOOGLE_PROTOBUF_VERSION 2006002 +#define GOOGLE_PROTOBUF_VERSION 3000000 // The minimum library version which works with the current version of the // headers. -#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 2006000 +#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 3000000 // The minimum header version which works with the current version of // the library. This constant should only be used by protoc's C++ code // generator. -static const int kMinHeaderVersionForLibrary = 2006000; +static const int kMinHeaderVersionForLibrary = 3000000; // The minimum protoc version which works with the current version of the // headers. -#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 2006000 +#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 3000000 // The minimum header version which works with the current version of // protoc. This constant should only be used in VerifyVersion(). -static const int kMinHeaderVersionForProtoc = 2006000; +static const int kMinHeaderVersionForProtoc = 3000000; // Verifies that the headers and libraries are compatible. Use the macro // below to call this. @@ -314,6 +314,12 @@ inline void GOOGLE_UNALIGNED_STORE64(void *p, uint64 v) { } #endif +#if defined(_MSC_VER) +#define GOOGLE_THREAD_LOCAL __declspec(thread) +#else +#define GOOGLE_THREAD_LOCAL __thread +#endif + // =================================================================== // from google3/base/basictypes.h diff --git a/src/google/protobuf/stubs/fastmem.h b/src/google/protobuf/stubs/fastmem.h index e553f142..763a6e60 100644 --- a/src/google/protobuf/stubs/fastmem.h +++ b/src/google/protobuf/stubs/fastmem.h @@ -46,7 +46,6 @@ #define GOOGLE_PROTOBUF_STUBS_FASTMEM_H_ #include <stddef.h> -#include <stdint.h> #include <stdio.h> #include <string.h> diff --git a/src/google/protobuf/stubs/type_traits.h b/src/google/protobuf/stubs/type_traits.h index f5365c38..b58cae3f 100644 --- a/src/google/protobuf/stubs/type_traits.h +++ b/src/google/protobuf/stubs/type_traits.h @@ -103,7 +103,7 @@ template <class T> struct remove_reference; template <class T> struct add_reference; template <class T> struct remove_pointer; template <class T, class U> struct is_same; -#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) +#if !(defined(__GNUC__) && __GNUC__ <= 3) template <class From, class To> struct is_convertible; #endif @@ -322,7 +322,7 @@ template<typename T, typename U> struct is_same : public false_type { }; template<typename T> struct is_same<T, T> : public true_type { }; // Specified by TR1 [4.6] Relationships between types -#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) +#if !(defined(__GNUC__) && __GNUC__ <= 3) namespace type_traits_internal { // This class is an implementation detail for is_convertible, and you @@ -339,6 +339,9 @@ struct ConvertHelper { static small_ Test(To); static big_ Test(...); static From Create(); + enum { + value = sizeof(Test(Create())) == sizeof(small_) + }; }; } // namespace type_traits_internal @@ -346,9 +349,7 @@ struct ConvertHelper { template <typename From, typename To> struct is_convertible : integral_constant<bool, - sizeof(type_traits_internal::ConvertHelper<From, To>::Test( - type_traits_internal::ConvertHelper<From, To>::Create())) - == sizeof(small_)> { + type_traits_internal::ConvertHelper<From, To>::value> { }; #endif diff --git a/src/google/protobuf/stubs/type_traits_unittest.cc b/src/google/protobuf/stubs/type_traits_unittest.cc index b42b9e83..49c10ace 100644 --- a/src/google/protobuf/stubs/type_traits_unittest.cc +++ b/src/google/protobuf/stubs/type_traits_unittest.cc @@ -610,7 +610,7 @@ TEST(TypeTraitsTest, TestIsSame) { } TEST(TypeTraitsTest, TestConvertible) { -#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) +#if !(defined(__GNUC__) && __GNUC__ <= 3) EXPECT_TRUE((is_convertible<int, int>::value)); EXPECT_TRUE((is_convertible<int, long>::value)); EXPECT_TRUE((is_convertible<long, int>::value)); diff --git a/src/google/protobuf/unknown_field_set_unittest.cc b/src/google/protobuf/unknown_field_set_unittest.cc index 6bba8fc7..9b02f0b0 100644 --- a/src/google/protobuf/unknown_field_set_unittest.cc +++ b/src/google/protobuf/unknown_field_set_unittest.cc @@ -485,7 +485,7 @@ TEST_F(UnknownFieldSetTest, UnknownEnumValue) { TEST_F(UnknownFieldSetTest, SpaceUsedExcludingSelf) { UnknownFieldSet empty; empty.AddVarint(1, 0); - EXPECT_EQ(/* vector<UnknownField> */ 24 + /* sizeof(UnknownField) */ 16, + EXPECT_EQ(sizeof(vector<UnknownField>) + sizeof(UnknownField), empty.SpaceUsedExcludingSelf()); } |