8154077: (fs) Reduce number of file system classes loaded during startup
Reviewed-by: bpb, chegar
--- 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;
--- 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;
--- 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;
--- 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);
--- 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;
+ }
+ }
}
--- 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.
*/
--- 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
--- 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 {
--- 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)