Automated g4 rollback of commit 7beadb7277453efec7e12b925005e7f0e003b592.

*** Reason for rollback ***

Original CL was rolled backed incorrectly. See post-submit discussion on http://https://github.com/bazelbuild/bazel/commit/7beadb7277453efec7e12b925005e7f0e003b592.

*** Original change description ***

Automated g4 rollback of commit 38b835097f9ae9a6062172b8a33ec2e2d1edde20.

*** Reason for rollback ***

Breaking Bazel build on linux, see http://ci.bazel.io/job/bazel-tests/733/

Repro: bazel build //src/test/java/com/google/devtools/build/lib:packages_test

Found by bisecting.

*** Original change description ***

Only allocate some formerly frequently allocated PathFragment objects once.

This reduces both gc churn and retained memory usage.

RELNOTES: None
PiperOrigin-RevId: 154839279
diff --git a/src/main/java/com/google/devtools/build/lib/actions/Artifact.java b/src/main/java/com/google/devtools/build/lib/actions/Artifact.java
index 7c6a870..74c7682 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/Artifact.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/Artifact.java
@@ -543,8 +543,7 @@
    */
   public final PathFragment getRunfilesPath() {
     PathFragment relativePath = rootRelativePath;
-    if (relativePath.segmentCount() > 1
-        && relativePath.getSegment(0).equals(Label.EXTERNAL_PATH_PREFIX)) {
+    if (relativePath.startsWith(Label.EXTERNAL_PATH_PREFIX)) {
       // Turn external/repo/foo into ../repo/foo.
       relativePath = relativePath.relativeTo(Label.EXTERNAL_PATH_PREFIX);
       relativePath = PathFragment.create("..").getRelative(relativePath);
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
index 30007e6..a6c43d4 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
@@ -1262,7 +1262,18 @@
    * <p>For example "pkg/dir/name" -> "pkg/&lt;fragment>/rule/dir/name.
    */
   public final PathFragment getUniqueDirectory(String fragment) {
-    return AnalysisUtils.getUniqueDirectory(getLabel(), PathFragment.create(fragment));
+    return getUniqueDirectory(PathFragment.create(fragment));
+  }
+
+  /**
+   * Returns a path fragment qualified by the rule name and unique fragment to
+   * disambiguate artifacts produced from the source file appearing in
+   * multiple rules.
+   *
+   * <p>For example "pkg/dir/name" -> "pkg/&lt;fragment>/rule/dir/name.
+   */
+  public final PathFragment getUniqueDirectory(PathFragment fragment) {
+    return AnalysisUtils.getUniqueDirectory(getLabel(), fragment);
   }
 
   /**
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java
index 9e11f94..3273a6d 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java
@@ -1168,7 +1168,7 @@
     INCLUDE(BlazeDirectories.RELATIVE_INCLUDE_DIR),
     OUTPUT(false);
 
-    private final String name;
+    private final PathFragment nameFragment;
     private final boolean middleman;
 
     /**
@@ -1177,12 +1177,12 @@
      * @param isMiddleman whether the root should be a middleman root or a "normal" derived root.
      */
     OutputDirectory(boolean isMiddleman) {
-      this.name = "";
+      this.nameFragment = PathFragment.EMPTY_FRAGMENT;
       this.middleman = isMiddleman;
     }
 
     OutputDirectory(String name) {
-      this.name = name;
+      this.nameFragment = PathFragment.create(name);
       this.middleman = false;
     }
 
@@ -1198,16 +1198,29 @@
       }
       // e.g., [[execroot/repo1]/bazel-out/config/bin]
       return INTERNER.intern(
-          Root.asDerivedRoot(execRoot, outputDir.getRelative(name), repositoryName.isMain()));
+          Root.asDerivedRoot(
+              execRoot,
+              outputDir.getRelative(nameFragment),
+              repositoryName.isMain()));
     }
   }
 
-  // "Cache" of roots, so we don't keep around thousands of copies of the same root.
-  private static Interner<Root> INTERNER = Interners.newWeakInterner();
-
   private final BlazeDirectories directories;
   private final String outputDirName;
 
