Reduce garbage in options transitions: avoid cloning `BuildOptions` if possible in `AppleCrosstoolTransition` and avoid unnecessary string concatenation in `BuildOptions#get`.
PiperOrigin-RevId: 361568642
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 99a6d29..d218edb 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
@@ -178,7 +178,7 @@
/** Returns the actual instance of a FragmentOptions class. */
public <T extends FragmentOptions> T get(Class<T> optionsClass) {
FragmentOptions options = fragmentOptionsMap.get(optionsClass);
- Preconditions.checkNotNull(options, "fragment options unavailable: " + optionsClass.getName());
+ Preconditions.checkNotNull(options, "fragment options unavailable: %s", optionsClass);
return optionsClass.cast(options);
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleCrosstoolTransition.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleCrosstoolTransition.java
index 40408cc..e60068f 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleCrosstoolTransition.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleCrosstoolTransition.java
@@ -23,25 +23,26 @@
import com.google.devtools.build.lib.analysis.config.CoreOptions;
import com.google.devtools.build.lib.analysis.config.FragmentOptions;
import com.google.devtools.build.lib.analysis.config.transitions.PatchTransition;
-import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.rules.apple.AppleCommandLineOptions;
import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
import com.google.devtools.build.lib.rules.apple.AppleConfiguration.ConfigurationDistinguisher;
import com.google.devtools.build.lib.rules.apple.ApplePlatform;
import com.google.devtools.build.lib.rules.cpp.CppOptions;
-import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
+import com.google.devtools.build.lib.skyframe.serialization.autocodec.SerializationConstant;
/**
- * Transition that produces a configuration that causes c++ toolchain selection to use the
- * CROSSTOOL given in apple_crosstool_top.
+ * Transition that produces a configuration that causes c++ toolchain selection to use the CROSSTOOL
+ * given in apple_crosstool_top.
*/
-public class AppleCrosstoolTransition implements PatchTransition {
+public final class AppleCrosstoolTransition implements PatchTransition {
/** A singleton instance of AppleCrosstoolTransition. */
- @AutoCodec
+ @SerializationConstant
public static final PatchTransition APPLE_CROSSTOOL_TRANSITION = new AppleCrosstoolTransition();
+ private AppleCrosstoolTransition() {}
+
@Override
public ImmutableSet<Class<? extends FragmentOptions>> requiresOptionFragments() {
return ImmutableSet.of(
@@ -50,10 +51,7 @@
@Override
public BuildOptions patch(BuildOptionsView buildOptions, EventHandler eventHandler) {
- BuildOptionsView result = buildOptions.clone();
-
AppleCommandLineOptions appleOptions = buildOptions.get(AppleCommandLineOptions.class);
- CoreOptions configOptions = buildOptions.get(CoreOptions.class);
if (appleOptions.configurationDistinguisher != ConfigurationDistinguisher.UNKNOWN) {
// The configuration distinguisher is only set by AppleCrosstoolTransition and
@@ -62,10 +60,19 @@
return buildOptions.underlying();
}
+ CoreOptions configOptions = buildOptions.get(CoreOptions.class);
String cpu =
ApplePlatform.cpuStringForTarget(
appleOptions.applePlatformType,
determineSingleArchitecture(appleOptions, configOptions));
+
+ // Avoid a clone if nothing would change.
+ if (configOptions.cpu.equals(cpu)
+ && buildOptions.get(CppOptions.class).crosstoolTop.equals(appleOptions.appleCrosstoolTop)) {
+ return buildOptions.underlying();
+ }
+
+ BuildOptionsView result = buildOptions.clone();
setAppleCrosstoolTransitionConfiguration(buildOptions, result, cpu);
return result.underlying();
}
@@ -81,14 +88,13 @@
*/
public static void setAppleCrosstoolTransitionConfiguration(
BuildOptionsView from, BuildOptionsView to, String cpu) {
- Label crosstoolTop = from.get(AppleCommandLineOptions.class).appleCrosstoolTop;
- Label libcTop = from.get(AppleCommandLineOptions.class).appleLibcTop;
- String cppCompiler = from.get(AppleCommandLineOptions.class).cppCompiler;
+ AppleCommandLineOptions appleOptions = from.get(AppleCommandLineOptions.class);
CoreOptions toOptions = to.get(CoreOptions.class);
CppOptions toCppOptions = to.get(CppOptions.class);
- if (toOptions.cpu.equals(cpu) && toCppOptions.crosstoolTop.equals(crosstoolTop)) {
+ if (toOptions.cpu.equals(cpu)
+ && toCppOptions.crosstoolTop.equals(appleOptions.appleCrosstoolTop)) {
// If neither the CPU nor the Crosstool changes, do nothing. This is so that C++ to
// Objective-C dependencies work if the top-level configuration is already an Apple one.
// Removing the configuration distinguisher (which can't be set from the command line) and
@@ -99,14 +105,15 @@
}
toOptions.cpu = cpu;
- toCppOptions.crosstoolTop = crosstoolTop;
+ toCppOptions.crosstoolTop = appleOptions.appleCrosstoolTop;
to.get(AppleCommandLineOptions.class).configurationDistinguisher =
ConfigurationDistinguisher.APPLE_CROSSTOOL;
- to.get(CppOptions.class).cppCompiler = cppCompiler;
- to.get(CppOptions.class).libcTopLabel = libcTop;
+
+ toCppOptions.cppCompiler = appleOptions.cppCompiler;
+ toCppOptions.libcTopLabel = appleOptions.appleLibcTop;
// OSX toolchains do not support fission.
- to.get(CppOptions.class).fissionModes = ImmutableList.of();
+ toCppOptions.fissionModes = ImmutableList.of();
// Ensure platforms aren't set so that platform mapping can take place.
to.get(PlatformOptions.class).platforms = ImmutableList.of();
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/BUILD b/src/main/java/com/google/devtools/build/lib/rules/objc/BUILD
index 3d2411f..b89c883 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/BUILD
@@ -49,7 +49,6 @@
"//src/main/java/com/google/devtools/build/lib/concurrent",
"//src/main/java/com/google/devtools/build/lib/events",
"//src/main/java/com/google/devtools/build/lib/packages",
- "//src/main/java/com/google/devtools/build/lib/packages/semantics",
"//src/main/java/com/google/devtools/build/lib/rules/apple",
"//src/main/java/com/google/devtools/build/lib/rules/apple/cpp",
"//src/main/java/com/google/devtools/build/lib/rules/apple/swift",
@@ -60,6 +59,7 @@
"//src/main/java/com/google/devtools/build/lib/shell",
"//src/main/java/com/google/devtools/build/lib/skyframe:configured_target_and_data",
"//src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec",
+ "//src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec:serialization-constant",
"//src/main/java/com/google/devtools/build/lib/starlarkbuildapi",
"//src/main/java/com/google/devtools/build/lib/starlarkbuildapi/apple",
"//src/main/java/com/google/devtools/build/lib/util",