Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(112)

Unified Diff: third_party/protobuf/src/google/protobuf/dynamic_message.cc

Issue 1322483002: Revert https://codereview.chromium.org/1291903002 (protobuf roll). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 318ce6f9fb6a8c3a75c9ff3d99a7aec731b6fc95..09bec54363aa2eba3004ea0ea6b6e11f67b3d780 100644
--- a/third_party/protobuf/src/google/protobuf/dynamic_message.cc
+++ b/third_party/protobuf/src/google/protobuf/dynamic_message.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
+// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -72,11 +72,8 @@
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/generated_message_reflection.h>
-#include <google/protobuf/arenastring.h>
-#include <google/protobuf/map_field_inl.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>
@@ -86,21 +83,13 @@ namespace protobuf {
using internal::WireFormat;
using internal::ExtensionSet;
using internal::GeneratedMessageReflection;
-using internal::MapField;
-using internal::MapFieldBase;
-using internal::ArenaStringPtr;
-
// ===================================================================
// Some helper tables and functions...
namespace {
-bool IsMapFieldInApi(const FieldDescriptor* field) {
- return field->is_map();
-}
-
// Compute the byte size of the in-memory representation of the field.
int FieldSpaceUsed(const FieldDescriptor* field) {
typedef FieldDescriptor FD; // avoid line wrapping
@@ -114,12 +103,7 @@ int FieldSpaceUsed(const FieldDescriptor* field) {
case FD::CPPTYPE_FLOAT : return sizeof(RepeatedField<float >);
case FD::CPPTYPE_BOOL : return sizeof(RepeatedField<bool >);
case FD::CPPTYPE_ENUM : return sizeof(RepeatedField<int >);
- case FD::CPPTYPE_MESSAGE:
- if (IsMapFieldInApi(field)) {
- return sizeof(MapFieldBase);
- } else {
- return sizeof(RepeatedPtrField<Message>);
- }
+ case FD::CPPTYPE_MESSAGE: return sizeof(RepeatedPtrField<Message>);
case FD::CPPTYPE_STRING:
switch (field->options().ctype()) {
@@ -147,7 +131,7 @@ int FieldSpaceUsed(const FieldDescriptor* field) {
switch (field->options().ctype()) {
default: // TODO(kenton): Support other string reps.
case FieldOptions::STRING:
- return sizeof(ArenaStringPtr);
+ return sizeof(string*);
}
break;
}
@@ -157,42 +141,11 @@ int FieldSpaceUsed(const FieldDescriptor* field) {
return 0;
}
-// Compute the byte size of in-memory representation of the oneof fields
-// in default oneof instance.
-int OneofFieldSpaceUsed(const FieldDescriptor* field) {
- typedef FieldDescriptor FD; // avoid line wrapping
- switch (field->cpp_type()) {
- case FD::CPPTYPE_INT32 : return sizeof(int32 );
- case FD::CPPTYPE_INT64 : return sizeof(int64 );
- case FD::CPPTYPE_UINT32 : return sizeof(uint32 );
- case FD::CPPTYPE_UINT64 : return sizeof(uint64 );
- case FD::CPPTYPE_DOUBLE : return sizeof(double );
- case FD::CPPTYPE_FLOAT : return sizeof(float );
- case FD::CPPTYPE_BOOL : return sizeof(bool );
- case FD::CPPTYPE_ENUM : return sizeof(int );
-
- case FD::CPPTYPE_MESSAGE:
- return sizeof(Message*);
-
- case FD::CPPTYPE_STRING:
- switch (field->options().ctype()) {
- default:
- case FieldOptions::STRING:
- return sizeof(ArenaStringPtr);
- }
- break;
- }
-
- GOOGLE_LOG(DFATAL) << "Can't get here.";
- return 0;
-}
-
inline int DivideRoundingUp(int i, int j) {
return (i + (j - 1)) / j;
}
static const int kSafeAlignment = sizeof(uint64);
-static const int kMaxOneofUnionSize = sizeof(uint64);
inline int AlignTo(int offset, int alignment) {
return DivideRoundingUp(offset, alignment) * alignment;
@@ -215,10 +168,8 @@ class DynamicMessage : public Message {
struct TypeInfo {
int size;
int has_bits_offset;
- int oneof_case_offset;
int unknown_fields_offset;
int extensions_offset;
- int is_default_instance_offset;
// Not owned by the TypeInfo.
DynamicMessageFactory* factory; // The factory that created this object.
@@ -234,13 +185,11 @@ class DynamicMessage : public Message {
// looking back at this field. This would assume details about the
// implementation of scoped_ptr.
const DynamicMessage* prototype;
- void* default_oneof_instance;
- TypeInfo() : prototype(NULL), default_oneof_instance(NULL) {}
+ TypeInfo() : prototype(NULL) {}
~TypeInfo() {
delete prototype;
- operator delete(default_oneof_instance);
}
};
@@ -253,19 +202,14 @@ class DynamicMessage : public Message {
// implements Message ----------------------------------------------
Message* New() const;
- Message* New(::google::protobuf::Arena* arena) const;
- ::google::protobuf::Arena* GetArena() const { return NULL; };
int GetCachedSize() const;
void SetCachedSize(int size) const;
Metadata GetMetadata() const;
-
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessage);
- DynamicMessage(const TypeInfo* type_info, ::google::protobuf::Arena* arena);
- void SharedCtor();
inline bool is_prototype() const {
return type_info_->prototype == this ||
@@ -282,6 +226,7 @@ class DynamicMessage : public Message {
}
const TypeInfo* type_info_;
+
// TODO(kenton): Make this an atomic<int> when C++ supports it.
mutable int cached_byte_size_;
};
@@ -289,17 +234,6 @@ class DynamicMessage : public Message {
DynamicMessage::DynamicMessage(const TypeInfo* type_info)
: type_info_(type_info),
cached_byte_size_(0) {
- SharedCtor();
-}
-
-DynamicMessage::DynamicMessage(const TypeInfo* type_info,
- ::google::protobuf::Arena* arena)
- : type_info_(type_info),
- cached_byte_size_(0) {
- SharedCtor();
-}
-
-void DynamicMessage::SharedCtor() {
// We need to call constructors for various fields manually and set
// default values where appropriate. We use placement new to call
// constructors. If you haven't heard of placement new, I suggest Googling
@@ -311,17 +245,6 @@ void DynamicMessage::SharedCtor() {
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))
- 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;
if (type_info_->extensions_offset != -1) {
@@ -331,9 +254,6 @@ void DynamicMessage::SharedCtor() {
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->containing_oneof()) {
- continue;
- }
switch (field->cpp_type()) {
#define HANDLE_TYPE(CPPTYPE, TYPE) \
case FieldDescriptor::CPPTYPE_##CPPTYPE: \
@@ -366,17 +286,15 @@ void DynamicMessage::SharedCtor() {
default: // TODO(kenton): Support other string reps.
case FieldOptions::STRING:
if (!field->is_repeated()) {
- const string* default_value;
if (is_prototype()) {
- default_value = &field->default_value_string();
+ new(field_ptr) const string*(&field->default_value_string());
} else {
- default_value =
- &(reinterpret_cast<const ArenaStringPtr*>(
+ string* default_value =
+ *reinterpret_cast<string* const*>(
type_info_->prototype->OffsetToPointer(
- type_info_->offsets[i]))->Get(NULL));
+ type_info_->offsets[i]));
+ new(field_ptr) string*(default_value);
}
- ArenaStringPtr* asp = new(field_ptr) ArenaStringPtr();
- asp->UnsafeSetDefault(default_value);
} else {
new(field_ptr) RepeatedPtrField<string>();
}
@@ -388,11 +306,7 @@ void DynamicMessage::SharedCtor() {
if (!field->is_repeated()) {
new(field_ptr) Message*(NULL);
} else {
- if (IsMapFieldInApi(field)) {
- new (field_ptr) MapFieldBase();
- } else {
- new (field_ptr) RepeatedPtrField<Message>();
- }
+ new(field_ptr) RepeatedPtrField<Message>();
}
break;
}
@@ -413,41 +327,12 @@ DynamicMessage::~DynamicMessage() {
// We need to manually run the destructors for repeated fields and strings,
// just as we ran their constructors in the the DynamicMessage constructor.
- // We also need to manually delete oneof fields if it is set and is string
- // or message.
// Additionally, if any singular embedded messages have been allocated, we
// need to delete them, UNLESS we are the prototype message of this type,
// in which case any embedded messages are other prototypes and shouldn't
// be touched.
for (int i = 0; i < descriptor->field_count(); i++) {
const FieldDescriptor* field = descriptor->field(i);
- if (field->containing_oneof()) {
- void* field_ptr = OffsetToPointer(
- type_info_->oneof_case_offset
- + sizeof(uint32) * field->containing_oneof()->index());
- if (*(reinterpret_cast<const uint32*>(field_ptr)) ==
- field->number()) {
- field_ptr = OffsetToPointer(type_info_->offsets[
- descriptor->field_count() + field->containing_oneof()->index()]);
- if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
- switch (field->options().ctype()) {
- default:
- case FieldOptions::STRING: {
- const ::std::string* default_value =
- &(reinterpret_cast<const ArenaStringPtr*>(
- type_info_->prototype->OffsetToPointer(
- type_info_->offsets[i]))->Get(NULL));
- reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy(default_value,
- NULL);
- break;
- }
- }
- } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
- delete *reinterpret_cast<Message**>(field_ptr);
- }
- }
- continue;
- }
void* field_ptr = OffsetToPointer(type_info_->offsets[i]);
if (field->is_repeated()) {
@@ -479,12 +364,8 @@ DynamicMessage::~DynamicMessage() {
break;
case FieldDescriptor::CPPTYPE_MESSAGE:
- if (IsMapFieldInApi(field)) {
- reinterpret_cast<MapFieldBase*>(field_ptr)->~MapFieldBase();
- } else {
- reinterpret_cast<RepeatedPtrField<Message>*>(field_ptr)
- ->~RepeatedPtrField<Message>();
- }
+ reinterpret_cast<RepeatedPtrField<Message>*>(field_ptr)
+ ->~RepeatedPtrField<Message>();
break;
}
@@ -492,12 +373,10 @@ DynamicMessage::~DynamicMessage() {
switch (field->options().ctype()) {
default: // TODO(kenton): Support other string reps.
case FieldOptions::STRING: {
- const ::std::string* default_value =
- &(reinterpret_cast<const ArenaStringPtr*>(
- type_info_->prototype->OffsetToPointer(
- type_info_->offsets[i]))->Get(NULL));
- reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy(default_value,
- NULL);
+ string* ptr = *reinterpret_cast<string**>(field_ptr);
+ if (ptr != &field->default_value_string()) {
+ delete ptr;
+ }
break;
}
}
@@ -523,10 +402,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->containing_oneof()) {
- field_ptr = reinterpret_cast<uint8*>(
- type_info_->default_oneof_instance) + type_info_->offsets[i];
- }
if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
!field->is_repeated()) {
@@ -538,14 +413,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 {
@@ -554,16 +421,6 @@ Message* DynamicMessage::New() const {
return new(new_base) DynamicMessage(type_info_);
}
-Message* DynamicMessage::New(::google::protobuf::Arena* arena) const {
- if (arena != NULL) {
- Message* message = New();
- arena->Own(message);
- return message;
- } else {
- return New();
- }
-}
-
int DynamicMessage::GetCachedSize() const {
return cached_byte_size_;
}
@@ -572,9 +429,7 @@ void DynamicMessage::SetCachedSize(int size) const {
// This is theoretically not thread-compatible, but in practice it works
// because if multiple threads write this simultaneously, they will be
// writing the exact same value.
- GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
cached_byte_size_ = size;
- GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
Metadata DynamicMessage::GetMetadata() const {
@@ -604,9 +459,6 @@ DynamicMessageFactory::DynamicMessageFactory(const DescriptorPool* pool)
DynamicMessageFactory::~DynamicMessageFactory() {
for (PrototypeMap::Map::iterator iter = prototypes_->map_.begin();
iter != prototypes_->map_.end(); ++iter) {
- DeleteDefaultOneofInstance(iter->second->type,
- iter->second->offsets.get(),
- iter->second->default_oneof_instance);
delete iter->second;
}
}
@@ -645,7 +497,7 @@ 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()];
+ int* offsets = new int[type->field_count()];
type_info->offsets.reset(offsets);
// Decide all field offsets by packing in order.
@@ -655,31 +507,11 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock(
size = AlignOffset(size);
// Next the has_bits, which is an array of uint32s.
- if (type->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) {
- type_info->has_bits_offset = -1;
- } else {
- type_info->has_bits_offset = size;
- int has_bits_array_size =
- 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;
- }
-
- // The oneof_case, if any. It is an array of uint32s.
- if (type->oneof_decl_count() > 0) {
- type_info->oneof_case_offset = size;
- size += type->oneof_decl_count() * sizeof(uint32);
- size = AlignOffset(size);
- }
+ type_info->has_bits_offset = size;
+ int has_bits_array_size =
+ DivideRoundingUp(type->field_count(), bitsizeof(uint32));
+ size += has_bits_array_size * sizeof(uint32);
+ size = AlignOffset(size);
// The ExtensionSet, if any.
if (type->extension_range_count() > 0) {
@@ -694,20 +526,10 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock(
// All the fields.
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.
- if (!type->field(i)->containing_oneof()) {
- int field_size = FieldSpaceUsed(type->field(i));
- size = AlignTo(size, min(kSafeAlignment, field_size));
- offsets[i] = size;
- size += field_size;
- }
- }
-
- // The oneofs.
- for (int i = 0; i < type->oneof_decl_count(); i++) {
- size = AlignTo(size, kSafeAlignment);
- offsets[type->field_count() + i] = size;
- size += kMaxOneofUnionSize;
+ int field_size = FieldSpaceUsed(type->field(i));
+ size = AlignTo(size, min(kSafeAlignment, field_size));
+ offsets[i] = size;
+ size += field_size;
}
// Add the UnknownFieldSet to the end.
@@ -727,123 +549,23 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock(
type_info->prototype = prototype;
// Construct the reflection object.
- if (type->oneof_decl_count() > 0) {
- // Compute the size of default oneof instance and offsets of default
- // oneof fields.
- int oneof_size = 0;
- 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);
- int field_size = OneofFieldSpaceUsed(field);
- oneof_size = AlignTo(oneof_size, min(kSafeAlignment, field_size));
- offsets[field->index()] = oneof_size;
- oneof_size += field_size;
- }
- }
- // Construct default oneof instance.
- type_info->default_oneof_instance = ::operator new(oneof_size);
- 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));
- }
+ 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));
+
// Cross link prototypes.
prototype->CrossLinkPrototypes();
return prototype;
}
-void DynamicMessageFactory::ConstructDefaultOneofInstance(
- const Descriptor* type,
- const int 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++) {
- const FieldDescriptor* field = type->oneof_decl(i)->field(j);
- void* field_ptr = reinterpret_cast<uint8*>(
- default_oneof_instance) + offsets[field->index()];
- switch (field->cpp_type()) {
-#define HANDLE_TYPE(CPPTYPE, TYPE) \
- case FieldDescriptor::CPPTYPE_##CPPTYPE: \
- new(field_ptr) TYPE(field->default_value_##TYPE()); \
- break;
-
- HANDLE_TYPE(INT32 , int32 );
- HANDLE_TYPE(INT64 , int64 );
- HANDLE_TYPE(UINT32, uint32);
- HANDLE_TYPE(UINT64, uint64);
- HANDLE_TYPE(DOUBLE, double);
- HANDLE_TYPE(FLOAT , float );
- HANDLE_TYPE(BOOL , bool );
-#undef HANDLE_TYPE
-
- case FieldDescriptor::CPPTYPE_ENUM:
- new(field_ptr) int(field->default_value_enum()->number());
- break;
- case FieldDescriptor::CPPTYPE_STRING:
- switch (field->options().ctype()) {
- default:
- case FieldOptions::STRING:
- ArenaStringPtr* asp = new (field_ptr) ArenaStringPtr();
- asp->UnsafeSetDefault(&field->default_value_string());
- break;
- }
- break;
-
- case FieldDescriptor::CPPTYPE_MESSAGE: {
- new(field_ptr) Message*(NULL);
- break;
- }
- }
- }
- }
-}
-
-void DynamicMessageFactory::DeleteDefaultOneofInstance(
- const Descriptor* type,
- const int 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++) {
- const FieldDescriptor* field = type->oneof_decl(i)->field(j);
- if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
- switch (field->options().ctype()) {
- default:
- case FieldOptions::STRING:
- break;
- }
- }
- }
- }
-}
-
} // namespace protobuf
} // namespace google

Powered by Google App Engine
This is Rietveld 408576698