Automated rollback of commit 6b22fd125c.

PiperOrigin-RevId: 676010627
pull/18377/head
Protobuf Team Bot 2 months ago committed by Copybara-Service
parent f6b9a4942e
commit a95043eefa
  1. 31
      src/google/protobuf/descriptor.cc
  2. 6
      src/google/protobuf/descriptor.h
  3. 34
      src/google/protobuf/generated_message_reflection.cc

@ -33,7 +33,6 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "absl/algorithm/container.h"
#include "absl/base/attributes.h" #include "absl/base/attributes.h"
#include "absl/base/call_once.h" #include "absl/base/call_once.h"
#include "absl/base/casts.h" #include "absl/base/casts.h"
@ -73,7 +72,6 @@
#include "google/protobuf/descriptor_visitor.h" #include "google/protobuf/descriptor_visitor.h"
#include "google/protobuf/dynamic_message.h" #include "google/protobuf/dynamic_message.h"
#include "google/protobuf/feature_resolver.h" #include "google/protobuf/feature_resolver.h"
#include "google/protobuf/generated_enum_util.h"
#include "google/protobuf/generated_message_util.h" #include "google/protobuf/generated_message_util.h"
#include "google/protobuf/io/strtod.h" #include "google/protobuf/io/strtod.h"
#include "google/protobuf/io/tokenizer.h" #include "google/protobuf/io/tokenizer.h"
@ -2587,33 +2585,6 @@ const FieldDescriptor* Descriptor::map_value() const {
return field(1); return field(1);
} }
const uint32_t* EnumDescriptor::GetValidatorData() const {
// We generate the data on demand to delay the memory usage until we actually
// need it.
if (auto* p = validator_data_.load(std::memory_order_acquire)) return p;
std::vector<int32_t> values;
for (const auto& v : absl::MakeSpan(values_, value_count_)) {
values.push_back(v.number());
}
absl::c_sort(values);
values.erase(std::unique(values.begin(), values.end()), values.end());
auto data = internal::GenerateEnumData(values);
absl::MutexLockMaybe lock(file_->pool_->mutex_);
// Do the check again under the mutex to avoid wasting memory in case someone
// raced us. The memory is held by the pool, so "leaking" it can add up.
// But we do the preparation work above to not put all of that under the lock.
if (auto* p = validator_data_.load(std::memory_order_acquire)) return p;
uint32_t* owned_data = static_cast<uint32_t*>(
file_->pool_->tables_->AllocateBytes(data.size() * sizeof(uint32_t)));
memcpy(owned_data, data.data(), data.size() * sizeof(uint32_t));
validator_data_.store(owned_data, std::memory_order_release);
return owned_data;
}
const EnumValueDescriptor* EnumDescriptor::FindValueByName( const EnumValueDescriptor* EnumDescriptor::FindValueByName(
absl::string_view name) const { absl::string_view name) const {
return file()->tables_->FindNestedSymbol(this, name).enum_value_descriptor(); return file()->tables_->FindNestedSymbol(this, name).enum_value_descriptor();
@ -5199,7 +5170,6 @@ Symbol DescriptorPool::NewPlaceholderWithMutexHeld(
placeholder_enum->merged_features_ = &FeatureSet::default_instance(); placeholder_enum->merged_features_ = &FeatureSet::default_instance();
placeholder_enum->is_placeholder_ = true; placeholder_enum->is_placeholder_ = true;
placeholder_enum->is_unqualified_placeholder_ = (name[0] != '.'); placeholder_enum->is_unqualified_placeholder_ = (name[0] != '.');
placeholder_enum->validator_data_.store(nullptr, std::memory_order_relaxed);
// Enums must have at least one value. // Enums must have at least one value.
placeholder_enum->value_count_ = 1; placeholder_enum->value_count_ = 1;
@ -7058,7 +7028,6 @@ void DescriptorBuilder::BuildEnum(const EnumDescriptorProto& proto,
result->containing_type_ = parent; result->containing_type_ = parent;
result->is_placeholder_ = false; result->is_placeholder_ = false;
result->is_unqualified_placeholder_ = false; result->is_unqualified_placeholder_ = false;
result->validator_data_.store(nullptr, std::memory_order_relaxed);
if (proto.value_size() == 0) { if (proto.value_size() == 0) {
// We cannot allow enums with no values because this would mean there // We cannot allow enums with no values because this would mean there

@ -1455,8 +1455,6 @@ class PROTOBUF_EXPORT EnumDescriptor : private internal::SymbolBase {
// to this descriptor from the file root. // to this descriptor from the file root.
void GetLocationPath(std::vector<int>* output) const; void GetLocationPath(std::vector<int>* output) const;
const uint32_t* GetValidatorData() const;
// True if this is a placeholder for an unknown type. // True if this is a placeholder for an unknown type.
bool is_placeholder_ : 1; bool is_placeholder_ : 1;
// True if this is a placeholder and the type name wasn't fully-qualified. // True if this is a placeholder and the type name wasn't fully-qualified.
@ -1487,8 +1485,6 @@ class PROTOBUF_EXPORT EnumDescriptor : private internal::SymbolBase {
EnumDescriptor::ReservedRange* reserved_ranges_; EnumDescriptor::ReservedRange* reserved_ranges_;
const std::string** reserved_names_; const std::string** reserved_names_;
mutable std::atomic<const uint32_t*> validator_data_;
// IMPORTANT: If you add a new field, make sure to search for all instances // IMPORTANT: If you add a new field, make sure to search for all instances
// of Allocate<EnumDescriptor>() and AllocateArray<EnumDescriptor>() in // of Allocate<EnumDescriptor>() and AllocateArray<EnumDescriptor>() in
// descriptor.cc and update them to initialize the field. // descriptor.cc and update them to initialize the field.
@ -1505,7 +1501,7 @@ class PROTOBUF_EXPORT EnumDescriptor : private internal::SymbolBase {
friend class Reflection; friend class Reflection;
}; };
PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(EnumDescriptor, 96); PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(EnumDescriptor, 88);
// Describes an individual enum constant of a particular type. To get the // Describes an individual enum constant of a particular type. To get the
// EnumValueDescriptor for a given enum value, first get the EnumDescriptor // EnumValueDescriptor for a given enum value, first get the EnumDescriptor

@ -3305,18 +3305,29 @@ void Reflection::PopulateTcParseEntries(
TcParseTableBase::FieldEntry* entries) const { TcParseTableBase::FieldEntry* entries) const {
for (const auto& entry : table_info.field_entries) { for (const auto& entry : table_info.field_entries) {
const FieldDescriptor* field = entry.field; const FieldDescriptor* field = entry.field;
const OneofDescriptor* oneof = field->real_containing_oneof(); if (field->type() == field->TYPE_ENUM &&
entries->offset = schema_.GetFieldOffset(field); (entry.type_card & internal::field_layout::kTvMask) ==
if (oneof != nullptr) { internal::field_layout::kTvEnum &&
entries->has_idx = schema_.oneof_case_offset_ + 4 * oneof->index(); table_info.aux_entries[entry.aux_idx].type ==
} else if (schema_.HasHasbits()) { internal::TailCallTableInfo::kEnumValidator) {
entries->has_idx = // Mini parse can't handle it. Fallback to reflection.
static_cast<int>(8 * schema_.HasBitsOffset() + entry.hasbit_idx); *entries = {};
table_info.aux_entries[entry.aux_idx] = {};
} else { } else {
entries->has_idx = 0; const OneofDescriptor* oneof = field->real_containing_oneof();
entries->offset = schema_.GetFieldOffset(field);
if (oneof != nullptr) {
entries->has_idx = schema_.oneof_case_offset_ + 4 * oneof->index();
} else if (schema_.HasHasbits()) {
entries->has_idx =
static_cast<int>(8 * schema_.HasBitsOffset() + entry.hasbit_idx);
} else {
entries->has_idx = 0;
}
entries->aux_idx = entry.aux_idx;
entries->type_card = entry.type_card;
} }
entries->aux_idx = entry.aux_idx;
entries->type_card = entry.type_card;
++entries; ++entries;
} }
} }
@ -3361,8 +3372,7 @@ void Reflection::PopulateTcParseFieldAux(
aux_entry.enum_range.size}; aux_entry.enum_range.size};
break; break;
case internal::TailCallTableInfo::kEnumValidator: case internal::TailCallTableInfo::kEnumValidator:
field_aux++->enum_data = ABSL_LOG(FATAL) << "Not supported.";
aux_entry.field->enum_type()->GetValidatorData();
break; break;
case internal::TailCallTableInfo::kNumericOffset: case internal::TailCallTableInfo::kNumericOffset:
field_aux++->offset = aux_entry.offset; field_aux++->offset = aux_entry.offset;

Loading…
Cancel
Save