1111
1212#include " google/protobuf/compiler/java/full/message.h"
1313
14+ #include < algorithm>
1415#include < memory>
1516#include < string>
1617#include < utility>
@@ -608,9 +609,33 @@ void ImmutableMessageGenerator::GenerateMessageSerializationMethods(
608609 }
609610
610611 printer->Outdent ();
612+ printer->Print (" }\n " );
613+
614+ // Chunk up the getSerializedSize() into chunks to be JIT friendly.
615+ constexpr int kNumFieldsPerChunk = 32 ;
616+ int num_chunks = (descriptor_->field_count () + kNumFieldsPerChunk - 1 ) /
617+ kNumFieldsPerChunk ;
618+ for (int i = 0 ; i < num_chunks; ++i) {
619+ printer->Print (
620+ " private int computeSerializedSize_$chunk$() {\n "
621+ " int size = 0;\n " ,
622+ " chunk" , absl::StrCat (i));
623+ printer->Indent ();
624+
625+ int chunk_field_start = i * kNumFieldsPerChunk ;
626+ int chunk_field_end = std::min (chunk_field_start + kNumFieldsPerChunk ,
627+ descriptor_->field_count ());
628+
629+ for (int j = chunk_field_start; j < chunk_field_end; ++j) {
630+ field_generators_.get (sorted_fields[j])
631+ .GenerateSerializedSizeCode (printer);
632+ }
633+ printer->Outdent ();
634+ printer->Print (" return size;\n " );
635+ printer->Print (" }\n " );
636+ }
637+
611638 printer->Print (
612- " }\n "
613- " \n "
614639 " @java.lang.Override\n "
615640 " public int getSerializedSize() {\n "
616641 " int size = memoizedSize;\n "
@@ -620,8 +645,9 @@ void ImmutableMessageGenerator::GenerateMessageSerializationMethods(
620645
621646 printer->Print (" size = 0;\n " );
622647
623- for (int i = 0 ; i < descriptor_->field_count (); i++) {
624- field_generators_.get (sorted_fields[i]).GenerateSerializedSizeCode (printer);
648+ for (int i = 0 ; i < num_chunks; ++i) {
649+ printer->Print (" size += computeSerializedSize_$chunk$();\n " , " chunk" ,
650+ absl::StrCat (i));
625651 }
626652
627653 if (descriptor_->extension_range_count () > 0 ) {
0 commit comments