diff options
Diffstat (limited to 'src/google/protobuf/dynamic_message.cc')
-rw-r--r-- | src/google/protobuf/dynamic_message.cc | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/src/google/protobuf/dynamic_message.cc b/src/google/protobuf/dynamic_message.cc index d6bde495..ee8113e3 100644 --- a/src/google/protobuf/dynamic_message.cc +++ b/src/google/protobuf/dynamic_message.cc @@ -77,13 +77,14 @@ #include <google/protobuf/generated_message_util.h> #include <google/protobuf/generated_message_reflection.h> #include <google/protobuf/arenastring.h> +#include <google/protobuf/extension_set.h> +#include <google/protobuf/map_field.h> #include <google/protobuf/map_field_inl.h> +#include <google/protobuf/map_type_handler.h> #include <google/protobuf/reflection_ops.h> #include <google/protobuf/repeated_field.h> -#include <google/protobuf/map_type_handler.h> -#include <google/protobuf/extension_set.h> #include <google/protobuf/wire_format.h> -#include <google/protobuf/map_field.h> + namespace google { namespace protobuf { @@ -239,6 +240,7 @@ class DynamicMessage : public Message { // looking back at this field. This would assume details about the // implementation of scoped_ptr. const DynamicMessage* prototype; + int weak_field_map_offset; // The offset for the weak_field_map; TypeInfo() : prototype(NULL) {} @@ -323,7 +325,6 @@ void DynamicMessage::SharedCtor() { // constructor.) const Descriptor* descriptor = type_info_->type; - // Initialize oneof cases. for (int i = 0 ; i < descriptor->oneof_decl_count(); ++i) { new (OffsetToPointer(type_info_->oneof_case_offset + sizeof(uint32) * i)) @@ -336,7 +337,6 @@ void DynamicMessage::SharedCtor() { if (type_info_->extensions_offset != -1) { new (OffsetToPointer(type_info_->extensions_offset)) ExtensionSet; } - for (int i = 0; i < descriptor->field_count(); i++) { const FieldDescriptor* field = descriptor->field(i); void* field_ptr = OffsetToPointer(type_info_->offsets[i]); @@ -537,7 +537,6 @@ void DynamicMessage::CrossLinkPrototypes() { for (int i = 0; i < descriptor->field_count(); i++) { const FieldDescriptor* field = descriptor->field(i); void* field_ptr = OffsetToPointer(type_info_->offsets[i]); - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && !field->is_repeated()) { // For fields with message types, we need to cross-link with the @@ -694,6 +693,7 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( // All the fields. // // TODO(b/31226269): Optimize the order of fields to minimize padding. + int num_weak_fields = 0; 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. @@ -717,6 +717,8 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( type_info->internal_metadata_offset = size; size += sizeof(InternalMetadataWithArena); + type_info->weak_field_map_offset = -1; + // Align the final size to make sure no clever allocators think that // alignment is not necessary. type_info->size = size; @@ -738,7 +740,6 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( } } size = AlignOffset(size); - // Allocate the prototype + oneof fields. void* base = operator new(size); memset(base, 0, size); @@ -752,7 +753,7 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( type_info->prototype = static_cast<DynamicMessage*>(base); DynamicMessage* prototype = new(base) DynamicMessage(type_info); - if (type->oneof_decl_count() > 0) { + if (type->oneof_decl_count() > 0 || num_weak_fields > 0) { // Construct default oneof instance. ConstructDefaultOneofInstance(type_info->type, type_info->offsets.get(), @@ -767,7 +768,8 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( type_info->internal_metadata_offset, type_info->extensions_offset, type_info->oneof_case_offset, - type_info->size}; + type_info->size, + type_info->weak_field_map_offset}; type_info->reflection.reset(new GeneratedMessageReflection( type_info->type, schema, type_info->pool, this)); @@ -781,12 +783,12 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( void DynamicMessageFactory::ConstructDefaultOneofInstance( const Descriptor* type, const uint32 offsets[], - void* default_oneof_instance) { + void* default_oneof_or_weak_instance) { for (int i = 0; i < type->oneof_decl_count(); i++) { for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) { const FieldDescriptor* field = type->oneof_decl(i)->field(j); void* field_ptr = reinterpret_cast<uint8*>( - default_oneof_instance) + offsets[field->index()]; + default_oneof_or_weak_instance) + offsets[field->index()]; switch (field->cpp_type()) { #define HANDLE_TYPE(CPPTYPE, TYPE) \ case FieldDescriptor::CPPTYPE_##CPPTYPE: \ |