aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/google/protobuf/dynamic_message.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/google/protobuf/dynamic_message.cc')
-rw-r--r--src/google/protobuf/dynamic_message.cc96
1 files changed, 59 insertions, 37 deletions
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<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
@@ -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<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);
@@ -413,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*>(
@@ -445,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;
@@ -506,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;
@@ -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++) {