From 5a76e633ea9b5adb215e93fdc11e1c0c08b3fc74 Mon Sep 17 00:00:00 2001 From: Adam Cozzette Date: Thu, 17 Nov 2016 16:48:38 -0800 Subject: Integrated internal changes from Google --- src/google/protobuf/dynamic_message.cc | 96 +++++++++++++++++++++------------- 1 file changed, 59 insertions(+), 37 deletions(-) (limited to 'src/google/protobuf/dynamic_message.cc') diff --git a/src/google/protobuf/dynamic_message.cc b/src/google/protobuf/dynamic_message.cc index f51bc9d6..d686e01e 100644 --- a/src/google/protobuf/dynamic_message.cc +++ b/src/google/protobuf/dynamic_message.cc @@ -88,11 +88,11 @@ namespace google { namespace protobuf { -using internal::WireFormat; +using internal::DynamicMapField; using internal::ExtensionSet; using internal::GeneratedMessageReflection; +using internal::InternalMetadataWithArena; using internal::MapField; -using internal::DynamicMapField; using internal::ArenaStringPtr; @@ -221,7 +221,7 @@ class DynamicMessage : public Message { int size; int has_bits_offset; int oneof_case_offset; - int unknown_fields_offset; + int internal_metadata_offset; int extensions_offset; // Not owned by the TypeInfo. @@ -231,7 +231,8 @@ class DynamicMessage : public Message { // Warning: The order in which the following pointers are defined is // important (the prototype must be deleted *before* the offsets). - google::protobuf::scoped_array offsets; + google::protobuf::scoped_array offsets; + google::protobuf::scoped_array has_bits_indices; google::protobuf::scoped_ptr reflection; // Don't use a scoped_ptr to hold the prototype: the destructor for // DynamicMessage needs to know whether it is the prototype, and does so by @@ -327,14 +328,15 @@ void DynamicMessage::SharedCtor() { // Initialize oneof cases. for (int i = 0 ; i < descriptor->oneof_decl_count(); ++i) { - new(OffsetToPointer(type_info_->oneof_case_offset + sizeof(uint32) * i)) + new (OffsetToPointer(type_info_->oneof_case_offset + sizeof(uint32) * i)) uint32(0); } - new(OffsetToPointer(type_info_->unknown_fields_offset)) UnknownFieldSet; + new (OffsetToPointer(type_info_->internal_metadata_offset)) + InternalMetadataWithArena; if (type_info_->extensions_offset != -1) { - new(OffsetToPointer(type_info_->extensions_offset)) ExtensionSet; + new (OffsetToPointer(type_info_->extensions_offset)) ExtensionSet; } for (int i = 0; i < descriptor->field_count(); i++) { @@ -379,10 +381,10 @@ void DynamicMessage::SharedCtor() { if (is_prototype()) { default_value = &field->default_value_string(); } else { - default_value = - &(reinterpret_cast( - type_info_->prototype->OffsetToPointer( - type_info_->offsets[i]))->Get(NULL)); + default_value = &(reinterpret_cast( + type_info_->prototype->OffsetToPointer( + type_info_->offsets[i])) + ->Get()); } ArenaStringPtr* asp = new(field_ptr) ArenaStringPtr(); asp->UnsafeSetDefault(default_value); @@ -413,8 +415,9 @@ void DynamicMessage::SharedCtor() { DynamicMessage::~DynamicMessage() { const Descriptor* descriptor = type_info_->type; - reinterpret_cast( - OffsetToPointer(type_info_->unknown_fields_offset))->~UnknownFieldSet(); + reinterpret_cast( + OffsetToPointer(type_info_->internal_metadata_offset)) + ->~InternalMetadataWithArena(); if (type_info_->extensions_offset != -1) { reinterpret_cast( @@ -445,10 +448,10 @@ DynamicMessage::~DynamicMessage() { case FieldOptions::STRING: { const ::std::string* default_value = &(reinterpret_cast( - reinterpret_cast( - type_info_->default_oneof_instance) - + type_info_->offsets[i]) - ->Get(NULL)); + reinterpret_cast( + type_info_->default_oneof_instance) + + type_info_->offsets[i]) + ->Get()); reinterpret_cast(field_ptr)->Destroy( default_value, NULL); break; @@ -506,8 +509,9 @@ DynamicMessage::~DynamicMessage() { case FieldOptions::STRING: { const ::std::string* default_value = &(reinterpret_cast( - type_info_->prototype->OffsetToPointer( - type_info_->offsets[i]))->Get(NULL)); + type_info_->prototype->OffsetToPointer( + type_info_->offsets[i])) + ->Get()); reinterpret_cast(field_ptr)->Destroy( default_value, NULL); break; @@ -649,7 +653,8 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( // or not that field is set. // Compute size and offsets. - int* offsets = new int[type->field_count() + type->oneof_decl_count()]; + uint32* offsets = + new uint32[type->field_count() + type->oneof_decl_count()]; type_info->offsets.reset(offsets); // Decide all field offsets by packing in order. @@ -667,6 +672,12 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( DivideRoundingUp(type->field_count(), bitsizeof(uint32)); size += has_bits_array_size * sizeof(uint32); size = AlignOffset(size); + + uint32* has_bits_indices = new uint32[type->field_count()]; + for (int i = 0; i < type->field_count(); i++) { + has_bits_indices[i] = i; + } + type_info->has_bits_indices.reset(has_bits_indices); } // The oneof_case, if any. It is an array of uint32s. @@ -687,6 +698,8 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( } // All the fields. + // + // TODO(b/31226269): Optimize the order of fields to minimize padding. for (int i = 0; i < type->field_count(); i++) { // Make sure field is aligned to avoid bus errors. // Oneof fields do not use any space. @@ -705,10 +718,10 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( size += kMaxOneofUnionSize; } - // Add the UnknownFieldSet to the end. + // Add the InternalMetadataWithArena to the end. size = AlignOffset(size); - type_info->unknown_fields_offset = size; - size += sizeof(UnknownFieldSet); + type_info->internal_metadata_offset = size; + size += sizeof(InternalMetadataWithArena); // Align the final size to make sure no clever allocators think that // alignment is not necessary. @@ -728,6 +741,10 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( DynamicMessage* prototype = new(base) DynamicMessage(type_info); // Construct the reflection object. + + void* default_oneof_instance = NULL; + int oneof_case_offset = -1; + if (type->oneof_decl_count() > 0) { // Compute the size of default oneof instance and offsets of default // oneof fields. @@ -746,19 +763,24 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( ConstructDefaultOneofInstance(type_info->type, type_info->offsets.get(), type_info->default_oneof_instance); - type_info->reflection.reset(new GeneratedMessageReflection( - type_info->type, type_info->prototype, type_info->offsets.get(), - type_info->has_bits_offset, type_info->unknown_fields_offset, - type_info->extensions_offset, type_info->default_oneof_instance, - type_info->oneof_case_offset, type_info->pool, this, type_info->size, - -1 /* arena_offset */)); - } else { - type_info->reflection.reset(new GeneratedMessageReflection( - type_info->type, type_info->prototype, type_info->offsets.get(), - type_info->has_bits_offset, type_info->unknown_fields_offset, - type_info->extensions_offset, type_info->pool, this, type_info->size, - -1 /* arena_offset */)); + default_oneof_instance = type_info->default_oneof_instance; + oneof_case_offset = type_info->oneof_case_offset; } + + internal::ReflectionSchema schema = { + type_info->prototype, + type_info->offsets.get(), + type_info->has_bits_indices.get(), + type_info->has_bits_offset, + type_info->internal_metadata_offset, + type_info->extensions_offset, + default_oneof_instance, + oneof_case_offset, + type_info->size}; + + type_info->reflection.reset(new GeneratedMessageReflection( + type_info->type, schema, type_info->pool, this)); + // Cross link prototypes. prototype->CrossLinkPrototypes(); @@ -767,7 +789,7 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( void DynamicMessageFactory::ConstructDefaultOneofInstance( const Descriptor* type, - const int offsets[], + const uint32 offsets[], void* default_oneof_instance) { for (int i = 0; i < type->oneof_decl_count(); i++) { for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) { @@ -813,7 +835,7 @@ void DynamicMessageFactory::ConstructDefaultOneofInstance( void DynamicMessageFactory::DeleteDefaultOneofInstance( const Descriptor* type, - const int offsets[], + const uint32 offsets[], void* default_oneof_instance) { for (int i = 0; i < type->oneof_decl_count(); i++) { for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) { -- cgit v1.2.3