+  // We intern the roots for non-main repositories, so we don't keep around thousands of copies of
+  // the same root.
+  private static Interner<Root> INTERNER = Interners.newWeakInterner();
+
+  // We precompute the roots for the main repository, since that's the common case.
+  private final Root outputDirectoryForMainRepository;
+  private final Root binDirectoryForMainRepository;
+  private final Root includeDirectoryForMainRepository;
+  private final Root genfilesDirectoryForMainRepository;
+  private final Root coverageDirectoryForMainRepository;
+  private final Root testlogsDirectoryForMainRepository;
+  private final Root middlemanDirectoryForMainRepository;
+
   /** If false, AnalysisEnviroment doesn't register any actions created by the ConfiguredTarget. */
   private final boolean actionsEnabled;
 
@@ -1444,6 +1457,22 @@
     this.mnemonic = buildMnemonic();
     this.outputDirName = (options.outputDirectoryName != null)
         ? options.outputDirectoryName : mnemonic;
+
+    this.outputDirectoryForMainRepository =
+        OutputDirectory.OUTPUT.getRoot(RepositoryName.MAIN, outputDirName, directories);
+    this.binDirectoryForMainRepository =
+        OutputDirectory.BIN.getRoot(RepositoryName.MAIN, outputDirName, directories);
+    this.includeDirectoryForMainRepository =
+        OutputDirectory.INCLUDE.getRoot(RepositoryName.MAIN, outputDirName, directories);
+    this.genfilesDirectoryForMainRepository =
+        OutputDirectory.GENFILES.getRoot(RepositoryName.MAIN, outputDirName, directories);
+    this.coverageDirectoryForMainRepository =
+        OutputDirectory.COVERAGE.getRoot(RepositoryName.MAIN, outputDirName, directories);
+    this.testlogsDirectoryForMainRepository =
+        OutputDirectory.TESTLOGS.getRoot(RepositoryName.MAIN, outputDirName, directories);
+    this.middlemanDirectoryForMainRepository =
+        OutputDirectory.MIDDLEMAN.getRoot(RepositoryName.MAIN, outputDirName, directories);
+
     this.platformName = buildPlatformName();
 
     this.shellExecutable = computeShellExecutable();
