Inline CppCompileAction.execWithReply
This allows us to remove CppCompileActionResult, and also simplifies the
code.
This is in preparation for async C++ compile action execution.
Progress on #6394.
PiperOrigin-RevId: 239366249
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java
index 0d66294..a2c1a67 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java
@@ -64,7 +64,6 @@
import com.google.devtools.build.lib.profiler.SilentCloseable;
import com.google.devtools.build.lib.rules.cpp.CcCommon.CoptsFilter;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration;
-import com.google.devtools.build.lib.rules.cpp.CppCompileActionResult.Reply;
import com.google.devtools.build.lib.rules.cpp.IncludeScanner.IncludeScanningHeaderData;
import com.google.devtools.build.lib.skyframe.ActionExecutionValue;
import com.google.devtools.build.lib.util.DependencySet;
@@ -1188,12 +1187,15 @@
}
}
- CppCompileActionResult.Reply reply;
List<SpawnResult> spawnResults;
+ byte[] dotDContents;
try (Defer ignored = new Defer()) {
- CppCompileActionResult cppCompileActionResult = execWithReply(spawnContext);
- reply = cppCompileActionResult.contextReply();
- spawnResults = cppCompileActionResult.spawnResults();
+ Spawn spawn = createSpawn(actionExecutionContext.getClientEnv());
+ SpawnActionContext context = actionExecutionContext.getContext(SpawnActionContext.class);
+ spawnResults = context.exec(spawn, spawnContext);
+ // SpawnActionContext guarantees that the first list entry exists and corresponds to the
+ // executed spawn.
+ dotDContents = getDotDContents(spawnResults.get(0));
} catch (ExecException e) {
throw e.toActionExecutionException(
"C++ compilation of rule '" + getOwner().getLabel() + "'",
@@ -1226,9 +1228,12 @@
} else {
discoveredInputs =
discoverInputsFromDotdFiles(
- actionExecutionContext, execRoot, scanningContext.getArtifactResolver(), reply);
+ actionExecutionContext,
+ execRoot,
+ scanningContext.getArtifactResolver(),
+ dotDContents);
}
- reply = null; // Clear in-memory .d files early.
+ dotDContents = null; // Garbage collect in-memory .d contents.
if (discoversInputs()) {
// Post-execute "include scanning", which modifies the action inputs to match what the compile
@@ -1251,8 +1256,21 @@
return ActionResult.create(spawnResults);
}
- protected CppCompileActionResult execWithReply(ActionExecutionContext actionExecutionContext)
- throws ExecException, InterruptedException {
+ protected byte[] getDotDContents(SpawnResult spawnResult) throws EnvironmentalExecException {
+ if (getDotdFile() != null) {
+ InputStream in = spawnResult.getInMemoryOutput(getDotdFile());
+ if (in != null) {
+ try {
+ return ByteStreams.toByteArray(in);
+ } catch (IOException e) {
+ throw new EnvironmentalExecException("Reading in-memory .d file failed", e);
+ }
+ }
+ }
+ return null;
+ }
+
+ protected Spawn createSpawn(Map<String, String> clientEnv) {
// Intentionally not adding {@link CppCompileAction#inputsForInvalidation}, those are not needed
// for execution.
ImmutableList.Builder<ActionInput> inputsBuilder =
@@ -1263,7 +1281,6 @@
inputsBuilder.add(getParamFileActionInput());
}
ImmutableList<ActionInput> inputs = inputsBuilder.build();
- clearAdditionalInputs();
ImmutableMap<String, String> executionInfo = getExecutionInfo();
ImmutableList.Builder<ActionInput> outputs =
@@ -1288,38 +1305,14 @@
.build();
}
- Spawn spawn =
- new SimpleSpawn(
- this,
- ImmutableList.copyOf(getArguments()),
- getEnvironment(actionExecutionContext.getClientEnv()),
- executionInfo,
- inputs,
- outputs.build(),
- estimateResourceConsumptionLocal());
-
- SpawnActionContext context = actionExecutionContext.getContext(SpawnActionContext.class);
- List<SpawnResult> spawnResults = context.exec(spawn, actionExecutionContext);
- // The SpawnActionContext guarantees that the first list entry is the successful one.
- SpawnResult spawnResult = spawnResults.get(0);
-
- CppCompileActionResult.Builder cppCompileActionResultBuilder =
- CppCompileActionResult.builder().setSpawnResults(spawnResults);
-
- if (getDotdFile() != null) {
- InputStream in = spawnResult.getInMemoryOutput(getDotdFile());
- if (in != null) {
- byte[] contents;
- try {
- contents = ByteStreams.toByteArray(in);
- } catch (IOException e) {
- throw new EnvironmentalExecException("Reading in-memory .d file failed", e);
- }
- cppCompileActionResultBuilder.setContextReply(
- new CppCompileActionResult.InMemoryFile(contents));
- }
- }
- return cppCompileActionResultBuilder.build();
+ return new SimpleSpawn(
+ this,
+ ImmutableList.copyOf(getArguments()),
+ getEnvironment(clientEnv),
+ executionInfo,
+ inputs,
+ outputs.build(),
+ estimateResourceConsumptionLocal());
}
@VisibleForTesting
@@ -1355,7 +1348,7 @@
ActionExecutionContext actionExecutionContext,
Path execRoot,
ArtifactResolver artifactResolver,
- Reply reply)
+ byte[] dotDContents)
throws ActionExecutionException {
if (!needsDotdInputPruning || getDotdFile() == null) {
return NestedSetBuilder.emptySet(Order.STABLE_ORDER);
@@ -1365,7 +1358,7 @@
.setAction(this)
.setSourceFile(getSourceFile())
.setDependencies(
- processDepset(actionExecutionContext, execRoot, reply).getDependencies())
+ processDepset(actionExecutionContext, execRoot, dotDContents).getDependencies())
.setPermittedSystemIncludePrefixes(getPermittedSystemIncludePrefixes(execRoot))
.setAllowedDerivedinputs(getAllowedDerivedInputs());
@@ -1377,12 +1370,12 @@
}
public DependencySet processDepset(
- ActionExecutionContext actionExecutionContext, Path execRoot, Reply reply)
+ ActionExecutionContext actionExecutionContext, Path execRoot, byte[] dotDContents)
throws ActionExecutionException {
try {
DependencySet depSet = new DependencySet(execRoot);
- if (reply != null && cppConfiguration.getInmemoryDotdFiles()) {
- return depSet.process(reply.getContents());
+ if (dotDContents != null && cppConfiguration.getInmemoryDotdFiles()) {
+ return depSet.process(dotDContents);
}
return depSet.read(actionExecutionContext.getInputPath(getDotdFile()));
} catch (IOException e) {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileActionResult.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileActionResult.java
deleted file mode 100644
index 076fff7..0000000
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileActionResult.java
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2017 The Bazel Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.devtools.build.lib.rules.cpp;
-
-import com.google.auto.value.AutoValue;
-import com.google.common.collect.ImmutableList;
-import com.google.devtools.build.lib.actions.SpawnResult;
-import java.io.IOException;
-import java.util.List;
-import javax.annotation.Nullable;
-
-/** Contains information about the result of a CppCompileAction's execution. */
-@AutoValue
-public abstract class CppCompileActionResult {
- /** Reply for the execution of a C++ compilation. */
- public interface Reply {
- /** Returns the contents of the .d file. */
- byte[] getContents() throws IOException;
- }
-
- /** A simple in-memory implementation of Reply. */
- public static class InMemoryFile implements Reply {
- private final byte[] contents;
-
- public InMemoryFile(byte[] contents) {
- this.contents = contents;
- }
-
- @Override
- public byte[] getContents() {
- return contents;
- }
- }
-
- /** Returns the SpawnResults created by the action, if any. */
- public abstract List<SpawnResult> spawnResults();
-
- /**
- * Gets the optional CppCompileActionContext.Reply for the action.
- *
- * <p>Could be null if there is no reply (e.g. if there is no .d file documenting which #include
- * statements are actually required.)
- */
- @Nullable
- public abstract Reply contextReply();
-
- /** Returns a builder that can be used to construct a {@link CppCompileActionResult} object. */
- public static Builder builder() {
- return new AutoValue_CppCompileActionResult.Builder();
- }
-
- /** Builder for a {@link CppCompileActionResult} instance, which is immutable once built. */
- @AutoValue.Builder
- public abstract static class Builder {
-
- /** Returns the SpawnResults for the action, if any. */
- abstract List<SpawnResult> spawnResults();
-
- /** Sets the SpawnResults for the action. */
- public abstract Builder setSpawnResults(List<SpawnResult> spawnResults);
-
- /** Sets the CppCompileActionContext.Reply for the action. */
- public abstract Builder setContextReply(Reply reply);
-
- abstract CppCompileActionResult realBuild();
-
- /**
- * Returns an immutable CppCompileActionResult object.
- *
- * <p>The list of SpawnResults is also made immutable here.
- */
- public CppCompileActionResult build() {
- return this.setSpawnResults(ImmutableList.copyOf(spawnResults())).realBuild();
- }
- }
-}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/FakeCppCompileAction.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/FakeCppCompileAction.java
index cfe0cf9..b916960 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/FakeCppCompileAction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/FakeCppCompileAction.java
@@ -29,6 +29,8 @@
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.ExecException;
import com.google.devtools.build.lib.actions.ResourceSet;
+import com.google.devtools.build.lib.actions.Spawn;
+import com.google.devtools.build.lib.actions.SpawnActionContext;
import com.google.devtools.build.lib.actions.SpawnResult;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
@@ -131,16 +133,20 @@
// First, do a normal compilation, to generate the ".d" file. The generated object file is built
// to a temporary location (tempOutputFile) and ignored afterwards.
logger.info("Generating " + getDotdFile());
- CppCompileActionResult.Reply reply = null;
+ byte[] dotDContents = null;
try {
- CppCompileActionResult cppCompileActionResult = execWithReply(actionExecutionContext);
- reply = cppCompileActionResult.contextReply();
- spawnResults = cppCompileActionResult.spawnResults();
+ Spawn spawn = createSpawn(actionExecutionContext.getClientEnv());
+ SpawnActionContext context = actionExecutionContext.getContext(SpawnActionContext.class);
+ spawnResults = context.exec(spawn, actionExecutionContext);
+ // The SpawnActionContext guarantees that the first list entry is the successful one.
+ dotDContents = getDotDContents(spawnResults.get(0));
} catch (ExecException e) {
throw e.toActionExecutionException(
"C++ compilation of rule '" + getOwner().getLabel() + "'",
actionExecutionContext.getVerboseFailures(),
this);
+ } finally {
+ clearAdditionalInputs();
}
CppIncludeExtractionContext scanningContext =
actionExecutionContext.getContext(CppIncludeExtractionContext.class);
@@ -155,7 +161,7 @@
.setAction(this)
.setSourceFile(getSourceFile())
.setDependencies(
- processDepset(actionExecutionContext, execRoot, reply).getDependencies())
+ processDepset(actionExecutionContext, execRoot, dotDContents).getDependencies())
.setPermittedSystemIncludePrefixes(getPermittedSystemIncludePrefixes(execRoot))
.setAllowedDerivedinputs(getAllowedDerivedInputs());
@@ -169,7 +175,7 @@
.discoverInputsFromDependencies(execRoot, scanningContext.getArtifactResolver());
}
- reply = null; // Clear in-memory .d files early.
+ dotDContents = null; // Garbage collect in-memory .d contents.
// Even cc_fake_binary rules need to properly declare their dependencies...
// In fact, they need to declare their dependencies even more than cc_binary rules do.