aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/actions
diff options
context:
space:
mode:
authorGravatar tomlu <tomlu@google.com>2017-11-29 14:01:21 -0800
committerGravatar Copybara-Service <copybara-piper@google.com>2017-11-29 14:03:30 -0800
commit3d1a194ff9e76f25f1a7242ff2d021523ba8e4a0 (patch)
tree9fec583a59b8ee6ee0f4fac513d5471956dfe1d3 /src/main/java/com/google/devtools/build/lib/actions
parent8f8b8859fc7d85feee97481443fb11c0b7ae03ce (diff)
Add ActionKeyContext to Action#getKey.
This key context can be used by actions to share partial key computations, for instance when computing MD5s for nested sets. RELNOTES: None PiperOrigin-RevId: 177359607
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/actions')
-rw-r--r--src/main/java/com/google/devtools/build/lib/actions/AbstractAction.java16
-rw-r--r--src/main/java/com/google/devtools/build/lib/actions/Action.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/actions/ActionCacheChecker.java8
-rw-r--r--src/main/java/com/google/devtools/build/lib/actions/ActionExecutionContext.java12
-rw-r--r--src/main/java/com/google/devtools/build/lib/actions/ActionExecutionMetadata.java32
-rw-r--r--src/main/java/com/google/devtools/build/lib/actions/ActionKeyContext.java41
-rw-r--r--src/main/java/com/google/devtools/build/lib/actions/ActionLookupValue.java19
-rw-r--r--src/main/java/com/google/devtools/build/lib/actions/Actions.java25
-rw-r--r--src/main/java/com/google/devtools/build/lib/actions/BUILD1
-rw-r--r--src/main/java/com/google/devtools/build/lib/actions/FailAction.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/actions/MapBasedActionGraph.java22
-rw-r--r--src/main/java/com/google/devtools/build/lib/actions/MiddlemanAction.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/actions/MutableActionGraph.java22
13 files changed, 148 insertions, 57 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/actions/AbstractAction.java b/src/main/java/com/google/devtools/build/lib/actions/AbstractAction.java
index d1d805fcd5..04f74585c2 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/AbstractAction.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/AbstractAction.java
@@ -295,16 +295,17 @@ public abstract class AbstractAction implements Action, SkylarkValue {
/**
* See the javadoc for {@link com.google.devtools.build.lib.actions.Action} and {@link
- * com.google.devtools.build.lib.actions.ActionExecutionMetadata#getKey()} for the contract for
- * {@link #computeKey()}.
+ * ActionExecutionMetadata#getKey(ActionKeyContext)} for the contract for {@link
+ * #computeKey(ActionKeyContext)}.
*/
- protected abstract String computeKey() throws CommandLineExpansionException;
+ protected abstract String computeKey(ActionKeyContext actionKeyContext)
+ throws CommandLineExpansionException;
@Override
- public final synchronized String getKey() {
+ public final synchronized String getKey(ActionKeyContext actionKeyContext) {
if (cachedKey == null) {
try {
- cachedKey = computeKey();
+ cachedKey = computeKey(actionKeyContext);
} catch (CommandLineExpansionException e) {
cachedKey = KEY_ERROR;
}
@@ -481,12 +482,13 @@ public abstract class AbstractAction implements Action, SkylarkValue {
}
@Override
- public ExtraActionInfo.Builder getExtraActionInfo() throws CommandLineExpansionException {
+ public ExtraActionInfo.Builder getExtraActionInfo(ActionKeyContext actionKeyContext)
+ throws CommandLineExpansionException {
ActionOwner owner = getOwner();
ExtraActionInfo.Builder result =
ExtraActionInfo.newBuilder()
.setOwner(owner.getLabel().toString())
- .setId(getKey())
+ .setId(getKey(actionKeyContext))
.setMnemonic(getMnemonic());
Iterable<AspectDescriptor> aspectDescriptors = owner.getAspectDescriptors();
AspectDescriptor lastAspect = null;
diff --git a/src/main/java/com/google/devtools/build/lib/actions/Action.java b/src/main/java/com/google/devtools/build/lib/actions/Action.java
index e1c1b35cff..217ce5d59d 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/Action.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/Action.java
@@ -192,5 +192,6 @@ public interface Action extends ActionExecutionMetadata, Describable {
* <p>As this method is called from the ExtraAction, make sure it is ok to call this method from a
* different thread than the one this action is executed on.
*/
- ExtraActionInfo.Builder getExtraActionInfo() throws CommandLineExpansionException;
+ ExtraActionInfo.Builder getExtraActionInfo(ActionKeyContext actionKeyContext)
+ throws CommandLineExpansionException;
}
diff --git a/src/main/java/com/google/devtools/build/lib/actions/ActionCacheChecker.java b/src/main/java/com/google/devtools/build/lib/actions/ActionCacheChecker.java
index 8a49c9c40c..8e4dc88a46 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/ActionCacheChecker.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/ActionCacheChecker.java
@@ -74,6 +74,7 @@ public class ActionCacheChecker {
};
private final ActionCache actionCache;
+ private final ActionKeyContext actionKeyContext;
private final Predicate<? super Action> executionFilter;
private final ArtifactResolver artifactResolver;
private final CacheConfig cacheConfig;
@@ -103,10 +104,12 @@ public class ActionCacheChecker {
public ActionCacheChecker(
ActionCache actionCache,
ArtifactResolver artifactResolver,
+ ActionKeyContext actionKeyContext,
Predicate<? super Action> executionFilter,
@Nullable CacheConfig cacheConfig) {
this.actionCache = actionCache;
this.executionFilter = executionFilter;
+ this.actionKeyContext = actionKeyContext;
this.artifactResolver = artifactResolver;
this.cacheConfig =
cacheConfig != null
@@ -303,7 +306,7 @@ public class ActionCacheChecker {
reportChanged(handler, action);
actionCache.accountMiss(MissReason.DIFFERENT_FILES);
return true;
- } else if (!entry.getActionKey().equals(action.getKey())) {
+ } else if (!entry.getActionKey().equals(action.getKey(actionKeyContext))) {
reportCommand(handler, action);
actionCache.accountMiss(MissReason.DIFFERENT_ACTION_KEY);
return true;
@@ -356,7 +359,8 @@ public class ActionCacheChecker {
}
Map<String, String> usedClientEnv = computeUsedClientEnv(action, clientEnv);
ActionCache.Entry entry =
- new ActionCache.Entry(action.getKey(), usedClientEnv, action.discoversInputs());
+ new ActionCache.Entry(
+ action.getKey(actionKeyContext), usedClientEnv, action.discoversInputs());
for (Artifact output : action.getOutputs()) {
// Remove old records from the cache if they used different key.
String execPath = output.getExecPathString();
diff --git a/src/main/java/com/google/devtools/build/lib/actions/ActionExecutionContext.java b/src/main/java/com/google/devtools/build/lib/actions/ActionExecutionContext.java
index fc8a6bfb47..f356559a86 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/ActionExecutionContext.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/ActionExecutionContext.java
@@ -43,6 +43,7 @@ public class ActionExecutionContext implements Closeable {
private final Executor executor;
private final ActionInputFileCache actionInputFileCache;
private final ActionInputPrefetcher actionInputPrefetcher;
+ private final ActionKeyContext actionKeyContext;
private final MetadataHandler metadataHandler;
private final FileOutErr fileOutErr;
private final ImmutableMap<String, String> clientEnv;
@@ -54,6 +55,7 @@ public class ActionExecutionContext implements Closeable {
Executor executor,
ActionInputFileCache actionInputFileCache,
ActionInputPrefetcher actionInputPrefetcher,
+ ActionKeyContext actionKeyContext,
MetadataHandler metadataHandler,
FileOutErr fileOutErr,
Map<String, String> clientEnv,
@@ -61,6 +63,7 @@ public class ActionExecutionContext implements Closeable {
@Nullable SkyFunction.Environment env) {
this.actionInputFileCache = actionInputFileCache;
this.actionInputPrefetcher = actionInputPrefetcher;
+ this.actionKeyContext = actionKeyContext;
this.metadataHandler = metadataHandler;
this.fileOutErr = fileOutErr;
this.clientEnv = ImmutableMap.copyOf(clientEnv);
@@ -73,6 +76,7 @@ public class ActionExecutionContext implements Closeable {
Executor executor,
ActionInputFileCache actionInputFileCache,
ActionInputPrefetcher actionInputPrefetcher,
+ ActionKeyContext actionKeyContext,
MetadataHandler metadataHandler,
FileOutErr fileOutErr,
Map<String, String> clientEnv,
@@ -81,6 +85,7 @@ public class ActionExecutionContext implements Closeable {
executor,
actionInputFileCache,
actionInputPrefetcher,
+ actionKeyContext,
metadataHandler,
fileOutErr,
clientEnv,
@@ -92,6 +97,7 @@ public class ActionExecutionContext implements Closeable {
Executor executor,
ActionInputFileCache actionInputFileCache,
ActionInputPrefetcher actionInputPrefetcher,
+ ActionKeyContext actionKeyContext,
MetadataHandler metadataHandler,
FileOutErr fileOutErr,
Map<String, String> clientEnv,
@@ -100,6 +106,7 @@ public class ActionExecutionContext implements Closeable {
executor,
actionInputFileCache,
actionInputPrefetcher,
+ actionKeyContext,
metadataHandler,
fileOutErr,
clientEnv,
@@ -216,6 +223,10 @@ public class ActionExecutionContext implements Closeable {
return Preconditions.checkNotNull(env);
}
+ public ActionKeyContext getActionKeyContext() {
+ return actionKeyContext;
+ }
+
@Override
public void close() throws IOException {
fileOutErr.close();
@@ -230,6 +241,7 @@ public class ActionExecutionContext implements Closeable {
executor,
actionInputFileCache,
actionInputPrefetcher,
+ actionKeyContext,
metadataHandler,
fileOutErr,
clientEnv,
diff --git a/src/main/java/com/google/devtools/build/lib/actions/ActionExecutionMetadata.java b/src/main/java/com/google/devtools/build/lib/actions/ActionExecutionMetadata.java
index 7f4b569b13..ec94b6c72a 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/ActionExecutionMetadata.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/ActionExecutionMetadata.java
@@ -59,35 +59,36 @@ public interface ActionExecutionMetadata extends ActionAnalysisMetadata {
* <p>Examples of changes that should affect the key are:
*
* <ul>
- * <li>Changes to the BUILD file that materially affect the rule which gave rise to this Action.
- * <li>Changes to the command-line options, environment, or other global configuration resources
- * which affect the behaviour of this kind of Action (other than changes to the names of the
- * input/output files, which are handled externally).
- * <li>An upgrade to the build tools which changes the program logic of this kind of Action
- * (typically this is achieved by incorporating a UUID into the key, which is changed each
- * time the program logic of this action changes).
+ * <li>Changes to the BUILD file that materially affect the rule which gave rise to this Action.
+ * <li>Changes to the command-line options, environment, or other global configuration resources
+ * which affect the behaviour of this kind of Action (other than changes to the names of the
+ * input/output files, which are handled externally).
+ * <li>An upgrade to the build tools which changes the program logic of this kind of Action
+ * (typically this is achieved by incorporating a UUID into the key, which is changed each
+ * time the program logic of this action changes).
* </ul>
*/
- String getKey();
+ String getKey(ActionKeyContext actionKeyContext);
/**
- * Returns a human-readable description of the inputs to {@link #getKey()}.
- * Used in the output from '--explain', and in error messages for
- * '--check_up_to_date' and '--check_tests_up_to_date'.
- * May return null, meaning no extra information is available.
+ * Returns a human-readable description of the inputs to {@link #getKey(ActionKeyContext)}. Used
+ * in the output from '--explain', and in error messages for '--check_up_to_date' and
+ * '--check_tests_up_to_date'. May return null, meaning no extra information is available.
*
* <p>If the return value is non-null, for consistency it should be a multiline message of the
* form:
+ *
* <pre>
* <var>Summary</var>
* <var>Fieldname</var>: <var>value</var>
* <var>Fieldname</var>: <var>value</var>
* ...
* </pre>
+ *
* where each line after the first one is intended two spaces, and where any fields that might
* contain newlines or other funny characters are escaped using {@link
- * com.google.devtools.build.lib.shell.ShellUtils#shellEscape}.
- * For example:
+ * com.google.devtools.build.lib.shell.ShellUtils#shellEscape}. For example:
+ *
* <pre>
* Compiling foo.cc
* Command: /usr/bin/gcc
@@ -97,7 +98,8 @@ public interface ActionExecutionMetadata extends ActionAnalysisMetadata {
* Argument: foo.o
* </pre>
*/
- @Nullable String describeKey();
+ @Nullable
+ String describeKey();
/**
* Get the {@link RunfilesSupplier} providing runfiles needed by this action.
diff --git a/src/main/java/com/google/devtools/build/lib/actions/ActionKeyContext.java b/src/main/java/com/google/devtools/build/lib/actions/ActionKeyContext.java
new file mode 100644
index 0000000000..6ba29a7655
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/actions/ActionKeyContext.java
@@ -0,0 +1,41 @@
+// 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.actions;
+
+import com.google.devtools.build.lib.collect.nestedset.NestedSet;
+import com.google.devtools.build.lib.collect.nestedset.NestedSetFingerprintCache;
+import com.google.devtools.build.lib.util.Fingerprint;
+
+/** Contains state that aids in action key computation via {@link AbstractAction#computeKey}. */
+public class ActionKeyContext {
+ private static final class ArtifactNestedSetFingerprintCache
+ extends NestedSetFingerprintCache<Artifact> {
+ @Override
+ protected void addItemFingerprint(Fingerprint fingerprint, Artifact item) {
+ fingerprint.addPath(item.getExecPath());
+ }
+ }
+
+ private final ArtifactNestedSetFingerprintCache artifactNestedSetFingerprintCache =
+ new ArtifactNestedSetFingerprintCache();
+
+ public void addArtifactsToFingerprint(Fingerprint fingerprint, NestedSet<Artifact> artifacts) {
+ artifactNestedSetFingerprintCache.addNestedSetToFingerprint(fingerprint, artifacts);
+ }
+
+ public void clear() {
+ artifactNestedSetFingerprintCache.clear();
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/actions/ActionLookupValue.java b/src/main/java/com/google/devtools/build/lib/actions/ActionLookupValue.java
index bf6e3a0099..ffe650a19b 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/ActionLookupValue.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/ActionLookupValue.java
@@ -42,9 +42,9 @@ public class ActionLookupValue implements SkyValue {
private final ImmutableMap<Artifact, Integer> generatingActionIndex;
private static Actions.GeneratingActions filterSharedActionsAndThrowRuntimeIfConflict(
- List<ActionAnalysisMetadata> actions) {
+ ActionKeyContext actionKeyContext, List<ActionAnalysisMetadata> actions) {
try {
- return Actions.filterSharedActionsAndThrowActionConflict(actions);
+ return Actions.filterSharedActionsAndThrowActionConflict(actionKeyContext, actions);
} catch (ActionConflictException e) {
// Programming bug.
throw new IllegalStateException(e);
@@ -53,12 +53,19 @@ public class ActionLookupValue implements SkyValue {
@VisibleForTesting
public ActionLookupValue(
- List<ActionAnalysisMetadata> actions, boolean removeActionsAfterEvaluation) {
- this(filterSharedActionsAndThrowRuntimeIfConflict(actions), removeActionsAfterEvaluation);
+ ActionKeyContext actionKeyContext,
+ List<ActionAnalysisMetadata> actions,
+ boolean removeActionsAfterEvaluation) {
+ this(
+ filterSharedActionsAndThrowRuntimeIfConflict(actionKeyContext, actions),
+ removeActionsAfterEvaluation);
}
- protected ActionLookupValue(ActionAnalysisMetadata action, boolean removeActionAfterEvaluation) {
- this(ImmutableList.of(action), removeActionAfterEvaluation);
+ protected ActionLookupValue(
+ ActionKeyContext actionKeyContext,
+ ActionAnalysisMetadata action,
+ boolean removeActionAfterEvaluation) {
+ this(actionKeyContext, ImmutableList.of(action), removeActionAfterEvaluation);
}
protected ActionLookupValue(
diff --git a/src/main/java/com/google/devtools/build/lib/actions/Actions.java b/src/main/java/com/google/devtools/build/lib/actions/Actions.java
index 4acd7fefd7..91438261c7 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/Actions.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/Actions.java
@@ -54,7 +54,8 @@ public final class Actions {
* <p>This method implements an equivalence relationship across actions, based on the action
* class, the key, and the list of inputs and outputs.
*/
- public static boolean canBeShared(ActionAnalysisMetadata a, ActionAnalysisMetadata b) {
+ public static boolean canBeShared(
+ ActionKeyContext actionKeyContext, ActionAnalysisMetadata a, ActionAnalysisMetadata b) {
if (!a.getMnemonic().equals(b.getMnemonic())) {
return false;
}
@@ -66,7 +67,7 @@ public final class Actions {
Action actionA = (Action) a;
Action actionB = (Action) b;
- if (!actionA.getKey().equals(actionB.getKey())) {
+ if (!actionA.getKey(actionKeyContext).equals(actionB.getKey(actionKeyContext))) {
return false;
}
// Don't bother to check input and output counts first; the expected result for these tests is
@@ -89,10 +90,11 @@ public final class Actions {
* of indirection.
* @throws ActionConflictException iff there are two actions generate the same output
*/
- public static GeneratingActions findAndThrowActionConflict(List<ActionAnalysisMetadata> actions)
+ public static GeneratingActions findAndThrowActionConflict(
+ ActionKeyContext actionKeyContext, List<ActionAnalysisMetadata> actions)
throws ActionConflictException {
return Actions.maybeFilterSharedActionsAndThrowIfConflict(
- actions, /*allowSharedAction=*/ false);
+ actionKeyContext, actions, /*allowSharedAction=*/ false);
}
/**
@@ -106,13 +108,16 @@ public final class Actions {
* output
*/
public static GeneratingActions filterSharedActionsAndThrowActionConflict(
- List<ActionAnalysisMetadata> actions) throws ActionConflictException {
+ ActionKeyContext actionKeyContext, List<ActionAnalysisMetadata> actions)
+ throws ActionConflictException {
return Actions.maybeFilterSharedActionsAndThrowIfConflict(
- actions, /*allowSharedAction=*/ true);
+ actionKeyContext, actions, /*allowSharedAction=*/ true);
}
private static GeneratingActions maybeFilterSharedActionsAndThrowIfConflict(
- List<ActionAnalysisMetadata> actions, boolean allowSharedAction)
+ ActionKeyContext actionKeyContext,
+ List<ActionAnalysisMetadata> actions,
+ boolean allowSharedAction)
throws ActionConflictException {
Map<Artifact, Integer> generatingActions = new HashMap<>();
int actionIndex = 0;
@@ -120,8 +125,10 @@ public final class Actions {
for (Artifact artifact : action.getOutputs()) {
Integer previousIndex = generatingActions.put(artifact, actionIndex);
if (previousIndex != null && previousIndex != actionIndex) {
- if (!allowSharedAction || !Actions.canBeShared(actions.get(previousIndex), action)) {
- throw new ActionConflictException(artifact, actions.get(previousIndex), action);
+ if (!allowSharedAction
+ || !Actions.canBeShared(actionKeyContext, actions.get(previousIndex), action)) {
+ throw new ActionConflictException(
+ actionKeyContext, artifact, actions.get(previousIndex), action);
}
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/actions/BUILD b/src/main/java/com/google/devtools/build/lib/actions/BUILD
index f481e5f257..9b8d8bc600 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/actions/BUILD
@@ -28,6 +28,7 @@ java_library(
"//src/main/java/com/google/devtools/build/lib/causes",
"//src/main/java/com/google/devtools/build/lib/collect",
"//src/main/java/com/google/devtools/build/lib/collect/nestedset",
+ "//src/main/java/com/google/devtools/build/lib/collect/nestedset:fingerprint_cache",
"//src/main/java/com/google/devtools/build/lib/concurrent",
"//src/main/java/com/google/devtools/build/lib/profiler",
"//src/main/java/com/google/devtools/build/lib/shell",
diff --git a/src/main/java/com/google/devtools/build/lib/actions/FailAction.java b/src/main/java/com/google/devtools/build/lib/actions/FailAction.java
index 7f217409c8..86c22e0855 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/FailAction.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/FailAction.java
@@ -45,7 +45,7 @@ public final class FailAction extends AbstractAction {
}
@Override
- protected String computeKey() {
+ protected String computeKey(ActionKeyContext actionKeyContext) {
return GUID;
}
diff --git a/src/main/java/com/google/devtools/build/lib/actions/MapBasedActionGraph.java b/src/main/java/com/google/devtools/build/lib/actions/MapBasedActionGraph.java
index 9b27881aa6..f35f963bf7 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/MapBasedActionGraph.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/MapBasedActionGraph.java
@@ -23,9 +23,14 @@ import javax.annotation.concurrent.ThreadSafe;
*/
@ThreadSafe
public final class MapBasedActionGraph implements MutableActionGraph {
+ private final ActionKeyContext actionKeyContext;
private final ConcurrentMultimapWithHeadElement<Artifact, ActionAnalysisMetadata>
generatingActionMap = new ConcurrentMultimapWithHeadElement<>();
+ public MapBasedActionGraph(ActionKeyContext actionKeyContext) {
+ this.actionKeyContext = actionKeyContext;
+ }
+
@Override
@Nullable
public ActionAnalysisMetadata getGeneratingAction(Artifact artifact) {
@@ -36,10 +41,11 @@ public final class MapBasedActionGraph implements MutableActionGraph {
public void registerAction(ActionAnalysisMetadata action) throws ActionConflictException {
for (Artifact artifact : action.getOutputs()) {
ActionAnalysisMetadata previousAction = generatingActionMap.putAndGet(artifact, action);
- if (previousAction != null && previousAction != action
- && !Actions.canBeShared(action, previousAction)) {
+ if (previousAction != null
+ && previousAction != action
+ && !Actions.canBeShared(actionKeyContext, action, previousAction)) {
generatingActionMap.remove(artifact, action);
- throw new ActionConflictException(artifact, previousAction, action);
+ throw new ActionConflictException(actionKeyContext, artifact, previousAction, action);
}
}
}
@@ -49,9 +55,13 @@ public final class MapBasedActionGraph implements MutableActionGraph {
for (Artifact artifact : action.getOutputs()) {
generatingActionMap.remove(artifact, action);
ActionAnalysisMetadata otherAction = generatingActionMap.get(artifact);
- Preconditions.checkState(otherAction == null
- || (otherAction != action && Actions.canBeShared(action, otherAction)),
- "%s %s", action, otherAction);
+ Preconditions.checkState(
+ otherAction == null
+ || (otherAction != action
+ && Actions.canBeShared(actionKeyContext, action, otherAction)),
+ "%s %s",
+ action,
+ otherAction);
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/actions/MiddlemanAction.java b/src/main/java/com/google/devtools/build/lib/actions/MiddlemanAction.java
index f0c5972c6a..787f05248d 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/MiddlemanAction.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/MiddlemanAction.java
@@ -56,7 +56,7 @@ public final class MiddlemanAction extends AbstractAction {
}
@Override
- protected String computeKey() {
+ protected String computeKey(ActionKeyContext actionKeyContext) {
// TODO(bazel-team): Need to take middlemanType into account here.
// Only the set of inputs matters, and the dependency checker is
// responsible for considering those.
diff --git a/src/main/java/com/google/devtools/build/lib/actions/MutableActionGraph.java b/src/main/java/com/google/devtools/build/lib/actions/MutableActionGraph.java
index 1b1955a5e5..24a74ad28c 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/MutableActionGraph.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/MutableActionGraph.java
@@ -61,15 +61,19 @@ public interface MutableActionGraph extends ActionGraph {
* about the artifact for which the conflict is found, and data about the two conflicting actions
* and their owners.
*/
- public static final class ActionConflictException extends Exception {
+ final class ActionConflictException extends Exception {
+ private final ActionKeyContext actionKeyContext;
private final Artifact artifact;
private final ActionAnalysisMetadata previousAction;
private final ActionAnalysisMetadata attemptedAction;
private static final int MAX_DIFF_ARTIFACTS_TO_REPORT = 5;
- public ActionConflictException(Artifact artifact, ActionAnalysisMetadata previousAction,
+ public ActionConflictException(
+ ActionKeyContext actionKeyContext,
+ Artifact artifact,
+ ActionAnalysisMetadata previousAction,
ActionAnalysisMetadata attemptedAction) {
super(
String.format(
@@ -77,6 +81,7 @@ public interface MutableActionGraph extends ActionGraph {
artifact.prettyPrint(),
previousAction.prettyPrint(),
attemptedAction.prettyPrint()));
+ this.actionKeyContext = actionKeyContext;
this.artifact = artifact;
this.previousAction = previousAction;
this.attemptedAction = attemptedAction;
@@ -91,7 +96,7 @@ public interface MutableActionGraph extends ActionGraph {
"file '"
+ artifact.prettyPrint()
+ "' is generated by these conflicting actions:\n"
- + suffix(attemptedAction, previousAction);
+ + suffix(actionKeyContext, attemptedAction, previousAction);
eventListener.handle(Event.error(msg));
}
@@ -143,14 +148,13 @@ public interface MutableActionGraph extends ActionGraph {
}
}
- private static String getKey(ActionAnalysisMetadata action) {
- return action instanceof Action
- ? ((Action) action).getKey()
- : null;
+ private static String getKey(ActionKeyContext actionKeyContext, ActionAnalysisMetadata action) {
+ return action instanceof Action ? ((Action) action).getKey(actionKeyContext) : null;
}
// See also Actions.canBeShared()
- private static String suffix(ActionAnalysisMetadata a, ActionAnalysisMetadata b) {
+ private static String suffix(
+ ActionKeyContext actionKeyContext, ActionAnalysisMetadata a, ActionAnalysisMetadata b) {
// Note: the error message reveals to users the names of intermediate files that are not
// documented in the BUILD language. This error-reporting logic is rather elaborate but it
// does help to diagnose some tricky situations.
@@ -167,7 +171,7 @@ public interface MutableActionGraph extends ActionGraph {
addStringDetail(sb, "Configuration", aNull ? null : aOwner.getConfigurationChecksum(),
bNull ? null : bOwner.getConfigurationChecksum());
addStringDetail(sb, "Mnemonic", a.getMnemonic(), b.getMnemonic());
- addStringDetail(sb, "Action key", getKey(a), getKey(b));
+ addStringDetail(sb, "Action key", getKey(actionKeyContext, a), getKey(actionKeyContext, b));
if ((a instanceof ActionExecutionMetadata) && (b instanceof ActionExecutionMetadata)) {
addStringDetail(