Index: third_party/protobuf/src/google/protobuf/dynamic_message.cc |
diff --git a/third_party/protobuf/src/google/protobuf/dynamic_message.cc b/third_party/protobuf/src/google/protobuf/dynamic_message.cc |
index 9e83bd2918e4e828312026515a6b4c5ec4399856..d686e01e08eb059ba38301b34d2f4f1dc0b3655c 100644 |
--- a/third_party/protobuf/src/google/protobuf/dynamic_message.cc |
+++ b/third_party/protobuf/src/google/protobuf/dynamic_message.cc |
@@ -70,7 +70,6 @@ |
#endif |
#include <google/protobuf/stubs/common.h> |
-#include <google/protobuf/stubs/scoped_ptr.h> |
#include <google/protobuf/dynamic_message.h> |
#include <google/protobuf/descriptor.h> |
@@ -89,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; |
@@ -222,9 +221,8 @@ 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; |
- int is_default_instance_offset; |
// Not owned by the TypeInfo. |
DynamicMessageFactory* factory; // The factory that created this object. |
@@ -233,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<int> offsets; |
+ google::protobuf::scoped_array<uint32> offsets; |
+ google::protobuf::scoped_array<uint32> has_bits_indices; |
google::protobuf::scoped_ptr<const GeneratedMessageReflection> 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 |
@@ -329,19 +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); |
} |
- if (type_info_->is_default_instance_offset != -1) { |
- *reinterpret_cast<bool*>( |
- OffsetToPointer(type_info_->is_default_instance_offset)) = false; |
- } |
- |
- 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++) { |
@@ -386,10 +381,10 @@ void DynamicMessage::SharedCtor() { |
if (is_prototype()) { |
default_value = &field->default_value_string(); |
} else { |
- default_value = |
- &(reinterpret_cast<const ArenaStringPtr*>( |
- type_info_->prototype->OffsetToPointer( |
- type_info_->offsets[i]))->Get(NULL)); |
+ default_value = &(reinterpret_cast<const ArenaStringPtr*>( |
+ type_info_->prototype->OffsetToPointer( |
+ type_info_->offsets[i])) |
+ ->Get()); |
} |
ArenaStringPtr* asp = new(field_ptr) ArenaStringPtr(); |
asp->UnsafeSetDefault(default_value); |
@@ -420,8 +415,9 @@ void DynamicMessage::SharedCtor() { |
DynamicMessage::~DynamicMessage() { |
const Descriptor* descriptor = type_info_->type; |
- reinterpret_cast<UnknownFieldSet*>( |
- OffsetToPointer(type_info_->unknown_fields_offset))->~UnknownFieldSet(); |
+ reinterpret_cast<InternalMetadataWithArena*>( |
+ OffsetToPointer(type_info_->internal_metadata_offset)) |
+ ->~InternalMetadataWithArena(); |
if (type_info_->extensions_offset != -1) { |
reinterpret_cast<ExtensionSet*>( |
@@ -452,10 +448,10 @@ DynamicMessage::~DynamicMessage() { |
case FieldOptions::STRING: { |
const ::std::string* default_value = |
&(reinterpret_cast<const ArenaStringPtr*>( |
- reinterpret_cast<uint8*>( |
- type_info_->default_oneof_instance) |
- + type_info_->offsets[i]) |
- ->Get(NULL)); |
+ reinterpret_cast<uint8*>( |
+ type_info_->default_oneof_instance) + |
+ type_info_->offsets[i]) |
+ ->Get()); |
reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy( |
default_value, NULL); |
break; |
@@ -513,8 +509,9 @@ DynamicMessage::~DynamicMessage() { |
case FieldOptions::STRING: { |
const ::std::string* default_value = |
&(reinterpret_cast<const ArenaStringPtr*>( |
- type_info_->prototype->OffsetToPointer( |
- type_info_->offsets[i]))->Get(NULL)); |
+ type_info_->prototype->OffsetToPointer( |
+ type_info_->offsets[i])) |
+ ->Get()); |
reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy( |
default_value, NULL); |
break; |
@@ -557,14 +554,6 @@ void DynamicMessage::CrossLinkPrototypes() { |
factory->GetPrototypeNoLock(field->message_type()); |
} |
} |
- |
- // Set as the default instance -- this affects field-presence semantics for |
- // proto3. |
- if (type_info_->is_default_instance_offset != -1) { |
- void* is_default_instance_ptr = |
- OffsetToPointer(type_info_->is_default_instance_offset); |
- *reinterpret_cast<bool*>(is_default_instance_ptr) = true; |
- } |
} |
Message* DynamicMessage::New() const { |
@@ -664,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. |
@@ -682,15 +672,12 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( |
DivideRoundingUp(type->field_count(), bitsizeof(uint32)); |
size += has_bits_array_size * sizeof(uint32); |
size = AlignOffset(size); |
- } |
- // The is_default_instance member, if any. |
- if (type->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) { |
- type_info->is_default_instance_offset = size; |
- size += sizeof(bool); |
- size = AlignOffset(size); |
- } else { |
- type_info->is_default_instance_offset = -1; |
+ 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. |
@@ -711,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. |
@@ -729,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. |
@@ -752,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. |
@@ -770,36 +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 */, |
- type_info->is_default_instance_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 */, |
- type_info->is_default_instance_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(); |
@@ -808,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++) { |
@@ -854,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++) { |