aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/skyframe
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/skyframe')
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/ActionArtifactCycleReporter.java24
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/ActionExecutionValue.java33
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/ArtifactFunction.java11
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/ArtifactSkyKey.java129
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/CompletionFunction.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java1
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/SkyframeActionExecutor.java19
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java5
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/StateInformingSkyFunctionEnvironment.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/TestCompletionFunction.java2
10 files changed, 98 insertions, 132 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ActionArtifactCycleReporter.java b/src/main/java/com/google/devtools/build/lib/skyframe/ActionArtifactCycleReporter.java
index ae4ced6fb3..81120765cb 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ActionArtifactCycleReporter.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ActionArtifactCycleReporter.java
@@ -18,6 +18,7 @@ import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.ActionLookupData;
+import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.pkgcache.PackageProvider;
import com.google.devtools.build.lib.skyframe.TargetCompletionValue.TargetCompletionKey;
@@ -31,11 +32,12 @@ import com.google.devtools.build.skyframe.SkyKey;
*/
public class ActionArtifactCycleReporter extends AbstractLabelCycleReporter {
@SuppressWarnings("unchecked")
- private static final Predicate<SkyKey> IS_ARTIFACT_OR_ACTION_SKY_KEY = Predicates.or(
- SkyFunctions.isSkyFunction(SkyFunctions.ARTIFACT),
- SkyFunctions.isSkyFunction(SkyFunctions.ACTION_EXECUTION),
- SkyFunctions.isSkyFunction(SkyFunctions.TARGET_COMPLETION),
- SkyFunctions.isSkyFunction(SkyFunctions.TEST_COMPLETION));
+ private static final Predicate<SkyKey> IS_ARTIFACT_OR_ACTION_SKY_KEY =
+ Predicates.or(
+ SkyFunctions.isSkyFunction(Artifact.ARTIFACT),
+ SkyFunctions.isSkyFunction(SkyFunctions.ACTION_EXECUTION),
+ SkyFunctions.isSkyFunction(SkyFunctions.TARGET_COMPLETION),
+ SkyFunctions.isSkyFunction(SkyFunctions.TEST_COMPLETION));
ActionArtifactCycleReporter(PackageProvider packageProvider) {
super(packageProvider);
@@ -46,9 +48,15 @@ public class ActionArtifactCycleReporter extends AbstractLabelCycleReporter {
return prettyPrint(key.functionName(), key.argument());
}
- private String prettyPrint(SkyFunctionName skyFunctionName, Object arg) {
+ private static String prettyPrintArtifact(Artifact artifact) {
+ return "file: " + artifact.getRootRelativePathString();
+ }
+
+ private static String prettyPrint(SkyFunctionName skyFunctionName, Object arg) {
if (arg instanceof ArtifactSkyKey) {
- return "file: " + ((ArtifactSkyKey) arg).getArtifact().getRootRelativePathString();
+ return prettyPrintArtifact(((ArtifactSkyKey) arg).getArtifact());
+ } else if (arg instanceof Artifact) {
+ return prettyPrintArtifact(((Artifact) arg));
} else if (arg instanceof ActionLookupData) {
return "action from: " + arg;
} else if (arg instanceof TargetCompletionKey
@@ -67,6 +75,8 @@ public class ActionArtifactCycleReporter extends AbstractLabelCycleReporter {
Object arg = key.argument();
if (arg instanceof ArtifactSkyKey) {
return ((ArtifactSkyKey) arg).getArtifact().getOwner();
+ } else if (arg instanceof Artifact) {
+ return ((Artifact) arg).getOwner();
} else if (arg instanceof ActionLookupData) {
return ((ActionLookupData) arg).getLabelForErrors();
} else if (arg instanceof TargetCompletionKey
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ActionExecutionValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/ActionExecutionValue.java
index 8ddb52a905..687a787628 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ActionExecutionValue.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ActionExecutionValue.java
@@ -19,10 +19,12 @@ import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.devtools.build.lib.actions.ActionLookupData;
import com.google.devtools.build.lib.actions.ActionLookupValue;
import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.actions.Artifact.OwnerlessArtifactWrapper;
import com.google.devtools.build.lib.actions.FileArtifactValue;
import com.google.devtools.build.lib.actions.FileStateValue;
import com.google.devtools.build.lib.actions.FileValue;
@@ -33,6 +35,8 @@ import com.google.devtools.build.lib.vfs.RootedPath;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
import javax.annotation.Nullable;
/**
@@ -196,4 +200,33 @@ public class ActionExecutionValue implements SkyValue {
}
return value;
}
+
+ private static <V> ImmutableMap<Artifact, V> transformKeys(
+ ImmutableMap<Artifact, V> data, Map<OwnerlessArtifactWrapper, Artifact> newArtifactMap) {
+ if (data.isEmpty()) {
+ return data;
+ }
+ ImmutableMap.Builder<Artifact, V> result = ImmutableMap.builderWithExpectedSize(data.size());
+ for (Map.Entry<Artifact, V> entry : data.entrySet()) {
+ Artifact transformedArtifact =
+ Preconditions.checkNotNull(
+ newArtifactMap.get(new OwnerlessArtifactWrapper(entry.getKey())), entry);
+ result.put(transformedArtifact, entry.getValue());
+ }
+ return result.build();
+ }
+
+ ActionExecutionValue transformForSharedAction(ImmutableSet<Artifact> outputs) {
+ Map<OwnerlessArtifactWrapper, Artifact> newArtifactMap =
+ outputs
+ .stream()
+ .collect(Collectors.toMap(OwnerlessArtifactWrapper::new, Function.identity()));
+ // This is only called for shared actions, so we'll almost certainly have to transform all keys
+ // in all sets.
+ return new ActionExecutionValue(
+ transformKeys(artifactData, newArtifactMap),
+ transformKeys(treeArtifactData, newArtifactMap),
+ transformKeys(additionalOutputData, newArtifactMap),
+ outputSymlinks);
+ }
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactFunction.java
index 6913091c73..fbf3ec00d3 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactFunction.java
@@ -53,11 +53,11 @@ class ArtifactFunction implements SkyFunction {
@Override
public SkyValue compute(SkyKey skyKey, Environment env)
throws ArtifactFunctionException, InterruptedException {
- ArtifactSkyKey artifactSkyKey = (ArtifactSkyKey) skyKey.argument();
- Artifact artifact = artifactSkyKey.getArtifact();
+ Artifact artifact = ArtifactSkyKey.artifact(skyKey);
+ boolean isMandatory = ArtifactSkyKey.isMandatory(skyKey);
if (artifact.isSourceArtifact()) {
try {
- return createSourceValue(artifact, artifactSkyKey.isMandatory(), env);
+ return createSourceValue(artifact, isMandatory, env);
} catch (MissingInputFileException e) {
// The error is not necessarily truly transient, but we mark it as such because we have
// the above side effect of posting an event to the EventBus. Importantly, that event
@@ -279,8 +279,7 @@ class ArtifactFunction implements SkyFunction {
throws InterruptedException {
// This artifact aggregates other artifacts. Keep track of them so callers can find them.
ImmutableList.Builder<Pair<Artifact, FileArtifactValue>> inputs = ImmutableList.builder();
- for (Map.Entry<SkyKey, SkyValue> entry :
- env.getValues(ArtifactSkyKey.mandatoryKeys(action.getInputs())).entrySet()) {
+ for (Map.Entry<SkyKey, SkyValue> entry : env.getValues(action.getInputs()).entrySet()) {
Artifact input = ArtifactSkyKey.artifact(entry.getKey());
SkyValue inputValue = entry.getValue();
Preconditions.checkNotNull(inputValue, "%s has null dep %s", artifact, input);
@@ -316,7 +315,7 @@ class ArtifactFunction implements SkyFunction {
@Override
public String extractTag(SkyKey skyKey) {
- return Label.print(((ArtifactSkyKey) skyKey.argument()).getArtifact().getOwner());
+ return Label.print(ArtifactSkyKey.artifact(skyKey).getOwner());
}
@VisibleForTesting
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactSkyKey.java b/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactSkyKey.java
index 20d9e97bb5..e63b73c5b0 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactSkyKey.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactSkyKey.java
@@ -13,135 +13,63 @@
// limitations under the License.
package com.google.devtools.build.lib.skyframe;
-import com.google.common.base.Function;
import com.google.common.base.Preconditions;
-import com.google.common.collect.Collections2;
import com.google.common.collect.Interner;
-import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.concurrent.BlazeInterners;
import com.google.devtools.build.lib.concurrent.ThreadSafety;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.skyframe.SkyFunctionName;
import com.google.devtools.build.skyframe.SkyKey;
-import java.util.Collection;
/**
- * A {@link SkyKey} coming from an {@link Artifact}. Source artifacts are checked for existence,
- * while output artifacts imply creation of the output file.
+ * A {@link SkyKey} coming from an {@link Artifact} that is not mandatory: absence of the Artifact
+ * does not imply any error.
*
- * <p>There are effectively three kinds of output artifact values corresponding to these keys. The
- * first corresponds to an ordinary artifact {@link FileArtifactValue}. It stores the relevant data
- * for the artifact -- digest/mtime and size. The second corresponds to either an "aggregating"
- * artifact -- the output of an aggregating middleman action -- or a TreeArtifact. It stores the
- * relevant data of all its inputs, as well as a combined digest for itself.
- *
- * <p>Artifacts are compared using just their paths, but in Skyframe, the configured target that
- * owns an artifact must also be part of the comparison. For example, suppose we build //foo:foo in
- * configurationA, yielding artifact foo.out. If we change the configuration to configurationB in
- * such a way that the path to the artifact does not change, requesting foo.out from the graph will
- * result in the value entry for foo.out under configurationA being returned. This would prevent
- * caching the graph in different configurations, and also causes big problems with change pruning,
- * which assumes the invariant that a value's first dependency will always be the same. In this
- * case, the value entry's old dependency on //foo:foo in configurationA would cause it to request
- * (//foo:foo, configurationA) from the graph, causing an undesired re-analysis of (//foo:foo,
- * configurationA).
- *
- * <p>In order to prevent that, instead of just comparing Artifacts, we compare for equality using
- * both the Artifact, and the owner. The effect is functionally that of making Artifact.equals()
- * check the owner, but only within these keys, since outside of Skyframe it is quite crucial that
- * Artifacts with different owners be able to compare equal.
+ * <p>Since {@link Artifact} is already a {@link SkyKey}, this wrapper is only needed when the
+ * {@link Artifact} is not mandatory (discovered during include scanning).
*/
+// TODO(janakr): pull mandatory/non-mandatory handling up to consumers and get rid of this wrapper.
@AutoCodec
public class ArtifactSkyKey implements SkyKey {
private static final Interner<ArtifactSkyKey> INTERNER = BlazeInterners.newWeakInterner();
- private static final Function<Artifact, SkyKey> TO_MANDATORY_KEY =
- artifact -> key(artifact, true);
- private static final Function<ArtifactSkyKey, Artifact> TO_ARTIFACT = ArtifactSkyKey::getArtifact;
- private final Artifact artifact;
- // Always true for derived artifacts.
- private final boolean isMandatory;
- // TODO(janakr): we may want to remove this field in the future. The expensive hash computation
- // is already cached one level down (in the Artifact), so the CPU overhead here may not be
- // worth the memory. However, when running with +CompressedOops, this field is free, so we leave
- // it. When running with -CompressedOops, we might be able to save memory by using polymorphism
- // for isMandatory and dropping this field.
- private int hashCode = 0;
+ private final Artifact.SourceArtifact artifact;
- private ArtifactSkyKey(Artifact sourceArtifact, boolean mandatory) {
- Preconditions.checkArgument(sourceArtifact.isSourceArtifact());
+ private ArtifactSkyKey(Artifact.SourceArtifact sourceArtifact) {
this.artifact = Preconditions.checkNotNull(sourceArtifact);
- this.isMandatory = mandatory;
- }
-
- /**
- * Constructs an ArtifactSkyKey for a derived artifact. The mandatory attribute is not needed
- * because a derived artifact must be a mandatory input for some action in order to ensure that it
- * is built in the first place. If it fails to build, then that fact is cached in the node, so any
- * action that has it as a non-mandatory input can retrieve that information from the node.
- */
- private ArtifactSkyKey(Artifact derivedArtifact) {
- this.artifact = Preconditions.checkNotNull(derivedArtifact);
- Preconditions.checkArgument(!derivedArtifact.isSourceArtifact(), derivedArtifact);
- this.isMandatory = true; // Unused.
}
@ThreadSafety.ThreadSafe
- @AutoCodec.Instantiator
- public static ArtifactSkyKey key(Artifact artifact, boolean isMandatory) {
- return INTERNER.intern(
- artifact.isSourceArtifact()
- ? new ArtifactSkyKey(artifact, isMandatory)
- : new ArtifactSkyKey(artifact));
+ public static SkyKey key(Artifact artifact, boolean isMandatory) {
+ if (isMandatory || !artifact.isSourceArtifact()) {
+ return artifact;
+ }
+ return create(((Artifact.SourceArtifact) artifact));
}
- @ThreadSafety.ThreadSafe
- static Iterable<SkyKey> mandatoryKeys(Iterable<Artifact> artifacts) {
- return Iterables.transform(artifacts, TO_MANDATORY_KEY);
+ @AutoCodec.VisibleForSerialization
+ @AutoCodec.Instantiator
+ static ArtifactSkyKey create(Artifact.SourceArtifact artifact) {
+ return INTERNER.intern(new ArtifactSkyKey(artifact));
}
- public static Collection<Artifact> artifacts(Collection<? extends ArtifactSkyKey> keys) {
- return Collections2.transform(keys, TO_ARTIFACT);
+ public static Artifact artifact(SkyKey key) {
+ return key instanceof Artifact ? (Artifact) key : ((ArtifactSkyKey) key).artifact;
}
- public static Artifact artifact(SkyKey key) {
- return TO_ARTIFACT.apply((ArtifactSkyKey) key.argument());
+ public static boolean isMandatory(SkyKey key) {
+ return key instanceof Artifact;
}
@Override
public SkyFunctionName functionName() {
- return SkyFunctions.ARTIFACT;
+ return Artifact.ARTIFACT;
}
@Override
public int hashCode() {
- // We use the hash code caching strategy employed by java.lang.String. There are three subtle
- // things going on here:
- //
- // (1) We use a value of 0 to indicate that the hash code hasn't been computed and cached yet.
- // Yes, this means that if the hash code is really 0 then we will "recompute" it each time.
- // But this isn't a problem in practice since a hash code of 0 should be rare.
- //
- // (2) Since we have no synchronization, multiple threads can race here thinking there are the
- // first one to compute and cache the hash code.
- //
- // (3) Moreover, since 'hashCode' is non-volatile, the cached hash code value written from one
- // thread may not be visible by another. Note that we probably don't need to worry about
- // multiple inefficient reads of 'hashCode' on the same thread since it's non-volatile.
- //
- // All three of these issues are benign from a correctness perspective; in the end we have no
- // overhead from synchronization, at the cost of potentially computing the hash code more than
- // once.
- if (hashCode == 0) {
- hashCode = computeHashCode();
- }
- return hashCode;
- }
-
- private int computeHashCode() {
- int initialHash = artifact.hashCode() + artifact.getArtifactOwner().hashCode();
- return isMandatory ? initialHash : 47 * initialHash + 1;
+ return artifact.hashCode();
}
@Override
@@ -153,24 +81,13 @@ public class ArtifactSkyKey implements SkyKey {
return false;
}
ArtifactSkyKey thatArtifactSkyKey = ((ArtifactSkyKey) that);
- return Artifact.equalWithOwner(artifact, thatArtifactSkyKey.artifact)
- && isMandatory == thatArtifactSkyKey.isMandatory;
+ return artifact.equals(thatArtifactSkyKey.artifact);
}
Artifact getArtifact() {
return artifact;
}
- /**
- * Returns whether the artifact is a mandatory input of its requesting action. May only be called
- * for source artifacts, since a derived artifact must be a mandatory input of some action in
- * order to have been built in the first place.
- */
- public boolean isMandatory() {
- Preconditions.checkState(artifact.isSourceArtifact(), artifact);
- return isMandatory;
- }
-
@Override
public String toString() {
return artifact.prettyPrint() + " " + artifact.getArtifactOwner();
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/CompletionFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/CompletionFunction.java
index de70aa1af0..3916b7b4a6 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/CompletionFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/CompletionFunction.java
@@ -302,8 +302,7 @@ public final class CompletionFunction<TValue extends SkyValue, TResult extends S
Map<SkyKey, ValueOrException2<MissingInputFileException, ActionExecutionException>> inputDeps =
env.getValuesOrThrow(
- ArtifactSkyKey.mandatoryKeys(
- completor.getAllArtifactsToBuild(value, topLevelContext).getAllArtifacts()),
+ completor.getAllArtifactsToBuild(value, topLevelContext).getAllArtifacts(),
MissingInputFileException.class,
ActionExecutionException.class);
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java
index 0ef296c944..0b414000c0 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java
@@ -86,7 +86,6 @@ public final class SkyFunctions {
SkyFunctionName.create("BUILD_CONFIGURATION");
public static final SkyFunctionName CONFIGURATION_FRAGMENT =
SkyFunctionName.create("CONFIGURATION_FRAGMENT");
- public static final SkyFunctionName ARTIFACT = SkyFunctionName.create("ARTIFACT");
public static final SkyFunctionName ACTION_EXECUTION = ActionLookupData.NAME;
public static final SkyFunctionName RECURSIVE_FILESYSTEM_TRAVERSAL =
SkyFunctionName.create("RECURSIVE_DIRECTORY_TRAVERSAL");
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeActionExecutor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeActionExecutor.java
index acc97e046f..bdff840056 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeActionExecutor.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeActionExecutor.java
@@ -50,6 +50,7 @@ import com.google.devtools.build.lib.actions.Actions;
import com.google.devtools.build.lib.actions.AlreadyReportedActionExecutionException;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.Artifact.ArtifactExpander;
+import com.google.devtools.build.lib.actions.Artifact.OwnerlessArtifactWrapper;
import com.google.devtools.build.lib.actions.ArtifactPrefixConflictException;
import com.google.devtools.build.lib.actions.CachedActionEvent;
import com.google.devtools.build.lib.actions.EnvironmentalExecException;
@@ -141,7 +142,8 @@ public final class SkyframeActionExecutor {
// We don't want to execute the action again on the second entry to the SkyFunction.
// In both cases, we store the already-computed ActionExecutionValue to avoid having to compute it
// again.
- private ConcurrentMap<Artifact, Pair<ActionLookupData, FutureTask<ActionExecutionValue>>>
+ private ConcurrentMap<
+ OwnerlessArtifactWrapper, Pair<ActionLookupData, FutureTask<ActionExecutionValue>>>
buildActionMap;
// Errors found when examining all actions in the graph are stored here, so that they can be
@@ -388,13 +390,16 @@ public final class SkyframeActionExecutor {
}
boolean probeActionExecution(Action action) {
- return buildActionMap.containsKey(action.getPrimaryOutput());
+ return buildActionMap.containsKey(new OwnerlessArtifactWrapper(action.getPrimaryOutput()));
}
private boolean actionReallyExecuted(Action action, ActionLookupData actionLookupData) {
Pair<ActionLookupData, ?> cachedRun =
Preconditions.checkNotNull(
- buildActionMap.get(action.getPrimaryOutput()), "%s %s", action, actionLookupData);
+ buildActionMap.get(new OwnerlessArtifactWrapper(action.getPrimaryOutput())),
+ "%s %s",
+ action,
+ actionLookupData);
return actionLookupData.equals(cachedRun.getFirst());
}
@@ -434,7 +439,8 @@ public final class SkyframeActionExecutor {
actionLookupData));
// Check to see if another action is already executing/has executed this value.
Pair<ActionLookupData, FutureTask<ActionExecutionValue>> oldAction =
- buildActionMap.putIfAbsent(primaryOutput, Pair.of(actionLookupData, actionTask));
+ buildActionMap.putIfAbsent(
+ new OwnerlessArtifactWrapper(primaryOutput), Pair.of(actionLookupData, actionTask));
// true if this is a non-shared action or it's shared and to be executed.
boolean isPrimaryActionForTheValue = oldAction == null;
@@ -445,7 +451,10 @@ public final class SkyframeActionExecutor {
actionTask = oldAction.second;
}
try {
- return actionTask.get();
+ ActionExecutionValue value = actionTask.get();
+ return isPrimaryActionForTheValue
+ ? value
+ : value.transformForSharedAction(action.getOutputs());
} catch (ExecutionException e) {
Throwables.propagateIfPossible(e.getCause(),
ActionExecutionException.class, InterruptedException.class);
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
index 0de07ffcc0..4d413a96fb 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
@@ -503,7 +503,7 @@ public abstract class SkyframeExecutor implements WalkableGraphFactory {
map.put(SkyFunctions.TARGET_COMPLETION, CompletionFunction.targetCompletionFunction());
map.put(SkyFunctions.ASPECT_COMPLETION, CompletionFunction.aspectCompletionFunction());
map.put(SkyFunctions.TEST_COMPLETION, new TestCompletionFunction());
- map.put(SkyFunctions.ARTIFACT, new ArtifactFunction());
+ map.put(Artifact.ARTIFACT, new ArtifactFunction());
map.put(
SkyFunctions.BUILD_INFO_COLLECTION,
new BuildInfoCollectionFunction(
@@ -1325,14 +1325,13 @@ public abstract class SkyframeExecutor implements WalkableGraphFactory {
resourceManager.resetResourceUsage();
try {
progressReceiver.executionProgressReceiver = executionProgressReceiver;
- Iterable<SkyKey> artifactKeys = ArtifactSkyKey.mandatoryKeys(artifactsToBuild);
Iterable<TargetCompletionValue.TargetCompletionKey> targetKeys =
TargetCompletionValue.keys(targetsToBuild, topLevelArtifactContext, targetsToTest);
Iterable<SkyKey> aspectKeys = AspectCompletionValue.keys(aspects, topLevelArtifactContext);
Iterable<SkyKey> testKeys =
TestCompletionValue.keys(targetsToTest, topLevelArtifactContext, exclusiveTesting);
return buildDriver.evaluate(
- Iterables.concat(artifactKeys, targetKeys, aspectKeys, testKeys),
+ Iterables.concat(artifactsToBuild, targetKeys, aspectKeys, testKeys),
keepGoing,
numJobs,
reporter);
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/StateInformingSkyFunctionEnvironment.java b/src/main/java/com/google/devtools/build/lib/skyframe/StateInformingSkyFunctionEnvironment.java
index 8e4d7d5e02..4273e328c5 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/StateInformingSkyFunctionEnvironment.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/StateInformingSkyFunctionEnvironment.java
@@ -142,7 +142,8 @@ class StateInformingSkyFunctionEnvironment implements SkyFunction.Environment {
}
@Override
- public Map<SkyKey, SkyValue> getValues(Iterable<SkyKey> depKeys) throws InterruptedException {
+ public Map<SkyKey, SkyValue> getValues(Iterable<? extends SkyKey> depKeys)
+ throws InterruptedException {
preFetch.inform();
try {
return delegate.getValues(depKeys);
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/TestCompletionFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/TestCompletionFunction.java
index 4a9946a1bc..cbbe9f9d30 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/TestCompletionFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/TestCompletionFunction.java
@@ -52,7 +52,7 @@ public final class TestCompletionFunction implements SkyFunction {
}
}
} else {
- env.getValues(ArtifactSkyKey.mandatoryKeys(TestProvider.getTestStatusArtifacts(ct)));
+ env.getValues(TestProvider.getTestStatusArtifacts(ct));
if (env.valuesMissing()) {
return null;
}