diff --git a/src/main/java/com/google/devtools/build/lib/vfs/BUILD b/src/main/java/com/google/devtools/build/lib/vfs/BUILD index 9655e34157ed4d..f80997f0305041 100644 --- a/src/main/java/com/google/devtools/build/lib/vfs/BUILD +++ b/src/main/java/com/google/devtools/build/lib/vfs/BUILD @@ -62,6 +62,7 @@ java_library( exclude = PATH_FRAGMENT_SOURCES + OUTPUT_SERVICE_SOURCES + OS_PATH_POLICY_SOURCES, ), deps = [ + ":ospathpolicy", ":pathfragment", "//src/main/java/com/google/devtools/build/lib/clock", "//src/main/java/com/google/devtools/build/lib/concurrent", diff --git a/src/main/java/com/google/devtools/build/lib/vfs/RootedPath.java b/src/main/java/com/google/devtools/build/lib/vfs/RootedPath.java index 3cf3bec280468e..c74062eacc0869 100644 --- a/src/main/java/com/google/devtools/build/lib/vfs/RootedPath.java +++ b/src/main/java/com/google/devtools/build/lib/vfs/RootedPath.java @@ -26,15 +26,21 @@ *

Two {@link RootedPath}s are considered equal iff they have equal roots and equal relative * paths. * - *

Instances are interned, which results in a large memory benefit (see cl/516855266). In - * addition to being a {@link SkyKey} itself, {@link RootedPath} is used as a field in several other - * common {@link SkyKey} types. Interning on the level of those keys does not deduplicate referenced - * {@link RootedPath} instances which are also used as a {@link SkyKey} directly. + *

Instances are interned (except on Windows), which results in a large memory benefit (see + * cl/516855266). In addition to being a {@link SkyKey} itself, {@link RootedPath} is used as a + * field in several other common {@link SkyKey} types. Interning on the level of those keys does not + * deduplicate referenced {@link RootedPath} instances which are also used as a {@link SkyKey} + * directly. */ @AutoCodec public final class RootedPath implements Comparable, FileStateKey { - private static final SkyKeyInterner interner = SkyKey.newInterner(); + // Interning on Windows (case-insensitive) surfaces a bug where paths that only differ in casing + // use the same RootedPath instance. + // TODO(#17904): Investigate this bug and add test coverage. + @Nullable + private static final SkyKeyInterner interner = + OsPathPolicy.getFilePathOs().isCaseSensitive() ? SkyKey.newInterner() : null; private final Root root; private final PathFragment rootRelativePath; @@ -52,7 +58,8 @@ static RootedPath createInternal(Root root, PathFragment rootRelativePath) { "rootRelativePath: %s root: %s", rootRelativePath, root); - return interner.intern(new RootedPath(root, rootRelativePath)); + var rootedPath = new RootedPath(root, rootRelativePath); + return interner != null ? interner.intern(rootedPath) : rootedPath; } private RootedPath(Root root, PathFragment rootRelativePath) { @@ -153,6 +160,7 @@ public RootedPath argument() { } @Override + @Nullable public SkyKeyInterner getSkyKeyInterner() { return interner; }