Small optimization/cleanup for message split.

PiperOrigin-RevId: 564854706
pull/14061/head
Cong Liu 1 year ago committed by Copybara-Service
parent 3f1bf2e18e
commit ef198dbae3
  1. 29
      src/google/protobuf/compiler/cpp/message.cc

@ -1070,7 +1070,8 @@ void MessageGenerator::GenerateFieldClear(const FieldDescriptor* field,
// TODO(b/281513105): figure out if early return breaks tracking // TODO(b/281513105): figure out if early return breaks tracking
if (ShouldSplit(field, options_)) { if (ShouldSplit(field, options_)) {
p->Emit(R"cc( p->Emit(R"cc(
if (IsSplitMessageDefault()) return; if (PROTOBUF_PREDICT_TRUE(IsSplitMessageDefault()))
return;
)cc"); )cc");
} }
field_generators_.get(field).GenerateClearingCode(p); field_generators_.get(field).GenerateClearingCode(p);
@ -2069,7 +2070,7 @@ void MessageGenerator::GenerateClassMethods(io::Printer* p) {
if (ShouldSplit(descriptor_, options_)) { if (ShouldSplit(descriptor_, options_)) {
format( format(
"void $classname$::PrepareSplitMessageForWrite() {\n" "void $classname$::PrepareSplitMessageForWrite() {\n"
" if (IsSplitMessageDefault()) {\n" " if (PROTOBUF_PREDICT_TRUE(IsSplitMessageDefault())) {\n"
" void* chunk = $pbi$::CreateSplitMessageGeneric(" " void* chunk = $pbi$::CreateSplitMessageGeneric("
"GetArenaForAllocation(), &$1$, sizeof(Impl_::Split), this, &$2$);\n" "GetArenaForAllocation(), &$1$, sizeof(Impl_::Split), this, &$2$);\n"
" $split$ = reinterpret_cast<Impl_::Split*>(chunk);\n" " $split$ = reinterpret_cast<Impl_::Split*>(chunk);\n"
@ -2677,7 +2678,7 @@ void MessageGenerator::GenerateSharedDestructorCode(io::Printer* p) {
[&] { emit_field_dtors(/* split_fields= */ true); }}, [&] { emit_field_dtors(/* split_fields= */ true); }},
}, },
R"cc( R"cc(
if (!IsSplitMessageDefault()) { if (PROTOBUF_PREDICT_FALSE(!IsSplitMessageDefault())) {
auto* $cached_split_ptr$ = $split$; auto* $cached_split_ptr$ = $split$;
$split_field_dtors_impl$; $split_field_dtors_impl$;
delete $cached_split_ptr$; delete $cached_split_ptr$;
@ -2753,6 +2754,16 @@ void MessageGenerator::GenerateArenaDestructorCode(io::Printer* p) {
field_generators_.get(field).GenerateArenaDestructorCode(p); field_generators_.get(field).GenerateArenaDestructorCode(p);
} }
}; };
bool needs_arena_dtor_split = false;
for (const auto* field : optimized_order_) {
if (!ShouldSplit(field, options_)) continue;
if (field_generators_.get(field).NeedsArenaDestructor() >
ArenaDtorNeeds::kNone) {
needs_arena_dtor_split = true;
break;
}
}
// This code is placed inside a static method, rather than an ordinary one, // This code is placed inside a static method, rather than an ordinary one,
// since that simplifies Arena's destructor list (ordinary function pointers // since that simplifies Arena's destructor list (ordinary function pointers
// rather than member function pointers). _this is the object being // rather than member function pointers). _this is the object being
@ -2763,13 +2774,17 @@ void MessageGenerator::GenerateArenaDestructorCode(io::Printer* p) {
{"split_field_dtors", {"split_field_dtors",
[&] { [&] {
if (!ShouldSplit(descriptor_, options_)) return; if (!ShouldSplit(descriptor_, options_)) return;
if (!needs_arena_dtor_split) {
return;
}
p->Emit( p->Emit(
{ {
{"split_field_dtors_impl", {"split_field_dtors_impl",
[&] { emit_field_dtors(/* split_fields= */ true); }}, [&] { emit_field_dtors(/* split_fields= */ true); }},
}, },
R"cc( R"cc(
if (!_this->IsSplitMessageDefault()) { if (PROTOBUF_PREDICT_FALSE(
!_this->IsSplitMessageDefault())) {
$split_field_dtors_impl$; $split_field_dtors_impl$;
} }
)cc"); )cc");
@ -2970,7 +2985,7 @@ void MessageGenerator::GenerateCopyConstructorBody(io::Printer* p) const {
} }
if (ShouldSplit(descriptor_, options_)) { if (ShouldSplit(descriptor_, options_)) {
format("if (!from.IsSplitMessageDefault()) {\n"); format("if (PROTOBUF_PREDICT_FALSE(!from.IsSplitMessageDefault())) {\n");
format.Indent(); format.Indent();
format("_this->PrepareSplitMessageForWrite();\n"); format("_this->PrepareSplitMessageForWrite();\n");
// TODO(b/122856539): cache the split pointers. // TODO(b/122856539): cache the split pointers.
@ -3605,7 +3620,6 @@ void MessageGenerator::GenerateClear(io::Printer* p) {
auto next = FindNextUnequalChunk(it, end, MayGroupChunksForHaswordsCheck); auto next = FindNextUnequalChunk(it, end, MayGroupChunksForHaswordsCheck);
bool has_haswords_check = MaybeEmitHaswordsCheck( bool has_haswords_check = MaybeEmitHaswordsCheck(
it, next, options_, has_bit_indices_, cached_has_word_index, "", p); it, next, options_, has_bit_indices_, cached_has_word_index, "", p);
bool has_default_split_check = !it->fields.empty() && it->should_split; bool has_default_split_check = !it->fields.empty() && it->should_split;
if (has_default_split_check) { if (has_default_split_check) {
// Some fields are cleared without checking has_bit. So we add the // Some fields are cleared without checking has_bit. So we add the
@ -3727,7 +3741,6 @@ void MessageGenerator::GenerateClear(io::Printer* p) {
cached_has_word_index = -1; cached_has_word_index = -1;
} }
} }
// Step 4: Unions. // Step 4: Unions.
for (auto oneof : OneOfRange(descriptor_)) { for (auto oneof : OneOfRange(descriptor_)) {
format("clear_$1$();\n", oneof->name()); format("clear_$1$();\n", oneof->name());
@ -3982,7 +3995,7 @@ void MessageGenerator::GenerateClassSpecificMergeImpl(io::Printer* p) {
if (ShouldSplit(descriptor_, options_)) { if (ShouldSplit(descriptor_, options_)) {
format( format(
"if (!from.IsSplitMessageDefault()) {\n" "if (PROTOBUF_PREDICT_FALSE(!from.IsSplitMessageDefault())) {\n"
" _this->PrepareSplitMessageForWrite();\n" " _this->PrepareSplitMessageForWrite();\n"
"}\n"); "}\n");
} }

Loading…
Cancel
Save