diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc index 4ef1eeeadf..d0cf944d01 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc @@ -33,7 +33,6 @@ #include #include -#include "absl/algorithm/container.h" #include "absl/base/attributes.h" #include "absl/base/call_once.h" #include "absl/base/casts.h" @@ -73,7 +72,6 @@ #include "google/protobuf/descriptor_visitor.h" #include "google/protobuf/dynamic_message.h" #include "google/protobuf/feature_resolver.h" -#include "google/protobuf/generated_enum_util.h" #include "google/protobuf/generated_message_util.h" #include "google/protobuf/io/strtod.h" #include "google/protobuf/io/tokenizer.h" @@ -2587,33 +2585,6 @@ const FieldDescriptor* Descriptor::map_value() const { 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 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( - 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( absl::string_view name) const { 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->is_placeholder_ = true; placeholder_enum->is_unqualified_placeholder_ = (name[0] != '.'); - placeholder_enum->validator_data_.store(nullptr, std::memory_order_relaxed); // Enums must have at least one value. placeholder_enum->value_count_ = 1; @@ -7058,7 +7028,6 @@ void DescriptorBuilder::BuildEnum(const EnumDescriptorProto& proto, result->containing_type_ = parent; result->is_placeholder_ = false; result->is_unqualified_placeholder_ = false; - result->validator_data_.store(nullptr, std::memory_order_relaxed); if (proto.value_size() == 0) { // We cannot allow enums with no values because this would mean there diff --git a/src/google/protobuf/descriptor.h b/src/google/protobuf/descriptor.h index 532b51d03b..d65028a962 100644 --- a/src/google/protobuf/descriptor.h +++ b/src/google/protobuf/descriptor.h @@ -1455,8 +1455,6 @@ class PROTOBUF_EXPORT EnumDescriptor : private internal::SymbolBase { // to this descriptor from the file root. void GetLocationPath(std::vector* output) const; - const uint32_t* GetValidatorData() const; - // True if this is a placeholder for an unknown type. bool is_placeholder_ : 1; // 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_; const std::string** reserved_names_; - mutable std::atomic validator_data_; - // IMPORTANT: If you add a new field, make sure to search for all instances // of Allocate() and AllocateArray() in // descriptor.cc and update them to initialize the field. @@ -1505,7 +1501,7 @@ class PROTOBUF_EXPORT EnumDescriptor : private internal::SymbolBase { 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 // EnumValueDescriptor for a given enum value, first get the EnumDescriptor diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc index 31e66c8268..6a75583bfa 100644 --- a/src/google/protobuf/generated_message_reflection.cc +++ b/src/google/protobuf/generated_message_reflection.cc @@ -3305,18 +3305,29 @@ void Reflection::PopulateTcParseEntries( TcParseTableBase::FieldEntry* entries) const { for (const auto& entry : table_info.field_entries) { const FieldDescriptor* field = entry.field; - 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(8 * schema_.HasBitsOffset() + entry.hasbit_idx); + if (field->type() == field->TYPE_ENUM && + (entry.type_card & internal::field_layout::kTvMask) == + internal::field_layout::kTvEnum && + table_info.aux_entries[entry.aux_idx].type == + internal::TailCallTableInfo::kEnumValidator) { + // Mini parse can't handle it. Fallback to reflection. + *entries = {}; + table_info.aux_entries[entry.aux_idx] = {}; } 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(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; } } @@ -3361,8 +3372,7 @@ void Reflection::PopulateTcParseFieldAux( aux_entry.enum_range.size}; break; case internal::TailCallTableInfo::kEnumValidator: - field_aux++->enum_data = - aux_entry.field->enum_type()->GetValidatorData(); + ABSL_LOG(FATAL) << "Not supported."; break; case internal::TailCallTableInfo::kNumericOffset: field_aux++->offset = aux_entry.offset;