Skip to content

Commit 15c9e9a

Browse files
ClaytonKnittelcopybara-github
authored andcommitted
Don't assign hasbits to likely-present repeated fields with hasbits for repeated fields enabled.
PiperOrigin-RevId: 792437227
1 parent 418399e commit 15c9e9a

File tree

4 files changed

+24
-13
lines changed

4 files changed

+24
-13
lines changed

src/google/protobuf/compiler/cpp/helpers.cc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,8 +1098,11 @@ std::optional<float> GetFieldGroupPresenceProbability(
10981098

10991099
HasbitMode GetFieldHasbitMode(const FieldDescriptor* field,
11001100
const Options& options) {
1101-
// TODO: Use profile data to determine the hasbit mode for fields
1102-
// with optional hasbits.
1101+
if (IsProfileDriven(options) && field->is_repeated() &&
1102+
IsLikelyPresent(field, options)) {
1103+
return HasbitMode::kNoHasbit;
1104+
}
1105+
11031106
return internal::cpp::GetFieldHasbitModeWithoutProfile(field);
11041107
}
11051108

src/google/protobuf/compiler/cpp/message.cc

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -694,10 +694,13 @@ MessageGenerator::MessageGenerator(
694694

695695
bool MessageGenerator::ShouldGenerateEnclosingIf(
696696
const FieldDescriptor& field) const {
697-
return HasBitIndex(&field) != kNoHasbit &&
698-
(field.is_repeated() ||
699-
field.cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
700-
field.cpp_type() == FieldDescriptor::CPPTYPE_STRING);
697+
if (HasBitIndex(&field) == kNoHasbit) return false;
698+
// Always check hasbits for repeated fields since likely repeated fields,
699+
// which aren't assigned hasbits, would bail in the previous check.
700+
if (field.is_repeated()) return true;
701+
// Always check hasbits for message and string fields before clearing them.
702+
return field.cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
703+
field.cpp_type() == FieldDescriptor::CPPTYPE_STRING;
701704
}
702705

703706
size_t MessageGenerator::HasBitsSize() const {
@@ -3304,8 +3307,9 @@ void MessageGenerator::GenerateCopyInitFields(io::Printer* p) const {
33043307

33053308
auto generate_copy_fields = [&] {
33063309
for (auto it = begin; it != end; ++it) {
3307-
const auto& gen = field_generators_.get(*it);
3308-
auto v = p->WithVars(FieldVars(*it, options_));
3310+
const auto* field = *it;
3311+
const auto& gen = field_generators_.get(field);
3312+
auto v = p->WithVars(FieldVars(field, options_));
33093313

33103314
// Non trivial field values are copy constructed
33113315
if (!gen.has_trivial_value() || gen.should_split()) {
@@ -3315,9 +3319,9 @@ void MessageGenerator::GenerateCopyInitFields(io::Printer* p) const {
33153319

33163320
if (gen.is_message()) {
33173321
emit_pending_copy_fields(it, false);
3318-
emit_copy_message(*it);
3322+
emit_copy_message(field);
33193323
} else if (first == nullptr) {
3320-
first = *it;
3324+
first = field;
33213325
}
33223326
}
33233327
emit_pending_copy_fields(end, false);

src/google/protobuf/generated_message_reflection.cc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3265,7 +3265,8 @@ void Reflection::ClearHasBit(Message* message,
32653265
void Reflection::NaiveSwapHasBit(Message* message1, Message* message2,
32663266
const FieldDescriptor* field) const {
32673267
ABSL_DCHECK(!field->options().weak());
3268-
if (!schema_.HasHasbits()) {
3268+
if (!schema_.HasHasbits() ||
3269+
schema_.HasBitIndex(field) == static_cast<uint32_t>(kNoHasbit)) {
32693270
return;
32703271
}
32713272
const Reflection* r1 = message1->GetReflection();
@@ -3621,7 +3622,9 @@ void Reflection::PopulateTcParseEntries(
36213622
entries->has_idx = schema_.oneof_case_offset_ + 4 * oneof->index();
36223623
} else if (schema_.HasHasbits()) {
36233624
entries->has_idx =
3624-
static_cast<int>(8 * schema_.HasBitsOffset() + entry.hasbit_idx);
3625+
entry.hasbit_idx >= 0
3626+
? static_cast<int>(8 * schema_.HasBitsOffset() + entry.hasbit_idx)
3627+
: kNoHasbit;
36253628
} else {
36263629
entries->has_idx = 0;
36273630
}

src/google/protobuf/generated_message_tctable_lite.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@ absl::Status TcParser::VerifyHasBitConsistency(const MessageLite* msg,
114114
msg->GetTypeName(), FieldNumber(table, &entry)));
115115
};
116116
const auto cardinality = entry.type_card & fl::kFcMask;
117-
if (cardinality == fl::kFcSingular || cardinality == fl::kFcOneof) {
117+
if (cardinality == fl::kFcSingular || cardinality == fl::kFcOneof ||
118+
entry.has_idx == kNoHasbit) {
118119
continue;
119120
}
120121
if (!EnableExperimentalHintHasBitsForRepeatedFields() &&

0 commit comments

Comments
 (0)