|
|
@ -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"); |
|
|
|
} |
|
|
|
} |
|
|
|