Mark LazyField as zero initializable.

PiperOrigin-RevId: 645141554
pull/17183/head
Protobuf Team Bot 8 months ago committed by Copybara-Service
parent dcde39e12f
commit 6fb2049cfd
  1. 1
      src/google/protobuf/compiler/cpp/field.cc
  2. 7
      src/google/protobuf/compiler/cpp/field.h
  3. 6
      src/google/protobuf/compiler/cpp/helpers.cc
  4. 3
      src/google/protobuf/compiler/cpp/message.cc
  5. 15
      src/google/protobuf/compiler/cpp/padding_optimizer.cc

@ -147,6 +147,7 @@ FieldGeneratorBase::FieldGeneratorBase(const FieldDescriptor* field,
}
has_trivial_zero_default_ = CanInitializeByZeroing(field, options, scc);
has_brace_default_assign_ = has_trivial_zero_default_ && !is_lazy_;
}
void FieldGeneratorBase::GenerateMemberConstexprConstructor(

@ -69,6 +69,9 @@ class FieldGeneratorBase {
// I.e., the field can be initialized with `memset(&field, 0, sizeof(field))`
bool has_trivial_zero_default() const { return has_trivial_zero_default_; }
// Returns true if the provided field can be initialized with `= {}`.
bool has_brace_default_assign() const { return has_brace_default_assign_; }
// Returns true if the field is a singular or repeated message.
// This includes group message types. To explicitly check if a message
// type is a group type, use the `is_group()` function,
@ -204,6 +207,7 @@ class FieldGeneratorBase {
bool is_trivial_ = false;
bool has_trivial_value_ = false;
bool has_trivial_zero_default_ = false;
bool has_brace_default_assign_ = false;
bool is_message_ = false;
bool is_group_ = false;
bool is_string_ = false;
@ -255,6 +259,9 @@ class FieldGenerator {
bool has_trivial_zero_default() const {
return impl_->has_trivial_zero_default();
}
bool has_brace_default_assign() const {
return impl_->has_brace_default_assign();
}
bool is_message() const { return impl_->is_message(); }
bool is_group() const { return impl_->is_group(); }
bool is_weak() const { return impl_->is_weak(); }

@ -332,9 +332,7 @@ bool CanInitializeByZeroing(const FieldDescriptor* field,
case FieldDescriptor::CPPTYPE_BOOL:
return field->default_value_bool() == false;
case FieldDescriptor::CPPTYPE_MESSAGE:
// Non-repeated, non-lazy message fields are raw pointers initialized to
// null.
return !IsLazy(field, options, scc_analyzer);
return true;
default:
return false;
}
@ -446,7 +444,7 @@ std::string ResolveKeyword(absl::string_view name) {
}
std::string DotsToColons(absl::string_view name) {
std::vector<std::string> scope = absl::StrSplit(name, ".", absl::SkipEmpty());
std::vector<std::string> scope = absl::StrSplit(name, '.', absl::SkipEmpty());
for (auto& word : scope) {
word = ResolveKeyword(word);
}

@ -2470,7 +2470,8 @@ void MessageGenerator::GenerateZeroInitFields(io::Printer* p) const {
auto emit_pending_zero_fields = [&](Iterator end) {
if (first != nullptr) {
const FieldDescriptor* last = end[-1];
if (first != last) {
if (first != last ||
!field_generators_.get(first).has_brace_default_assign()) {
p->Emit({{"first", FieldName(first)},
{"last", FieldName(last)},
{"Impl", "Impl_"},

@ -73,12 +73,9 @@ static void OptimizeLayoutHelper(std::vector<const FieldDescriptor*>* fields,
enum Family {
REPEATED = 0,
STRING = 1,
// Laying out LAZY_MESSAGE before MESSAGE allows a single memset to zero
// MESSAGE and ZERO_INITIALIZABLE fields together.
LAZY_MESSAGE = 2,
MESSAGE = 3,
ZERO_INITIALIZABLE = 4,
OTHER = 5,
MESSAGE = 2,
ZERO_INITIALIZABLE = 3,
OTHER = 4,
kMaxFamily
};
@ -96,9 +93,6 @@ static void OptimizeLayoutHelper(std::vector<const FieldDescriptor*>* fields,
f = STRING;
} else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
f = MESSAGE;
if (IsLazy(field, options, scc_analyzer)) {
f = LAZY_MESSAGE;
}
} else if (CanInitializeByZeroing(field, options, scc_analyzer)) {
f = ZERO_INITIALIZABLE;
}
@ -192,9 +186,6 @@ static void OptimizeLayoutHelper(std::vector<const FieldDescriptor*>* fields,
// STRING is grouped next, as our Clear/SharedCtor/SharedDtor walks it and
// calls ArenaStringPtr::Destroy on each.
//
// LAZY_MESSAGE is grouped next, as it interferes with the ability to memset
// non-repeated fields otherwise.
//
// MESSAGE is grouped next, as our Clear/SharedDtor code walks it and calls
// delete on each. We initialize these fields with a NULL pointer (see
// MessageFieldGenerator::GenerateConstructorCode), which allows them to be

Loading…
Cancel
Save