Utilize `CustomCommandLine#addObject` to add a `Collection` without copying over its elements.
This is more memory efficient if the `Collection` is retained anyway, since we spend a single array slot on a pointer instead of an array slot for each element. It works straightaway because `CustomCommandLine` already has handling for lazily "expanding" `Iterable`.
This change only affects Java compilation actions, as they are the only case I found which is currently wastefully copying lists. To maximize the benefit, structure the `JavaHeaderCompileAction` builder to accept an existing `ImmutableList<String>` of Javac options instead of creating its own.
PiperOrigin-RevId: 535304666
Change-Id: Id41af250916e95e87fd69bcdc1bfda1d3bc1421f
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/actions/CustomCommandLine.java b/src/main/java/com/google/devtools/build/lib/analysis/actions/CustomCommandLine.java
index a415729..f1d9729 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/actions/CustomCommandLine.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/actions/CustomCommandLine.java
@@ -780,8 +780,15 @@
/**
* Adds a single argument to the command line, which is lazily converted to string.
*
- * <p>If the value is null, neither the arg nor the value is added.
+ * <p>If the value is null, this method is a no-op.
+ *
+ * <p>Passing a {@link Collection} containing multiple elements to this method instead of {@link
+ * #addAll(Collection)} and similar is preferable if the caller knows that the given instance
+ * will be retained elsewhere. This method spends a single array slot on the {@link Collection}
+ * instead of copying over all of its elements, potentially saving memory if it is retained
+ * elsewhere.
*/
+ @CanIgnoreReturnValue
public Builder addObject(@Nullable Object value) {
return addObjectInternal(value);
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java
index e068205..c23d308b 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java
@@ -554,8 +554,8 @@
.processorClasses()
.toList()
.contains("dagger.internal.codegen.ComponentProcessor")) {
- // see b/31371210
- builder.addJavacOpt("-Aexperimental_turbine_hjar");
+ // See b/31371210 and b/142059842.
+ builder.addTurbineHjarJavacOpt();
}
builder.enableDirectClasspath(enableDirectClasspath);
builder.build(javaToolchain);
@@ -566,7 +566,7 @@
private JavaHeaderCompileAction.Builder getJavaHeaderCompileActionBuilder() {
JavaTargetAttributes attributes = getAttributes();
- JavaHeaderCompileAction.Builder builder = JavaHeaderCompileAction.newBuilder(getRuleContext());
+ JavaHeaderCompileAction.Builder builder = JavaHeaderCompileAction.newBuilder(ruleContext);
builder.setSourceFiles(attributes.getSourceFiles());
builder.setSourceJars(attributes.getSourceJars());
builder.setClasspathEntries(attributes.getCompileTimeClassPath());
@@ -574,7 +574,7 @@
// Exclude any per-package configured data (see JavaCommon.computePerPackageData).
// It is used to allow Error Prone checks to load additional data,
// and Error Prone doesn't run during header compilation.
- builder.addAllJavacOpts(getJavacOpts());
+ builder.setJavacOpts(customJavacOpts);
builder.setStrictJavaDeps(attributes.getStrictJavaDeps());
builder.setCompileTimeDependencyArtifacts(attributes.getCompileTimeDependencyArtifacts());
builder.setDirectJars(attributes.getDirectJars());
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompileActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompileActionBuilder.java
index f2ee559f..e79a0ab 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompileActionBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompileActionBuilder.java
@@ -322,7 +322,7 @@
result.addAll(
"--builtin_processors",
Sets.intersection(plugins.processorClasses().toSet(), builtinProcessorNames));
- result.addExecPaths("--source_jars", ImmutableList.copyOf(sourceJars));
+ result.addExecPaths("--source_jars", sourceJars);
result.addExecPaths("--sources", sourceFiles);
if (!javacOpts.isEmpty()) {
if (stripOutputPaths) {
@@ -338,7 +338,7 @@
"--javacopts",
javacOpts.stream().map(coptStripper::strip).collect(Collectors.toList()));
} else {
- result.addAll("--javacopts", javacOpts);
+ result.add("--javacopts").addObject(javacOpts);
}
// terminate --javacopts with `--` to support javac flags that start with `--`
result.add("--");
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaHeaderCompileAction.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaHeaderCompileAction.java
index 950d2e1..5bf8e62 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaHeaderCompileAction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaHeaderCompileAction.java
@@ -155,7 +155,8 @@
private NestedSet<Artifact> directJars = NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER);
private NestedSet<Artifact> compileTimeDependencyArtifacts =
NestedSetBuilder.emptySet(Order.STABLE_ORDER);
- private final ImmutableList.Builder<String> javacOptsBuilder = ImmutableList.builder();
+ private ImmutableList<String> javacOpts = ImmutableList.of();
+ private boolean addTurbineHjarJavacOpt = false;
private JavaPluginData plugins = JavaPluginData.empty();
private ImmutableList<Artifact> additionalInputs = ImmutableList.of();
@@ -210,17 +211,20 @@
return this;
}
- /** Adds Java compiler flags. */
+ /** Sets Java compiler flags. */
@CanIgnoreReturnValue
- public Builder addAllJavacOpts(Iterable<String> javacOpts) {
- this.javacOptsBuilder.addAll(javacOpts);
+ public Builder setJavacOpts(ImmutableList<String> javacOpts) {
+ this.javacOpts = checkNotNull(javacOpts);
return this;
}
- /** Adds a Java compiler flag. */
+ /**
+ * Adds {@code -Aexperimental_turbine_hjar} to Java compiler flags without creating an entirely
+ * new list.
+ */
@CanIgnoreReturnValue
- public Builder addJavacOpt(String javacOpt) {
- this.javacOptsBuilder.add(javacOpt);
+ public Builder addTurbineHjarJavacOpt() {
+ this.addTurbineHjarJavacOpt = true;
return this;
}
@@ -342,8 +346,6 @@
checkNotNull(
compileTimeDependencyArtifacts, "compileTimeDependencyArtifacts must not be null");
- ImmutableList<String> javacOpts = javacOptsBuilder.build();
-
// Invariant: if strictJavaDeps is OFF, then directJars and
// dependencyArtifacts are ignored
if (strictJavaDeps == StrictDepsMode.OFF) {
@@ -424,8 +426,14 @@
.addExecPaths("--source_jars", sourceJars)
.add("--injecting_rule_kind", injectingRuleKind);
- if (!javacOpts.isEmpty()) {
- commandLine.addAll("--javacopts", javacOpts);
+ if (!javacOpts.isEmpty() || addTurbineHjarJavacOpt) {
+ commandLine.add("--javacopts");
+ if (!javacOpts.isEmpty()) {
+ commandLine.addObject(javacOpts);
+ }
+ if (addTurbineHjarJavacOpt) {
+ commandLine.add("-Aexperimental_turbine_hjar");
+ }
// terminate --javacopts with `--` to support javac flags that start with `--`
commandLine.add("--");
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/SingleJarActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/java/SingleJarActionBuilder.java
index df63e9c..15289fd 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/SingleJarActionBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/SingleJarActionBuilder.java
@@ -146,7 +146,7 @@
NestedSet<Artifact> resourceJars) {
CustomCommandLine.Builder args = CustomCommandLine.builder();
args.addExecPath("--output", outputJar);
- args.addAll(SOURCE_JAR_COMMAND_LINE_ARGS);
+ args.addObject(SOURCE_JAR_COMMAND_LINE_ARGS);
args.addExecPaths("--sources", resourceJars);
if (!resources.isEmpty()) {
args.add("--resources");