aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com
diff options
context:
space:
mode:
authorGravatar laurentlb <laurentlb@google.com>2017-03-30 20:15:08 +0000
committerGravatar Philipp Wollermann <philwo@google.com>2017-03-31 17:11:03 +0200
commit833fd12fd86ddc32e89b1b0cff57b248a58dc8ab (patch)
treeca6b3f5edffb9f457ac293d5f7d77a6f05a0ea18 /src/main/java/com
parent18a4c841d48df2eb52f27817ed566833809a92cc (diff)
Improve glob prefetching performance by providing a more realistic environment.
That means the prefetching execution is more similar to the real execution, it will fetch more globs and throw less exceptions. In the code path, one exception was thrown for almost each statement. With this change, many BUILD files can be evaluated without an exception. RELNOTES: None. PiperOrigin-RevId: 151740684
Diffstat (limited to 'src/main/java/com')
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java67
1 files changed, 51 insertions, 16 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java b/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
index 16df4e0b51..35c0cfb241 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
@@ -1341,8 +1341,15 @@ public final class PackageFactory {
try {
// At this point the package is guaranteed to exist. It may have parse or
// evaluation errors, resulting in a diminished number of rules.
- prefetchGlobs(packageId, astAfterPreprocessing.ast, astAfterPreprocessing.preprocessed,
- buildFile, globber, defaultVisibility, makeEnv);
+ prefetchGlobs(
+ packageId,
+ astAfterPreprocessing.ast,
+ astAfterPreprocessing.preprocessed,
+ buildFile,
+ globber,
+ defaultVisibility,
+ makeEnv,
+ imports);
return evaluateBuildFile(
workspaceName,
packageId,
@@ -1607,7 +1614,23 @@ public final class PackageFactory {
builder.build(), "no native function or rule '%s'");
}
- private void buildPkgEnv(Environment pkgEnv, PackageContext context, RuleFactory ruleFactory) {
+ /** A function that does nothing and ignores the arguments. */
+ private final BaseFunction noopFunction =
+ new BaseFunction("noop", FunctionSignature.KWARGS) {
+ @Override
+ public Object call(Object[] arguments, FuncallExpression ast, Environment env)
+ throws EvalException {
+ return Runtime.NONE;
+ }
+ };
+
+ /** @param fakeEnv specify if we declare no-op functions, or real functions. */
+ private void buildPkgEnv(
+ Environment pkgEnv,
+ PackageContext context,
+ RuleFactory ruleFactory,
+ PackageIdentifier packageId,
+ boolean fakeEnv) {
// TODO(bazel-team): remove the naked functions that are redundant with the nativeModule,
// or if not possible, at least make them straight copies from the native module variant.
// or better, use a common Environment.Frame for these common bindings
@@ -1625,12 +1648,20 @@ public final class PackageFactory {
for (String ruleClass : ruleFactory.getRuleClassNames()) {
BaseFunction ruleFunction = newRuleFunction(ruleFactory, ruleClass);
- pkgEnv.setup(ruleClass, ruleFunction);
+ if (fakeEnv) {
+ pkgEnv.setup(ruleClass, ruleFunction);
+ } else {
+ pkgEnv.setup(ruleClass, noopFunction);
+ }
}
for (EnvironmentExtension extension : environmentExtensions) {
extension.update(pkgEnv);
}
+
+ pkgEnv.setupDynamic(PKG_CONTEXT, context);
+ pkgEnv.setupDynamic(Runtime.PKG_NAME, packageId.getPackageFragment().getPathString());
+ pkgEnv.setupDynamic(Runtime.REPOSITORY_NAME, packageId.getRepository().toString());
}
/**
@@ -1702,10 +1733,7 @@ public final class PackageFactory {
PackageContext context =
new PackageContext(
pkgBuilder, globber, eventHandler, ruleFactory.getAttributeContainerFactory());
- buildPkgEnv(pkgEnv, context, ruleFactory);
- pkgEnv.setupDynamic(PKG_CONTEXT, context);
- pkgEnv.setupDynamic(Runtime.PKG_NAME, packageId.getPackageFragment().getPathString());
- pkgEnv.setupDynamic(Runtime.REPOSITORY_NAME, packageId.getRepository().toString());
+ buildPkgEnv(pkgEnv, context, ruleFactory, packageId, true);
if (containsError) {
pkgBuilder.setContainsErrors();
@@ -1736,12 +1764,16 @@ public final class PackageFactory {
return pkgBuilder;
}
- /**
- * Visit all targets and expand the globs in parallel.
- */
- private void prefetchGlobs(PackageIdentifier packageId, BuildFileAST buildFileAST,
- boolean wasPreprocessed, Path buildFilePath, Globber globber,
- RuleVisibility defaultVisibility, MakeEnvironment.Builder pkgMakeEnv)
+ /** Visit all targets and expand the globs in parallel. */
+ private void prefetchGlobs(
+ PackageIdentifier packageId,
+ BuildFileAST buildFileAST,
+ boolean wasPreprocessed,
+ Path buildFilePath,
+ Globber globber,
+ RuleVisibility defaultVisibility,
+ MakeEnvironment.Builder pkgMakeEnv,
+ Map<String, Extension> imports)
throws InterruptedException {
if (wasPreprocessed && preprocessorFactory.considersGlobs()) {
// All the globs have either already been evaluated and they aren't in the ast anymore, or
@@ -1759,6 +1791,7 @@ public final class PackageFactory {
Environment.builder(mutability)
.setGlobals(BazelLibrary.GLOBALS)
.setEventHandler(NullEventHandler.INSTANCE)
+ .setImportedExtensions(imports)
.setPhase(Phase.LOADING)
.build();
SkylarkUtils.setToolsRepository(pkgEnv, ruleClassProvider.getToolsRepository());
@@ -1780,12 +1813,14 @@ public final class PackageFactory {
globber,
NullEventHandler.INSTANCE,
ruleFactory.getAttributeContainerFactory());
- buildPkgEnv(pkgEnv, context, ruleFactory);
+ buildPkgEnv(pkgEnv, context, ruleFactory, packageId, false);
+
try {
pkgEnv.update("glob", newGlobFunction.apply(context, /*async=*/true));
// The Fileset function is heavyweight in that it can run glob(). Avoid this during the
// preloading phase.
- pkgEnv.update("FilesetEntry", Runtime.NONE);
+ pkgEnv.update("FilesetEntry", noopFunction);
+ pkgEnv.update("vardef", noopFunction);
} catch (EvalException e) {
throw new AssertionError(e);
}