Skip to content

Commit cc79f77

Browse files
mhansencopybara-github
authored andcommitted
Proto java full runtime: avoid allocating Integers accessing enum lists
Previously, we would allocate a boxed Integer when accessing repeated enums, because we used ArrayList<Integer>, which must box the int. Use IntArrayList and the primitive "int getInt()" method instead. PiperOrigin-RevId: 630229119
1 parent d6c2833 commit cc79f77

File tree

1 file changed

+48
-51
lines changed

1 file changed

+48
-51
lines changed

src/google/protobuf/compiler/java/immutable/enum_field.cc

Lines changed: 48 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -687,28 +687,27 @@ void RepeatedImmutableEnumFieldGenerator::GenerateMembers(
687687
printer->Print(
688688
variables_,
689689
"@SuppressWarnings(\"serial\")\n"
690-
"private java.util.List<java.lang.Integer> $name$_;\n"
690+
"private com.google.protobuf.Internal.IntList $name$_;\n"
691691
"private static final "
692-
"com.google.protobuf.Internal.ListAdapter.Converter<\n"
693-
" java.lang.Integer, $type$> $name$_converter_ =\n"
694-
" new com.google.protobuf.Internal.ListAdapter.Converter<\n"
695-
" java.lang.Integer, $type$>() {\n"
696-
" public $type$ convert(java.lang.Integer from) {\n"
692+
"com.google.protobuf.Internal.IntListAdapter.IntConverter<\n"
693+
" $type$> $name$_converter_ =\n"
694+
" new com.google.protobuf.Internal.IntListAdapter.IntConverter<\n"
695+
" $type$>() {\n"
696+
" public $type$ convert(int from) {\n"
697697
" $type$ result = $type$.forNumber(from);\n"
698698
" return result == null ? $unknown$ : result;\n"
699699
" }\n"
700700
" };\n");
701701
PrintExtraFieldInfo(variables_, printer);
702702
WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER,
703703
context_->options());
704-
printer->Print(
705-
variables_,
706-
"@java.lang.Override\n"
707-
"$deprecation$public java.util.List<$type$> "
708-
"${$get$capitalized_name$List$}$() {\n"
709-
" return new com.google.protobuf.Internal.ListAdapter<\n"
710-
" java.lang.Integer, $type$>($name$_, $name$_converter_);\n"
711-
"}\n");
704+
printer->Print(variables_,
705+
"@java.lang.Override\n"
706+
"$deprecation$public java.util.List<$type$> "
707+
"${$get$capitalized_name$List$}$() {\n"
708+
" return new com.google.protobuf.Internal.IntListAdapter<\n"
709+
" $type$>($name$_, $name$_converter_);\n"
710+
"}\n");
712711
printer->Annotate("{", "}", descriptor_);
713712
WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT,
714713
context_->options());
@@ -725,7 +724,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateMembers(
725724
variables_,
726725
"@java.lang.Override\n"
727726
"$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
728-
" return $name$_converter_.convert($name$_.get(index));\n"
727+
" return $name$_converter_.convert($name$_.getInt(index));\n"
729728
"}\n");
730729
printer->Annotate("{", "}", descriptor_);
731730
if (SupportUnknownEnumValue(descriptor_)) {
@@ -744,7 +743,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateMembers(
744743
"@java.lang.Override\n"
745744
"$deprecation$public int "
746745
"${$get$capitalized_name$Value$}$(int index) {\n"
747-
" return $name$_.get(index);\n"
746+
" return $name$_.getInt(index);\n"
748747
"}\n");
749748
printer->Annotate("{", "}", descriptor_);
750749
}
@@ -760,19 +759,18 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers(
760759
variables_,
761760
// One field is the list and the other field keeps track of whether the
762761
// list is immutable. If it's immutable, the invariant is that it must
763-
// either an instance of Collections.emptyList() or it's an ArrayList
764-
// wrapped in a Collections.unmodifiableList() wrapper and nobody else has
765-
// a reference to the underlying ArrayList. This invariant allows us to
766-
// share instances of lists between protocol buffers avoiding expensive
767-
// memory allocations. Note, immutable is a strong guarantee here -- not
768-
// just that the list cannot be modified via the reference but that the
769-
// list can never be modified.
770-
"private java.util.List<java.lang.Integer> $name$_ =\n"
771-
" java.util.Collections.emptyList();\n"
762+
// either an instance of emptyIntList() or it's an immutable IntArrayList
763+
// and nobody else has a reference to the underlying ArrayList. This
764+
// invariant allows us to share instances of lists between protocol
765+
// buffers avoiding expensive memory allocations. Note, immutable is a
766+
// strong guarantee here -- not just that the list cannot be modified via
767+
// the reference but that the list can never be modified.
768+
"private com.google.protobuf.Internal.IntList $name$_ =\n"
769+
" emptyIntList();\n"
772770

773771
"private void ensure$capitalized_name$IsMutable() {\n"
774772
" if (!$get_mutable_bit_builder$) {\n"
775-
" $name$_ = new java.util.ArrayList<java.lang.Integer>($name$_);\n"
773+
" $name$_ = makeMutableCopy($name$_);\n"
776774
" $set_mutable_bit_builder$;\n"
777775
" }\n"
778776
"}\n");
@@ -787,8 +785,8 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers(
787785
// immutable.
788786
"$deprecation$public java.util.List<$type$> "
789787
"${$get$capitalized_name$List$}$() {\n"
790-
" return new com.google.protobuf.Internal.ListAdapter<\n"
791-
" java.lang.Integer, $type$>($name$_, $name$_converter_);\n"
788+
" return new com.google.protobuf.Internal.IntListAdapter<\n"
789+
" $type$>($name$_, $name$_converter_);\n"
792790
"}\n");
793791
printer->Annotate("{", "}", descriptor_);
794792
WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT,
@@ -804,7 +802,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers(
804802
printer->Print(
805803
variables_,
806804
"$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
807-
" return $name$_converter_.convert($name$_.get(index));\n"
805+
" return $name$_converter_.convert($name$_.getInt(index));\n"
808806
"}\n");
809807
printer->Annotate("{", "}", descriptor_);
810808
WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER,
@@ -817,7 +815,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers(
817815
" throw new NullPointerException();\n"
818816
" }\n"
819817
" ensure$capitalized_name$IsMutable();\n"
820-
" $name$_.set(index, value.getNumber());\n"
818+
" $name$_.setInt(index, value.getNumber());\n"
821819
" onChanged();\n"
822820
" return this;\n"
823821
"}\n");
@@ -832,7 +830,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers(
832830
" throw new NullPointerException();\n"
833831
" }\n"
834832
" ensure$capitalized_name$IsMutable();\n"
835-
" $name$_.add(value.getNumber());\n"
833+
" $name$_.addInt(value.getNumber());\n"
836834
" onChanged();\n"
837835
" return this;\n"
838836
"}\n");
@@ -845,7 +843,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers(
845843
" java.lang.Iterable<? extends $type$> values) {\n"
846844
" ensure$capitalized_name$IsMutable();\n"
847845
" for ($type$ value : values) {\n"
848-
" $name$_.add(value.getNumber());\n"
846+
" $name$_.addInt(value.getNumber());\n"
849847
" }\n"
850848
" onChanged();\n"
851849
" return this;\n"
@@ -857,7 +855,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers(
857855
printer->Print(
858856
variables_,
859857
"$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
860-
" $name$_ = java.util.Collections.emptyList();\n"
858+
" $name$_ = emptyIntList();\n"
861859
" $clear_mutable_bit_builder$;\n"
862860
" onChanged();\n"
863861
" return this;\n"
@@ -878,7 +876,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers(
878876
printer->Print(variables_,
879877
"$deprecation$public int "
880878
"${$get$capitalized_name$Value$}$(int index) {\n"
881-
" return $name$_.get(index);\n"
879+
" return $name$_.getInt(index);\n"
882880
"}\n");
883881
printer->Annotate("{", "}", descriptor_);
884882
WriteFieldEnumValueAccessorDocComment(
@@ -889,7 +887,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers(
889887
"$deprecation$public Builder ${$set$capitalized_name$Value$}$(\n"
890888
" int index, int value) {\n"
891889
" ensure$capitalized_name$IsMutable();\n"
892-
" $name$_.set(index, value);\n"
890+
" $name$_.setInt(index, value);\n"
893891
" onChanged();\n"
894892
" return this;\n"
895893
"}\n");
@@ -901,7 +899,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers(
901899
"$deprecation$public Builder "
902900
"${$add$capitalized_name$Value$}$(int value) {\n"
903901
" ensure$capitalized_name$IsMutable();\n"
904-
" $name$_.add(value);\n"
902+
" $name$_.addInt(value);\n"
905903
" onChanged();\n"
906904
" return this;\n"
907905
"}\n");
@@ -915,7 +913,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers(
915913
" java.lang.Iterable<java.lang.Integer> values) {\n"
916914
" ensure$capitalized_name$IsMutable();\n"
917915
" for (int value : values) {\n"
918-
" $name$_.add(value);\n"
916+
" $name$_.addInt(value);\n"
919917
" }\n"
920918
" onChanged();\n"
921919
" return this;\n"
@@ -931,13 +929,13 @@ void RepeatedImmutableEnumFieldGenerator::
931929

932930
void RepeatedImmutableEnumFieldGenerator::GenerateInitializationCode(
933931
io::Printer* printer) const {
934-
printer->Print(variables_, "$name$_ = java.util.Collections.emptyList();\n");
932+
printer->Print(variables_, "$name$_ = emptyIntList();\n");
935933
}
936934

937935
void RepeatedImmutableEnumFieldGenerator::GenerateBuilderClearCode(
938936
io::Printer* printer) const {
939937
printer->Print(variables_,
940-
"$name$_ = java.util.Collections.emptyList();\n"
938+
"$name$_ = emptyIntList();\n"
941939
"$clear_mutable_bit_builder$;\n");
942940
}
943941

@@ -965,13 +963,12 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuildingCode(
965963
io::Printer* printer) const {
966964
// The code below ensures that the result has an immutable list. If our
967965
// list is immutable, we can just reuse it. If not, we make it immutable.
968-
printer->Print(
969-
variables_,
970-
"if ($get_mutable_bit_builder$) {\n"
971-
" $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
972-
" $clear_mutable_bit_builder$;\n"
973-
"}\n"
974-
"result.$name$_ = $name$_;\n");
966+
printer->Print(variables_,
967+
"if ($get_mutable_bit_builder$) {\n"
968+
" $name$_.makeImmutable();\n"
969+
" $clear_mutable_bit_builder$;\n"
970+
"}\n"
971+
"result.$name$_ = $name$_;\n");
975972
}
976973

977974
void RepeatedImmutableEnumFieldGenerator::GenerateBuilderParsingCode(
@@ -981,7 +978,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderParsingCode(
981978
printer->Print(variables_,
982979
"int tmpRaw = input.readEnum();\n"
983980
"ensure$capitalized_name$IsMutable();\n"
984-
"$name$_.add(tmpRaw);\n");
981+
"$name$_.addInt(tmpRaw);\n");
985982
} else {
986983
printer->Print(variables_,
987984
"int tmpRaw = input.readEnum();\n"
@@ -991,7 +988,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderParsingCode(
991988
" mergeUnknownVarintField($number$, tmpRaw);\n"
992989
"} else {\n"
993990
" ensure$capitalized_name$IsMutable();\n"
994-
" $name$_.add(tmpRaw);\n"
991+
" $name$_.addInt(tmpRaw);\n"
995992
"}\n");
996993
}
997994
}
@@ -1022,12 +1019,12 @@ void RepeatedImmutableEnumFieldGenerator::GenerateSerializationCode(
10221019
" output.writeUInt32NoTag($name$MemoizedSerializedSize);\n"
10231020
"}\n"
10241021
"for (int i = 0; i < $name$_.size(); i++) {\n"
1025-
" output.writeEnumNoTag($name$_.get(i));\n"
1022+
" output.writeEnumNoTag($name$_.getInt(i));\n"
10261023
"}\n");
10271024
} else {
10281025
printer->Print(variables_,
10291026
"for (int i = 0; i < $name$_.size(); i++) {\n"
1030-
" output.writeEnum($number$, $name$_.get(i));\n"
1027+
" output.writeEnum($number$, $name$_.getInt(i));\n"
10311028
"}\n");
10321029
}
10331030
}
@@ -1042,7 +1039,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateSerializedSizeCode(
10421039
printer->Print(variables_,
10431040
"for (int i = 0; i < $name$_.size(); i++) {\n"
10441041
" dataSize += com.google.protobuf.CodedOutputStream\n"
1045-
" .computeEnumSizeNoTag($name$_.get(i));\n"
1042+
" .computeEnumSizeNoTag($name$_.getInt(i));\n"
10461043
"}\n");
10471044
printer->Print("size += dataSize;\n");
10481045
if (descriptor_->is_packed()) {

0 commit comments

Comments
 (0)