Fix memory regression in RuleVisibility Benchmarks show that https://github.com/bazelbuild/bazel/commit/cd82f68cfdf44aabaea1931ea9ff870ec7bb4af1 introduced a memory regression. Fix it by: * memoizing the very frequently used ["//visibility:public"] and ["//visibility:private"] declared labels lists * for filtering out private labels, using a list builder with a known expected size instead of relying on the streams api I also experimented with feeding the simplified visibility label lists back into the package builder's list interner - but decided against it because benchmarks show it results in a slightly higher memory usage. PiperOrigin-RevId: 681511741 Change-Id: I498e4adca976834d6b137b106f9d202c793bb54d
diff --git a/src/main/java/com/google/devtools/build/lib/packages/RuleVisibility.java b/src/main/java/com/google/devtools/build/lib/packages/RuleVisibility.java index f564cb5..0c4ca66 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/RuleVisibility.java +++ b/src/main/java/com/google/devtools/build/lib/packages/RuleVisibility.java
@@ -55,12 +55,20 @@ @SerializationConstant Label PRIVATE_LABEL = Label.parseCanonicalUnchecked("//visibility:private"); + // Constant for memory efficiency; see b/370873477. + @SerializationConstant + ImmutableList<Label> PUBLIC_DECLARED_LABELS = ImmutableList.of(PUBLIC_LABEL); + + // Constant for memory efficiency; see b/370873477. + @SerializationConstant + ImmutableList<Label> PRIVATE_DECLARED_LABELS = ImmutableList.of(PRIVATE_LABEL); + @SerializationConstant RuleVisibility PUBLIC = new RuleVisibility() { @Override public ImmutableList<Label> getDeclaredLabels() { - return ImmutableList.of(PUBLIC_LABEL); + return PUBLIC_DECLARED_LABELS; } @Override @@ -79,7 +87,7 @@ new RuleVisibility() { @Override public ImmutableList<Label> getDeclaredLabels() { - return ImmutableList.of(PRIVATE_LABEL); + return PRIVATE_DECLARED_LABELS; } @Override @@ -175,17 +183,22 @@ } } if (hasPublicLabel) { - return PUBLIC.getDeclaredLabels(); + return PUBLIC_DECLARED_LABELS; } if (numPrivateLabels == labels.size()) { - return PRIVATE.getDeclaredLabels(); + return PRIVATE_DECLARED_LABELS; } if (numPrivateLabels == 0) { return labels; } - return labels.stream() - .filter(label -> !label.equals(PRIVATE_LABEL)) - .collect(ImmutableList.toImmutableList()); + ImmutableList.Builder<Label> withoutPrivateLabels = + ImmutableList.builderWithExpectedSize(labels.size() - numPrivateLabels); + for (Label label : labels) { + if (!label.equals(PRIVATE_LABEL)) { + withoutPrivateLabels.add(label); + } + } + return withoutPrivateLabels.build(); } /**