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.cc24
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: \