@@ -2068,7 +2097,9 @@
    * Returns the output directory for this build configuration.
    */
   public Root getOutputDirectory(RepositoryName repositoryName) {
-    return OutputDirectory.OUTPUT.getRoot(repositoryName, outputDirName, directories);
+    return repositoryName.equals(RepositoryName.MAIN)
+        ? outputDirectoryForMainRepository
+        : OutputDirectory.OUTPUT.getRoot(repositoryName, outputDirName, directories);
   }
 
   /**
@@ -2087,7 +2118,9 @@
    * repositories (external) but will need to be fixed.
    */
   public Root getBinDirectory(RepositoryName repositoryName) {
-    return OutputDirectory.BIN.getRoot(repositoryName, outputDirName, directories);
+    return repositoryName.equals(RepositoryName.MAIN)
+        ? binDirectoryForMainRepository
+        : OutputDirectory.BIN.getRoot(repositoryName, outputDirName, directories);
   }
 
   /**
@@ -2101,7 +2134,9 @@
    * Returns the include directory for this build configuration.
    */
   public Root getIncludeDirectory(RepositoryName repositoryName) {
-    return OutputDirectory.INCLUDE.getRoot(repositoryName, outputDirName, directories);
+    return repositoryName.equals(RepositoryName.MAIN)
+        ? includeDirectoryForMainRepository
+        : OutputDirectory.INCLUDE.getRoot(repositoryName, outputDirName, directories);
   }
 
   /**
@@ -2114,7 +2149,9 @@
   }
 
   public Root getGenfilesDirectory(RepositoryName repositoryName) {
-    return OutputDirectory.GENFILES.getRoot(repositoryName, outputDirName, directories);
+    return repositoryName.equals(RepositoryName.MAIN)
+        ? genfilesDirectoryForMainRepository
+        : OutputDirectory.GENFILES.getRoot(repositoryName, outputDirName, directories);
   }
 
   /**
@@ -2123,14 +2160,18 @@
    * needed for Jacoco's coverage reporting tools.
    */
   public Root getCoverageMetadataDirectory(RepositoryName repositoryName) {
-    return OutputDirectory.COVERAGE.getRoot(repositoryName, outputDirName, directories);
+    return repositoryName.equals(RepositoryName.MAIN)
+        ? coverageDirectoryForMainRepository
+        : OutputDirectory.COVERAGE.getRoot(repositoryName, outputDirName, directories);
   }
 
   /**
    * Returns the testlogs directory for this build configuration.
    */
   public Root getTestLogsDirectory(RepositoryName repositoryName) {
-    return OutputDirectory.TESTLOGS.getRoot(repositoryName, outputDirName, directories);
+    return repositoryName.equals(RepositoryName.MAIN)
+        ? testlogsDirectoryForMainRepository
+        : OutputDirectory.TESTLOGS.getRoot(repositoryName, outputDirName, directories);
   }
 
   /**
@@ -2157,7 +2198,9 @@
    * Returns the internal directory (used for middlemen) for this build configuration.
    */
   public Root getMiddlemanDirectory(RepositoryName repositoryName) {
-    return OutputDirectory.MIDDLEMAN.getRoot(repositoryName, outputDirName, directories);
+    return repositoryName.equals(RepositoryName.MAIN)
+        ? middlemanDirectoryForMainRepository
+        : OutputDirectory.MIDDLEMAN.getRoot(repositoryName, outputDirName, directories);
   }
 
   public boolean getAllowRuntimeDepsOnNeverLink() {
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPythonSemantics.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPythonSemantics.java
index ac6d574..29ccba9 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPythonSemantics.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPythonSemantics.java
@@ -207,7 +207,7 @@
   }
 
   private static boolean isUnderWorkspace(PathFragment path) {
-    return !path.startsWith(PathFragment.create(Label.EXTERNAL_PATH_PREFIX));
+    return !path.startsWith(Label.EXTERNAL_PATH_PREFIX);
   }
 
   private static String getZipRunfilesPath(PathFragment path, PathFragment workspaceName) {
diff --git a/src/main/java/com/google/devtools/build/lib/cmdline/Label.java b/src/main/java/com/google/devtools/build/lib/cmdline/Label.java
index 4bc5a4c..ef62fc1 100644
--- a/src/main/java/com/google/devtools/build/lib/cmdline/Label.java
+++ b/src/main/java/com/google/devtools/build/lib/cmdline/Label.java
@@ -72,7 +72,7 @@
   public static final PackageIdentifier EXTERNAL_PACKAGE_IDENTIFIER =
       PackageIdentifier.createInMainRepo(EXTERNAL_PACKAGE_NAME);
 
-  public static final String EXTERNAL_PATH_PREFIX = "external";
+  public static final PathFragment EXTERNAL_PATH_PREFIX = PathFragment.create("external");
 
   private static final Interner<Label> LABEL_INTERNER = BlazeInterners.newWeakInterner();
 
diff --git a/src/main/java/com/google/devtools/build/lib/cmdline/PackageIdentifier.java b/src/main/java/com/google/devtools/build/lib/cmdline/PackageIdentifier.java
index 2deba30..8640f26 100644
--- a/src/main/java/com/google/devtools/build/lib/cmdline/PackageIdentifier.java
+++ b/src/main/java/com/google/devtools/build/lib/cmdline/PackageIdentifier.java
@@ -79,7 +79,7 @@
         ? Preconditions.checkNotNull(
             execPath.getParentDirectory(), "Must pass in files, not root directory")
         : execPath;
-    if (tofind.startsWith(PathFragment.create(Label.EXTERNAL_PATH_PREFIX))) {
+    if (tofind.startsWith(Label.EXTERNAL_PATH_PREFIX)) {
       // TODO(ulfjack): Remove this when kchodorow@'s exec root rearrangement has been rolled out.
       RepositoryName repository = RepositoryName.create("@" + tofind.getSegment(1));
       return PackageIdentifier.create(repository, tofind.subFragment(2, tofind.segmentCount()));
diff --git a/src/main/java/com/google/devtools/build/lib/cmdline/RepositoryName.java b/src/main/java/com/google/devtools/build/lib/cmdline/RepositoryName.java
index b9564e7..b008978 100644
--- a/src/main/java/com/google/devtools/build/lib/cmdline/RepositoryName.java
+++ b/src/main/java/com/google/devtools/build/lib/cmdline/RepositoryName.java
@@ -139,7 +139,7 @@
    * was invalid.
    */
   public static Pair<RepositoryName, PathFragment> fromPathFragment(PathFragment path) {
-    if (path.segmentCount() < 2 || !path.getSegment(0).equals(Label.EXTERNAL_PATH_PREFIX)) {
+    if (path.segmentCount() < 2 || !path.startsWith(Label.EXTERNAL_PATH_PREFIX)) {
       return null;
     }
     try {
@@ -202,7 +202,7 @@
   }
 
   /**
-   * Returns if this is the default repository, that is, {@link #name} is "@".
+   * Returns if this is the main repository, that is, {@link #name} is "@".
    */
   public boolean isMain() {
     return name.equals("@");
@@ -232,7 +232,7 @@
   public PathFragment getPathUnderExecRoot() {
     return isDefault() || isMain()
         ? PathFragment.EMPTY_FRAGMENT
-        : PathFragment.create(Label.EXTERNAL_PATH_PREFIX).getRelative(strippedName());
+        : Label.EXTERNAL_PATH_PREFIX.getRelative(strippedName());
   }
 
   /**
diff --git a/src/main/java/com/google/devtools/build/lib/pkgcache/PathPackageLocator.java b/src/main/java/com/google/devtools/build/lib/pkgcache/PathPackageLocator.java
index f828538..223b0c4 100644
--- a/src/main/java/com/google/devtools/build/lib/pkgcache/PathPackageLocator.java
+++ b/src/main/java/com/google/devtools/build/lib/pkgcache/PathPackageLocator.java
@@ -45,6 +45,7 @@
  * filesystem) idempotent.
  */
 public class PathPackageLocator implements Serializable {
+  private static final PathFragment BUILD_PATH_FRAGMENT = PathFragment.create("BUILD");
 
   public static final ImmutableSet<String> DEFAULT_TOP_LEVEL_EXCLUDES =
       ImmutableSet.of("experimental");
@@ -101,7 +102,8 @@
       AtomicReference<? extends UnixGlob.FilesystemCalls> cache)  {
     Preconditions.checkArgument(!packageIdentifier.getRepository().isDefault());
     if (packageIdentifier.getRepository().isMain()) {
-      return getFilePath(packageIdentifier.getPackageFragment().getRelative("BUILD"), cache);
+      return getFilePath(
+          packageIdentifier.getPackageFragment().getRelative(BUILD_PATH_FRAGMENT), cache);
     } else {
       Verify.verify(outputBase != null, String.format(
           "External package '%s' needs to be loaded but this PathPackageLocator instance does not "
@@ -111,7 +113,7 @@
       // is true for the invocation in GlobCache, but not for the locator.getBuildFileForPackage()
       // invocation in Parser#include().
       Path buildFile = outputBase.getRelative(
-          packageIdentifier.getSourceRoot()).getRelative("BUILD");
+          packageIdentifier.getSourceRoot()).getRelative(BUILD_PATH_FRAGMENT);
       try {
         FileStatus stat = cache.get().statIfFound(buildFile, Symlinks.FOLLOW);
         if (stat != null && stat.isFile()) {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java
index 74d1d3c..1b1884c 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java
@@ -110,6 +110,8 @@
         }
       };
 
+  private static final PathFragment BUILD_PATH_FRAGMENT = PathFragment.create("BUILD");
+
   private static final int VALIDATION_DEBUG = 0;  // 0==none, 1==warns/errors, 2==all
   private static final boolean VALIDATION_DEBUG_WARN = VALIDATION_DEBUG >= 1;
 
@@ -948,7 +950,7 @@
     // Still not found: see if it is in a subdir of a declared package.
     Path root = input.getRoot().getPath();
     for (Path dir = input.getPath().getParentDirectory();;) {
-      if (dir.getRelative("BUILD").exists()) {
+      if (dir.getRelative(BUILD_PATH_FRAGMENT).exists()) {
         return false;  // Bad: this is a sub-package, not a subdir of a declared package.
       }
       dir = dir.getParentDirectory();
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileActionBuilder.java
index 693970c..333361f 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileActionBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileActionBuilder.java
@@ -477,7 +477,7 @@
         continue;
       }
       // One starting ../ is okay for getting to a sibling repository.
-      if (include.startsWith(PathFragment.create(Label.EXTERNAL_PATH_PREFIX))) {
+      if (include.startsWith(Label.EXTERNAL_PATH_PREFIX)) {
         include = include.relativeTo(Label.EXTERNAL_PATH_PREFIX);
       }
       if (include.isAbsolute()
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java
index 41afb81..aa719c8 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java
@@ -60,6 +60,8 @@
  * <p>This class can be used only after the loading phase.
  */
 public class CppHelper {
+  static final PathFragment OBJS = PathFragment.create("_objs");
+
   private static final String GREPPED_INCLUDES_SUFFIX = ".includes";
 
   // TODO(bazel-team): should this use Link.SHARED_LIBRARY_FILETYPES?
@@ -283,7 +285,7 @@
    * Returns the directory where object files are created.
    */
   public static PathFragment getObjDirectory(Label ruleLabel) {
-    return AnalysisUtils.getUniqueDirectory(ruleLabel, PathFragment.create("_objs"));
+    return AnalysisUtils.getUniqueDirectory(ruleLabel, OBJS);
   }
 
   /**
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionBuilder.java
index b2a6711..0c640ff 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionBuilder.java
@@ -952,7 +952,7 @@
     PathFragment stampOutputDirectory =
         outputBinaryPath
             .getParentDirectory()
-            .getRelative("_objs")
+            .getRelative(CppHelper.OBJS)
             .getRelative(outputBinaryPath.getBaseName());
 
     for (Artifact linkstamp : linkstamps) {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java
index 5389023..e7b9c7c 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java
@@ -71,6 +71,7 @@
   private final ImmutableList<Artifact> additionalJavaBaseInputs;
 
   private static final String DEFAULT_ATTRIBUTES_SUFFIX = "";
+  private static final PathFragment JAVAC = PathFragment.create("_javac");
 
   public JavaCompilationHelper(RuleContext ruleContext, JavaSemantics semantics,
       ImmutableList<String> javacOpts, JavaTargetAttributes.Builder attributes,
@@ -564,7 +565,7 @@
   private PathFragment workDir(Artifact outputJar, String suffix) {
     String basename = FileSystemUtils.removeExtension(outputJar.getExecPath().getBaseName());
     return getConfiguration().getBinDirectory(ruleContext.getRule().getRepository()).getExecPath()
-        .getRelative(ruleContext.getUniqueDirectory("_javac"))
+        .getRelative(ruleContext.getUniqueDirectory(JAVAC))
         .getRelative(basename + suffix);
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IntermediateArtifacts.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IntermediateArtifacts.java
index 8de811f..ba324e6 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/IntermediateArtifacts.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IntermediateArtifacts.java
@@ -34,6 +34,8 @@
 // TODO(bazel-team): This should really be named DerivedArtifacts as it contains methods for
 // final as well as intermediate artifacts.
 public final class IntermediateArtifacts {
+  private static final PathFragment OBJS = PathFragment.create("_objs");
+
   static final String LINKMAP_SUFFIX = ".linkmap";
 
   /**
@@ -275,8 +277,7 @@
   }
 
   private Artifact inUniqueObjsDir(Artifact source, String extension) {
-    PathFragment uniqueDir =
-        PathFragment.create("_objs").getRelative(ruleContext.getLabel().getName());
+    PathFragment uniqueDir = OBJS.getRelative(ruleContext.getLabel().getName());
     PathFragment sourceFile = uniqueDir.getRelative(source.getRootRelativePath());
     PathFragment scopeRelativePath = FileSystemUtils.replaceExtension(sourceFile, extension);
     return scopedArtifact(scopeRelativePath);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/LocalRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/rules/repository/LocalRepositoryFunction.java
index 490b1f6..8d7e3eb 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/repository/LocalRepositoryFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/repository/LocalRepositoryFunction.java
@@ -100,7 +100,7 @@
             directory.getRoot(),
             directory
                 .getRelativePath()
-                .getChild(PackageLookupValue.BuildFileName.WORKSPACE.getFilename()));
+                .getRelative(PackageLookupValue.BuildFileName.WORKSPACE.getFilenameFragment()));
 
     SkyKey workspaceFileKey = FileValue.key(workspaceRootedFile);
     FileValue value;
diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java
index 20c26b5..e6f3837 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java
@@ -473,8 +473,7 @@
 
       if (repositoryPath.segmentCount() > 1) {
         if (rule.getRuleClass().equals(LocalRepositoryRule.NAME)
-            && repositoryPath.endsWith(
-                PathFragment.create(BuildFileName.WORKSPACE.getFilename()))) {
+            && repositoryPath.endsWith(BuildFileName.WORKSPACE.getFilenameFragment())) {
           // Ignore this, there is a dependency from LocalRepositoryFunction->WORKSPACE file already
           return;
         }
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/LocalRepositoryLookupFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/LocalRepositoryLookupFunction.java
index ae4b250..7326203 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/LocalRepositoryLookupFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/LocalRepositoryLookupFunction.java
@@ -94,7 +94,7 @@
               directory.getRoot(),
               directory
                   .getRelativePath()
-                  .getChild(PackageLookupValue.BuildFileName.WORKSPACE.getFilename()));
+                  .getRelative(PackageLookupValue.BuildFileName.WORKSPACE.getFilenameFragment()));
       FileValue workspaceFileValue =
           (FileValue)
               env.getValueOrThrow(
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupFunction.java
index e427c34..c0a115a 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupFunction.java
@@ -315,7 +315,7 @@
     // This checks for the build file names in the correct precedence order.
     for (BuildFileName buildFileName : buildFilesByPriority) {
       PathFragment buildFileFragment =
-          id.getPackageFragment().getChild(buildFileName.getFilename());
+          id.getPackageFragment().getRelative(buildFileName.getFilenameFragment());
       RootedPath buildFileRootedPath =
           RootedPath.toRootedPath(repositoryValue.getPath(), buildFileFragment);
       FileValue fileValue = getFileValue(buildFileRootedPath, env, packageIdentifier);
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupValue.java
index 5ed0e55..79f6a41 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupValue.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupValue.java
@@ -43,32 +43,32 @@
     WORKSPACE("WORKSPACE") {
       @Override
       public PathFragment getBuildFileFragment(PackageIdentifier packageIdentifier) {
-        return PathFragment.create(BuildFileName.WORKSPACE.getFilename());
+        return getFilenameFragment();
       }
     },
     BUILD("BUILD") {
       @Override
       public PathFragment getBuildFileFragment(PackageIdentifier packageIdentifier) {
-        return packageIdentifier.getPackageFragment().getChild(getFilename());
+        return packageIdentifier.getPackageFragment().getRelative(getFilenameFragment());
       }
     },
     BUILD_DOT_BAZEL("BUILD.bazel") {
       @Override
       public PathFragment getBuildFileFragment(PackageIdentifier packageIdentifier) {
-        return packageIdentifier.getPackageFragment().getChild(getFilename());
+        return packageIdentifier.getPackageFragment().getRelative(getFilenameFragment());
       }
     };
 
     private static final BuildFileName[] VALUES = BuildFileName.values();
 
-    private final String filename;
+    private final PathFragment filenameFragment;
 
     private BuildFileName(String filename) {
-      this.filename = filename;
+      this.filenameFragment = PathFragment.create(filename);
     }
 
-    public String getFilename() {
-      return filename;
+    public PathFragment getFilenameFragment() {
+      return filenameFragment;
     }
 
     /**