aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib
diff options
context:
space:
mode:
authorGravatar janakr <janakr@google.com>2018-08-14 21:38:51 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-08-14 21:40:26 -0700
commit7574d84e61086b5835a2b2cc003ca72fcfcf4fe4 (patch)
treec1fdc7992d6ffe9168112e5474917b0cb854a7c7 /src/main/java/com/google/devtools/build/lib
parent8dece49bed76b5f372ff5d3a3f25a32b2a9c1f52 (diff)
Filter out events from analysis when constructing execution-phase values in Skyframe.
This avoids some unnecessary iteration over already-emitted events that can show up in profiles, and allows us to store execution-phase values a bit more compactly, since we don't need to carry around wrapper objects and nested sets everywhere. This crucially depends on the fact that we can't build a target in the execution phase without first having analyzed it in a separate Skyframe call. Skyframe normally propagates all events/posts up the graph because it must be able to emit them if a user requests a node that only transitively depends on the node that emitted an event. However, because we do analysis in a separate Skyframe call, any warnings/posts associated with the analysis nodes will be emitted then, and we don't need to propagate them into execution. PiperOrigin-RevId: 208767078
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib')
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java38
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/packages/AbstractPackageLoader.java1
2 files changed, 39 insertions, 0 deletions
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 5e8f708444..028d4c8ee0 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
@@ -19,6 +19,7 @@ import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
import com.google.common.base.Stopwatch;
import com.google.common.base.Throwables;
import com.google.common.cache.Cache;
@@ -88,6 +89,7 @@ import com.google.devtools.build.lib.cmdline.TargetParsingException;
import com.google.devtools.build.lib.concurrent.ThreadSafety;
import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadCompatible;
import com.google.devtools.build.lib.events.ErrorSensingEventHandler;
+import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.events.ExtendedEventHandler;
import com.google.devtools.build.lib.events.Reporter;
@@ -146,8 +148,10 @@ import com.google.devtools.build.skyframe.Differencer.DiffWithDelta.Delta;
import com.google.devtools.build.skyframe.ErrorInfo;
import com.google.devtools.build.skyframe.EvaluationProgressReceiver;
import com.google.devtools.build.skyframe.EvaluationResult;
+import com.google.devtools.build.skyframe.EventFilter;
import com.google.devtools.build.skyframe.GraphInconsistencyReceiver;
import com.google.devtools.build.skyframe.ImmutableDiff;
+import com.google.devtools.build.skyframe.InMemoryMemoizingEvaluator;
import com.google.devtools.build.skyframe.Injectable;
import com.google.devtools.build.skyframe.MemoizingEvaluator;
import com.google.devtools.build.skyframe.MemoizingEvaluator.EvaluatorSupplier;
@@ -670,11 +674,45 @@ public abstract class SkyframeExecutor implements WalkableGraphFactory {
evaluatorDiffer(),
progressReceiver,
graphInconsistencyReceiver,
+ DEFAULT_FILTER_WITH_ACTIONS,
emittedEventState,
tracksStateForIncrementality());
buildDriver = getBuildDriver();
}
+ /**
+ * Use the fact that analysis of a target must occur before execution of that target, and in a
+ * separate Skyframe evaluation, to avoid propagating events from configured target nodes (and
+ * more generally action lookup nodes) to action execution nodes. We take advantage of the fact
+ * that if a node depends on an action lookup node and is not itself an action lookup node, then
+ * it is an execution-phase node: the action lookup nodes are terminal in the analysis phase.
+ */
+ private static final EventFilter DEFAULT_FILTER_WITH_ACTIONS =
+ new EventFilter() {
+ @Override
+ public boolean storeEventsAndPosts() {
+ return true;
+ }
+
+ @Override
+ public boolean apply(Event input) {
+ // Use the filtering defined in the default filter: no info/progress messages.
+ return InMemoryMemoizingEvaluator.DEFAULT_STORED_EVENT_FILTER.apply(input);
+ }
+
+ @Override
+ public Predicate<SkyKey> depEdgeFilterForEventsAndPosts(SkyKey primaryKey) {
+ if (primaryKey instanceof ActionLookupValue.ActionLookupKey) {
+ return Predicates.alwaysTrue();
+ } else {
+ return NO_ACTION_LOOKUP;
+ }
+ }
+ };
+
+ private static final Predicate<SkyKey> NO_ACTION_LOOKUP =
+ (key) -> !(key instanceof ActionLookupValue.ActionLookupKey);
+
protected SkyframeProgressReceiver newSkyframeProgressReceiver() {
return new SkyframeProgressReceiver();
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/packages/AbstractPackageLoader.java b/src/main/java/com/google/devtools/build/lib/skyframe/packages/AbstractPackageLoader.java
index 242a5ac66e..9fad67e516 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/packages/AbstractPackageLoader.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/packages/AbstractPackageLoader.java
@@ -342,6 +342,7 @@ public abstract class AbstractPackageLoader implements PackageLoader {
preinjectedDifferencer,
new EvaluationProgressReceiver.NullEvaluationProgressReceiver(),
GraphInconsistencyReceiver.THROWING,
+ InMemoryMemoizingEvaluator.DEFAULT_STORED_EVENT_FILTER,
new MemoizingEvaluator.EmittedEventState(),
/*keepEdges=*/ false));
}