# HG changeset patch # User alanb # Date 1460554165 -3600 # Node ID 931e55c1287da022f3d33090cc434fa53a02411d # Parent 9cb6e1141bdbd11380e1d5b63bbc1a0e38ba486a 8154077: (fs) Reduce number of file system classes loaded during startup Reviewed-by: bpb, chegar diff -r 9cb6e1141bdb -r 931e55c1287d jdk/make/mapfiles/libnio/mapfile-linux --- a/jdk/make/mapfiles/libnio/mapfile-linux Wed Apr 13 15:05:50 2016 +0200 +++ b/jdk/make/mapfiles/libnio/mapfile-linux Wed Apr 13 14:29:25 2016 +0100 @@ -161,7 +161,9 @@ Java_sun_nio_fs_UnixNativeDispatcher_strerror; Java_sun_nio_fs_UnixNativeDispatcher_dup; Java_sun_nio_fs_UnixNativeDispatcher_access0; + Java_sun_nio_fs_UnixNativeDispatcher_exists0; Java_sun_nio_fs_UnixNativeDispatcher_stat0; + Java_sun_nio_fs_UnixNativeDispatcher_stat1; Java_sun_nio_fs_UnixNativeDispatcher_lstat0; Java_sun_nio_fs_UnixNativeDispatcher_fstat; Java_sun_nio_fs_UnixNativeDispatcher_fstatat0; diff -r 9cb6e1141bdb -r 931e55c1287d jdk/make/mapfiles/libnio/mapfile-macosx --- a/jdk/make/mapfiles/libnio/mapfile-macosx Wed Apr 13 15:05:50 2016 +0200 +++ b/jdk/make/mapfiles/libnio/mapfile-macosx Wed Apr 13 14:29:25 2016 +0100 @@ -138,7 +138,9 @@ Java_sun_nio_fs_UnixNativeDispatcher_strerror; Java_sun_nio_fs_UnixNativeDispatcher_dup; Java_sun_nio_fs_UnixNativeDispatcher_access0; + Java_sun_nio_fs_UnixNativeDispatcher_exists0; Java_sun_nio_fs_UnixNativeDispatcher_stat0; + Java_sun_nio_fs_UnixNativeDispatcher_stat1; Java_sun_nio_fs_UnixNativeDispatcher_lstat0; Java_sun_nio_fs_UnixNativeDispatcher_fstat; Java_sun_nio_fs_UnixNativeDispatcher_fstatat0; diff -r 9cb6e1141bdb -r 931e55c1287d jdk/make/mapfiles/libnio/mapfile-solaris --- a/jdk/make/mapfiles/libnio/mapfile-solaris Wed Apr 13 15:05:50 2016 +0200 +++ b/jdk/make/mapfiles/libnio/mapfile-solaris Wed Apr 13 14:29:25 2016 +0100 @@ -138,7 +138,9 @@ Java_sun_nio_fs_UnixNativeDispatcher_strerror; Java_sun_nio_fs_UnixNativeDispatcher_dup; Java_sun_nio_fs_UnixNativeDispatcher_access0; + Java_sun_nio_fs_UnixNativeDispatcher_exists0; Java_sun_nio_fs_UnixNativeDispatcher_stat0; + Java_sun_nio_fs_UnixNativeDispatcher_stat1; Java_sun_nio_fs_UnixNativeDispatcher_lstat0; Java_sun_nio_fs_UnixNativeDispatcher_fstat; Java_sun_nio_fs_UnixNativeDispatcher_fstatat0; diff -r 9cb6e1141bdb -r 931e55c1287d jdk/src/java.base/share/classes/java/nio/file/Files.java --- a/jdk/src/java.base/share/classes/java/nio/file/Files.java Wed Apr 13 15:05:50 2016 +0200 +++ b/jdk/src/java.base/share/classes/java/nio/file/Files.java Wed Apr 13 14:29:25 2016 +0100 @@ -77,6 +77,8 @@ import java.util.stream.Stream; import java.util.stream.StreamSupport; +import sun.nio.fs.AbstractFileSystemProvider; + /** * This class consists exclusively of static methods that operate on files, * directories, or other types of files. @@ -2193,6 +2195,12 @@ * method denies read access to the file. */ public static boolean isDirectory(Path path, LinkOption... options) { + if (options.length == 0) { + FileSystemProvider provider = provider(path); + if (provider instanceof AbstractFileSystemProvider) + return ((AbstractFileSystemProvider)provider).isDirectory(path); + } + try { return readAttributes(path, BasicFileAttributes.class, options).isDirectory(); } catch (IOException ioe) { @@ -2230,6 +2238,12 @@ * method denies read access to the file. */ public static boolean isRegularFile(Path path, LinkOption... options) { + if (options.length == 0) { + FileSystemProvider provider = provider(path); + if (provider instanceof AbstractFileSystemProvider) + return ((AbstractFileSystemProvider)provider).isRegularFile(path); + } + try { return readAttributes(path, BasicFileAttributes.class, options).isRegularFile(); } catch (IOException ioe) { @@ -2385,6 +2399,12 @@ * @see #notExists */ public static boolean exists(Path path, LinkOption... options) { + if (options.length == 0) { + FileSystemProvider provider = provider(path); + if (provider instanceof AbstractFileSystemProvider) + return ((AbstractFileSystemProvider)provider).exists(path); + } + try { if (followLinks(options)) { provider(path).checkAccess(path); diff -r 9cb6e1141bdb -r 931e55c1287d jdk/src/java.base/share/classes/sun/nio/fs/AbstractFileSystemProvider.java --- a/jdk/src/java.base/share/classes/sun/nio/fs/AbstractFileSystemProvider.java Wed Apr 13 15:05:50 2016 +0200 +++ b/jdk/src/java.base/share/classes/sun/nio/fs/AbstractFileSystemProvider.java Wed Apr 13 14:29:25 2016 +0100 @@ -25,7 +25,9 @@ package sun.nio.fs; -import java.nio.file.*; +import java.nio.file.Path; +import java.nio.file.LinkOption; +import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.spi.FileSystemProvider; import java.io.IOException; import java.util.Map; @@ -34,7 +36,7 @@ * Base implementation class of FileSystemProvider */ -abstract class AbstractFileSystemProvider extends FileSystemProvider { +public abstract class AbstractFileSystemProvider extends FileSystemProvider { protected AbstractFileSystemProvider() { } /** @@ -107,4 +109,49 @@ public final boolean deleteIfExists(Path file) throws IOException { return implDelete(file, false); } + + /** + * Tests whether a file is a directory. + * + * @return {@code true} if the file is a directory; {@code false} if + * the file does not exist, is not a directory, or it cannot + * be determined if the file is a directory or not. + */ + public boolean isDirectory(Path file) { + try { + return readAttributes(file, BasicFileAttributes.class).isDirectory(); + } catch (IOException ioe) { + return false; + } + } + + /** + * Tests whether a file is a regular file with opaque content. + * + * @return {@code true} if the file is a regular file; {@code false} if + * the file does not exist, is not a regular file, or it + * cannot be determined if the file is a regular file or not. + */ + public boolean isRegularFile(Path file) { + try { + return readAttributes(file, BasicFileAttributes.class).isRegularFile(); + } catch (IOException ioe) { + return false; + } + } + + /** + * Checks the existence of a file. + * + * @return {@code true} if the file exists; {@code false} if the file does + * not exist or its existence cannot be determined. + */ + public boolean exists(Path file) { + try { + checkAccess(file); + return true; + } catch (IOException ioe) { + return false; + } + } } diff -r 9cb6e1141bdb -r 931e55c1287d jdk/src/java.base/unix/classes/sun/nio/fs/UnixFileSystemProvider.java --- a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixFileSystemProvider.java Wed Apr 13 15:05:50 2016 +0200 +++ b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixFileSystemProvider.java Wed Apr 13 14:29:25 2016 +0100 @@ -499,6 +499,29 @@ } } + @Override + public final boolean isDirectory(Path obj) { + UnixPath file = UnixPath.toUnixPath(obj); + file.checkRead(); + int mode = UnixNativeDispatcher.stat(file); + return ((mode & UnixConstants.S_IFMT) == UnixConstants.S_IFDIR); + } + + @Override + public final boolean isRegularFile(Path obj) { + UnixPath file = UnixPath.toUnixPath(obj); + file.checkRead(); + int mode = UnixNativeDispatcher.stat(file); + return ((mode & UnixConstants.S_IFMT) == UnixConstants.S_IFREG); + } + + @Override + public final boolean exists(Path obj) { + UnixPath file = UnixPath.toUnixPath(obj); + file.checkRead(); + return UnixNativeDispatcher.exists(file); + } + /** * Returns a {@code FileTypeDetector} for this platform. */ diff -r 9cb6e1141bdb -r 931e55c1287d jdk/src/java.base/unix/classes/sun/nio/fs/UnixNativeDispatcher.java --- a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixNativeDispatcher.java Wed Apr 13 15:05:50 2016 +0200 +++ b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixNativeDispatcher.java Wed Apr 13 14:29:25 2016 +0100 @@ -296,6 +296,23 @@ private static native void stat0(long pathAddress, UnixFileAttributes attrs) throws UnixException; + + /** + * stat(const char* path, struct stat* buf) + * + * @return st_mode (file type and mode) or 0 if an error occurs. + */ + static int stat(UnixPath path) { + NativeBuffer buffer = copyToNativeBuffer(path); + try { + return stat1(buffer.address()); + } finally { + buffer.release(); + } + } + private static native int stat1(long pathAddress); + + /** * lstat(const char* path, struct stat* buf) */ @@ -459,6 +476,22 @@ private static native void access0(long pathAddress, int amode) throws UnixException; /** + * access(constant char* path, F_OK) + * + * @return true if the file exists, false otherwise + */ + static boolean exists(UnixPath path) { + NativeBuffer buffer = copyToNativeBuffer(path); + try { + return exists0(buffer.address()); + } finally { + buffer.release(); + } + } + private static native boolean exists0(long pathAddress); + + + /** * struct passwd *getpwuid(uid_t uid); * * @return passwd->pw_name diff -r 9cb6e1141bdb -r 931e55c1287d jdk/src/java.base/unix/classes/sun/nio/fs/UnixUriUtils.java --- a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixUriUtils.java Wed Apr 13 15:05:50 2016 +0200 +++ b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixUriUtils.java Wed Apr 13 14:29:25 2016 +0100 @@ -114,12 +114,9 @@ // trailing slash if directory if (sb.charAt(sb.length()-1) != '/') { - try { - if (UnixFileAttributes.get(up, true).isDirectory()) - sb.append('/'); - } catch (UnixException x) { - // ignore - } + int mode = UnixNativeDispatcher.stat(up); + if ((mode & UnixConstants.S_IFMT) == UnixConstants.S_IFDIR) + sb.append('/'); } try { diff -r 9cb6e1141bdb -r 931e55c1287d jdk/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c --- a/jdk/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c Wed Apr 13 15:05:50 2016 +0200 +++ b/jdk/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c Wed Apr 13 14:29:25 2016 +0100 @@ -483,6 +483,20 @@ } } +JNIEXPORT jint JNICALL +Java_sun_nio_fs_UnixNativeDispatcher_stat1(JNIEnv* env, jclass this, jlong pathAddress) { + int err; + struct stat64 buf; + const char* path = (const char*)jlong_to_ptr(pathAddress); + + RESTARTABLE(stat64(path, &buf), err); + if (err == -1) { + return 0; + } else { + return (jint)buf.st_mode; + } +} + JNIEXPORT void JNICALL Java_sun_nio_fs_UnixNativeDispatcher_lstat0(JNIEnv* env, jclass this, jlong pathAddress, jobject attrs) @@ -897,6 +911,14 @@ } } +JNIEXPORT jboolean JNICALL +Java_sun_nio_fs_UnixNativeDispatcher_exists0(JNIEnv* env, jclass this, jlong pathAddress) { + int err; + const char* path = (const char*)jlong_to_ptr(pathAddress); + RESTARTABLE(access(path, F_OK), err); + return (err == 0) ? JNI_TRUE : JNI_FALSE; +} + JNIEXPORT void JNICALL Java_sun_nio_fs_UnixNativeDispatcher_statvfs0(JNIEnv* env, jclass this, jlong pathAddress, jobject attrs)