From 6ddc6229812c9da7477a69399b1e61c3d176494e Mon Sep 17 00:00:00 2001 From: Googler Date: Wed, 24 Apr 2019 17:28:05 -0700 Subject: [PATCH] Cache a soft reference to the reconstituted BuildOptions in OptionsDiffForReconstruction. This makes it so that applyDiff usually does no work and also reduces garbage creation. Although I do not think the results of applyDiff are currently being compared with equals/hashCode anywhere, this also prevents expensive re-initialization of fingerprint/hashCode if they ever are. PiperOrigin-RevId: 245148847 --- .../lib/analysis/config/BuildOptions.java | 44 +++++++++++++---- .../lib/analysis/config/BuildOptionsTest.java | 47 ++++++++++++------- 2 files changed, 66 insertions(+), 25 deletions(-) diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildOptions.java b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildOptions.java index ba4e6ac525c8b7..a64215d530b8a4 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildOptions.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildOptions.java @@ -50,6 +50,7 @@ import com.google.protobuf.CodedOutputStream; import java.io.IOException; import java.io.Serializable; +import java.lang.ref.SoftReference; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -307,7 +308,11 @@ public BuildOptions applyDiff(OptionsDiffForReconstruction optionsDiff) { } maybeInitializeFingerprintAndHashCode(); if (!Arrays.equals(fingerprint, optionsDiff.baseFingerprint)) { - throw new IllegalArgumentException("Can not reconstruct BuildOptions with a different base."); + throw new IllegalArgumentException("Cannot reconstruct BuildOptions with a different base."); + } + BuildOptions reconstructedOptions = optionsDiff.cachedReconstructed.get(); + if (reconstructedOptions != null) { + return reconstructedOptions; } Builder builder = builder(); for (FragmentOptions options : fragmentOptionsMap.values()) { @@ -332,8 +337,9 @@ public BuildOptions applyDiff(OptionsDiffForReconstruction optionsDiff) { } } skylarkOptions.putAll(optionsDiff.extraSecondStarlarkOptions); - builder.addStarlarkOptions(skylarkOptions); - return builder.build(); + reconstructedOptions = builder.addStarlarkOptions(skylarkOptions).build(); + optionsDiff.cachedReconstructed = new SoftReference<>(reconstructedOptions); + return reconstructedOptions; } /** @@ -673,7 +679,8 @@ public static OptionsDiffForReconstruction diffForReconstruction( second.computeChecksum(), diff.skylarkSecond, diff.extraStarlarkOptionsFirst, - diff.extraStarlarkOptionsSecond); + diff.extraStarlarkOptionsSecond, + second); } /** @@ -827,7 +834,15 @@ public static final class OptionsDiffForReconstruction { private final List