# HG changeset patch # User jlahoda # Date 1485957786 -3600 # Node ID 266c9503e22fc1b1beeb19dd1d54ba1ec1b7e44c # Parent 4287765963d55a9384e19025797420d7296ac89c 8171294: Slow compilation with long classpaths under JDK 9 Summary: Precompute packages contained in jars, to quickly determine at the lookup time whether a jar contains the given package Reviewed-by: jjg Contributed-by: maurizio.cimadamore@oracle.com diff -r 4287765963d5 -r 266c9503e22f langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java Tue Jan 31 17:01:55 2017 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java Wed Feb 01 15:03:06 2017 +0100 @@ -502,7 +502,7 @@ private final class ArchiveContainer implements Container { private final Path archivePath; private final FileSystem fileSystem; - private final Map pathCache = new HashMap<>(); + private final Map packages; public ArchiveContainer(Path archivePath) throws IOException, ProviderNotFoundException, SecurityException { this.archivePath = archivePath; @@ -514,6 +514,21 @@ } else { this.fileSystem = FileSystems.newFileSystem(archivePath, null); } + packages = new HashMap<>(); + for (Path root : fileSystem.getRootDirectories()) { + Files.walkFileTree(root, EnumSet.noneOf(FileVisitOption.class), Integer.MAX_VALUE, + new SimpleFileVisitor() { + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { + if (isValid(dir.getFileName())) { + packages.put(new RelativeDirectory(root.relativize(dir).toString()), dir); + return FileVisitResult.CONTINUE; + } else { + return FileVisitResult.SKIP_SUBTREE; + } + } + }); + } } /** @@ -526,7 +541,7 @@ Set fileKinds, boolean recurse, ListBuffer resultList) throws IOException { - Path resolvedSubdirectory = resolvePath(subdirectory); + Path resolvedSubdirectory = packages.get(subdirectory); if (resolvedSubdirectory == null) return ; @@ -544,18 +559,6 @@ } } - boolean isValid(Path fileName) { - if (fileName == null) { - return true; - } else { - String name = fileName.toString(); - if (name.endsWith("/")) { - name = name.substring(0, name.length() - 1); - } - return SourceVersion.isIdentifier(name); - } - } - @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { if (attrs.isRegularFile() && fileKinds.contains(getKind(file.getFileName().toString()))) { @@ -569,27 +572,29 @@ } - @Override - public JavaFileObject getFileObject(Path userPath, RelativeFile name) throws IOException { - Path p = resolvePath(name); - if (p != null) - return PathFileObject.forJarPath(JavacFileManager.this, p, userPath); - - return null; + private boolean isValid(Path fileName) { + if (fileName == null) { + return true; + } else { + String name = fileName.toString(); + if (name.endsWith("/")) { + name = name.substring(0, name.length() - 1); + } + return SourceVersion.isIdentifier(name); + } } - private synchronized Path resolvePath(RelativePath path) { - if (!pathCache.containsKey(path)) { - Path relativePath = path.resolveAgainst(fileSystem); - - if (!Files.exists(relativePath)) { - relativePath = null; + @Override + public JavaFileObject getFileObject(Path userPath, RelativeFile name) throws IOException { + RelativeDirectory root = name.dirname(); + Path packagepath = packages.get(root); + if (packagepath != null) { + Path relpath = packagepath.resolve(name.basename()); + if (Files.exists(relpath)) { + return PathFileObject.forJarPath(JavacFileManager.this, relpath, userPath); } - - pathCache.put(path, relativePath); - return relativePath; } - return pathCache.get(path); + return null; } @Override