From d0a3c5eb67320906e4b937df5434f0e673cb6dce Mon Sep 17 00:00:00 2001 From: janakr Date: Thu, 9 Aug 2018 15:59:24 -0700 Subject: Batch all DependencyResolver#getTarget calls. This leads to some duplicate iteration, but that should be cheap, while requesting packages sequentially can hurt... PiperOrigin-RevId: 208126130 --- .../lib/analysis/AspectAwareAttributeMapper.java | 3 +- .../build/lib/analysis/DependencyResolver.java | 372 +++++++++++++-------- .../lib/packages/AbstractAttributeMapper.java | 23 +- .../lib/packages/AggregatingAttributeMapper.java | 5 +- .../devtools/build/lib/packages/AttributeMap.java | 36 +- .../lib/packages/DelegatingAttributeMapper.java | 5 +- .../devtools/build/lib/packages/Package.java | 11 +- .../google/devtools/build/lib/packages/Rule.java | 38 +-- .../devtools/build/lib/packages/TargetUtils.java | 34 +- .../devtools/build/lib/query2/LabelVisitor.java | 17 +- .../query2/TransitionsOutputFormatterCallback.java | 16 +- .../lib/skyframe/ConfiguredTargetFunction.java | 12 +- .../lib/skyframe/SkyframeDependencyResolver.java | 69 ++-- .../devtools/build/lib/analysis/BuildViewTest.java | 38 +++ .../analysis/ConfiguredAttributeMapperTest.java | 31 +- .../build/lib/analysis/DependencyResolverTest.java | 30 +- .../select/AbstractAttributeMapperTest.java | 33 +- .../select/AggregatingAttributeMapperTest.java | 8 +- .../analysis/select/RawAttributeMapperTest.java | 9 +- .../lib/analysis/util/BuildViewForTesting.java | 29 +- 20 files changed, 477 insertions(+), 342 deletions(-) diff --git a/src/main/java/com/google/devtools/build/lib/analysis/AspectAwareAttributeMapper.java b/src/main/java/com/google/devtools/build/lib/analysis/AspectAwareAttributeMapper.java index b45e350fc4..4419d0b162 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/AspectAwareAttributeMapper.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/AspectAwareAttributeMapper.java @@ -22,6 +22,7 @@ import com.google.devtools.build.lib.packages.Attribute; import com.google.devtools.build.lib.packages.AttributeMap; import com.google.devtools.build.lib.packages.RuleClass; import com.google.devtools.build.lib.syntax.Type; +import java.util.Collection; /** * An {@link AttributeMap} that supports attribute type queries on both a rule and its aspects and @@ -134,7 +135,7 @@ class AspectAwareAttributeMapper implements AttributeMap { } @Override - public void visitLabels(AcceptsLabelAttribute observer) throws InterruptedException { + public Collection visitLabels() throws InterruptedException { throw new UnsupportedOperationException("rule + aspects label visition is not supported"); } diff --git a/src/main/java/com/google/devtools/build/lib/analysis/DependencyResolver.java b/src/main/java/com/google/devtools/build/lib/analysis/DependencyResolver.java index 0ae17e2093..6062d064ee 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/DependencyResolver.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/DependencyResolver.java @@ -18,6 +18,7 @@ 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.Iterables; import com.google.devtools.build.lib.analysis.AspectCollection.AspectCycleOnPathException; import com.google.devtools.build.lib.analysis.config.BuildConfiguration; import com.google.devtools.build.lib.analysis.config.BuildOptions; @@ -56,11 +57,12 @@ import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec. import com.google.devtools.build.lib.syntax.EvalException; import com.google.devtools.build.lib.syntax.EvalUtils; import com.google.devtools.build.lib.util.OrderedSetMultimap; -import java.util.ArrayList; import java.util.Collection; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Stream; import javax.annotation.Nullable; /** @@ -214,8 +216,8 @@ public abstract class DependencyResolver { @Nullable RuleTransitionFactory trimmingTransitionFactory) throws EvalException, InvalidConfigurationException, InconsistentAspectOrderException, InterruptedException { - Preconditions.checkArgument(node.getTarget() instanceof Rule); - BuildConfiguration ruleConfig = Preconditions.checkNotNull(node.getConfiguration()); + Preconditions.checkArgument(node.getTarget() instanceof Rule, node); + BuildConfiguration ruleConfig = Preconditions.checkNotNull(node.getConfiguration(), node); Rule rule = (Rule) node.getTarget(); ConfiguredAttributeMapper attributeMap = ConfiguredAttributeMapper.of(rule, configConditions); @@ -289,31 +291,31 @@ public abstract class DependencyResolver { private void resolveExplicitAttributes(final RuleResolver depResolver) throws InterruptedException, InconsistentAspectOrderException { - // Record error that might happen during label visitation. - final InconsistentAspectOrderException[] exception = new InconsistentAspectOrderException[1]; - - depResolver.attributeMap.visitLabels( - new AttributeMap.AcceptsLabelAttribute() { - @Override - public void acceptLabelAttribute(Label label, Attribute attribute) - throws InterruptedException { - if (attribute.getType() == BuildType.NODEP_LABEL - || attribute.isImplicit() - || attribute.isLateBound()) { - return; - } - try { - depResolver.resolveDep(new AttributeAndOwner(attribute), label); - } catch (InconsistentAspectOrderException e) { - if (exception[0] == null) { - exception[0] = e; - } - } - } - }); + // Track size of filtered iterable by having an always-true clause that only gets checked after + // all relevant clauses are checked. + Collection depEdges = depResolver.attributeMap.visitLabels(); + Iterable filteredEdges = + Iterables.filter( + depEdges, + depEdge -> + depEdge.getAttribute().getType() != BuildType.NODEP_LABEL + && !depEdge.getAttribute().isImplicit() + && !depEdge.getAttribute().isLateBound()); + Map result = + getTargets( + Iterables.transform(filteredEdges, AttributeMap.DepEdge::getLabel), + depResolver.rule, + depResolver.rootCauses, + depEdges.size()); + if (result == null) { + return; + } - if (exception[0] != null) { - throw exception[0]; + for (AttributeMap.DepEdge depEdge : filteredEdges) { + Target target = result.get(depEdge.getLabel()); + if (target != null) { + depResolver.registerEdge(new AttributeAndOwner(depEdge.getAttribute()), target); + } } } @@ -328,33 +330,57 @@ public abstract class DependencyResolver { Label ruleLabel = rule.getLabel(); ConfiguredAttributeMapper attributeMap = depResolver.attributeMap; ImmutableSet mappedAttributes = ImmutableSet.copyOf(attributeMap.getAttributeNames()); - for (AttributeAndOwner attributeAndOwner : depResolver.attributes) { - Attribute attribute = attributeAndOwner.attribute; - if (!attribute.isImplicit() || !attribute.getCondition().apply(attributeMap)) { - continue; - } + Set