java.io fix and speedup

Jeff Sturm jsturm@one-point.com
Sat Jan 4 05:43:00 GMT 2003


On 4 Jan 2003, Mark Wielaard wrote:
> If the mmap patch from Jeff is useable in
> general then that would give us much bigger improvements.

Below is the patch I used (against 3.2 branch).  It only attempts to
mmap() for read access.  I don't know whether this is a good idea, versus
waiting for a possible java.nio implementation.

(I got the idea from Per Bothner, in a message I can't find now.)

Index: configure.in
===================================================================
RCS file: /cvs/gcc/gcc/libjava/configure.in,v
retrieving revision 1.114.2.16
diff -u -p -r1.114.2.16 configure.in
--- configure.in	8 May 2002 04:26:24 -0000	1.114.2.16
+++ configure.in	4 Jan 2003 05:28:24 -0000
@@ -497,7 +497,7 @@ if test -n "${with_cross_host}"; then
 else
    AC_CHECK_FUNCS(strerror ioctl select fstat open fsync sleep opendir)
    AC_CHECK_FUNCS(gmtime_r localtime_r readdir_r getpwuid_r getcwd)
-   AC_CHECK_FUNCS(access stat mkdir rename rmdir unlink realpath utime chmod)
+   AC_CHECK_FUNCS(access stat mkdir rename rmdir unlink realpath utime chmod mmap)
    AC_CHECK_FUNCS(nl_langinfo setlocale)
    AC_CHECK_FUNCS(inet_aton inet_addr, break)
    AC_CHECK_FUNCS(inet_pton uname inet_ntoa)
Index: java/io/FileDescriptor.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/io/FileDescriptor.java,v
retrieving revision 1.8.12.1
diff -u -p -r1.8.12.1 FileDescriptor.java
--- java/io/FileDescriptor.java	8 Mar 2002 00:43:29 -0000	1.8.12.1
+++ java/io/FileDescriptor.java	4 Jan 2003 05:28:24 -0000
@@ -100,4 +100,8 @@ public final class FileDescriptor
   // we want to make sure this has the value -1.  This is the most
   // efficient way to accomplish that.
   private int fd = -1;
+
+  private gnu.gcj.RawData maddr;
+  private long mlen;
+  private long mpos;
 }
Index: java/io/natFileDescriptorPosix.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/io/natFileDescriptorPosix.cc,v
retrieving revision 1.16.10.2
diff -u -p -r1.16.10.2 natFileDescriptorPosix.cc
--- java/io/natFileDescriptorPosix.cc	10 Mar 2002 18:00:04 -0000	1.16.10.2
+++ java/io/natFileDescriptorPosix.cc	4 Jan 2003 05:28:25 -0000
@@ -28,6 +28,10 @@ details.  */
 #include <sys/filio.h>
 #endif

+#ifdef HAVE_MMAP
+#include <sys/mman.h>
+#endif
+
 #include <gcj/cni.h>
 #include <jvm.h>
 #include <java/io/FileDescriptor.h>
@@ -124,6 +128,31 @@ java::io::FileDescriptor::open (jstring

   _Jv_platform_close_on_exec (fd);

+#ifdef HAVE_MMAP
+  maddr = NULL;
+  mlen = 0;
+  mpos = 0;
+#  ifdef O_BINARY
+  if (flags == O_RDONLY | O_BINARY)
+#  else
+  if (flags == O_RDONLY)
+#  endif
+    {
+      struct stat sb;
+      if (::fstat (fd, &sb) != -1)
+	{
+	  mlen = sb.st_size;
+	  maddr = (gnu::gcj::RawData *) ::mmap (NULL, mlen, PROT_READ,
+						MAP_SHARED, fd, 0);
+	  if (maddr == MAP_FAILED)
+	    {
+	      mlen = 0;
+	      maddr = NULL;
+	    }
+	}
+    }
+#endif
+
   return fd;
 }

@@ -185,6 +214,10 @@ java::io::FileDescriptor::close (void)
 {
   jint save = fd;
   fd = -1;
+#ifdef HAVE_MMAP
+  if (maddr)
+    ::munmap (maddr, mlen);
+#endif
   if (::close (save))
     throw new IOException (JvNewStringLatin1 (strerror (errno)));
 }
@@ -196,6 +229,23 @@ java::io::FileDescriptor::seek (jlong po

   jlong len = length ();
   jlong here = getFilePointer ();
+  off_t r;
+
+#ifdef HAVE_MMAP
+  if (maddr)
+    {
+      len = mlen;
+      here = mpos;
+    }
+  else
+    {
+#endif
+      len = length ();
+      here = getFilePointer ();
+#ifdef HAVE_MMAP
+    }
+#endif
+

   if (eof_trunc
       && ((whence == SET && pos > len) || (whence == CUR && here + pos > len)))
@@ -204,33 +254,76 @@ java::io::FileDescriptor::seek (jlong po
       pos = len;
     }

-  off_t r = ::lseek (fd, (off_t) pos, whence == SET ? SEEK_SET : SEEK_CUR);
-  if (r == -1)
-    throw new IOException (JvNewStringLatin1 (strerror (errno)));
+#ifdef HAVE_MMAP
+  if (maddr)
+    {
+      if (whence == SET)
+	mpos = pos;
+      else
+	mpos += pos;
+      r = mpos;
+    }
+  else
+    {
+#endif
+      r = ::lseek (fd, (off_t) pos, whence == SET ? SEEK_SET : SEEK_CUR);
+      if (r == -1)
+	throw new IOException (JvNewStringLatin1 (strerror (errno)));
+#ifdef HAVE_MMAP
+    }
+#endif
   return r;
 }

 jlong
 java::io::FileDescriptor::length (void)
 {
-  struct stat sb;
-  if (::fstat (fd, &sb))
-    throw new IOException (JvNewStringLatin1 (strerror (errno)));
-  return sb.st_size;
+#ifdef HAVE_MMAP
+  if (maddr)
+    {
+      return mlen;
+    }
+  else
+    {
+#endif
+      struct stat sb;
+      if (::fstat (fd, &sb))
+	throw new IOException (JvNewStringLatin1 (strerror (errno)));
+      return sb.st_size;
+#ifdef HAVE_MMAP
+    }
+#endif
 }

 jlong
 java::io::FileDescriptor::getFilePointer (void)
 {
-  off_t r = ::lseek (fd, 0, SEEK_CUR);
-  if (r == -1)
-    throw new IOException (JvNewStringLatin1 (strerror (errno)));
-  return r;
+#ifdef HAVE_MMAP
+  if (maddr)
+    {
+      return mpos;
+    }
+  else
+    {
+#endif
+      off_t r = ::lseek (fd, 0, SEEK_CUR);
+      if (r == -1)
+	throw new IOException (JvNewStringLatin1 (strerror (errno)));
+      return r;
+#ifdef HAVE_MMAP
+    }
+#endif
 }

 jint
 java::io::FileDescriptor::read (void)
 {
+#ifdef HAVE_MMAP
+  if (maddr)
+    {
+      return mpos < mlen ? ((unsigned char *) maddr)[mpos++] : -1;
+    }
+#endif
   jbyte b;
   int r = ::read (fd, &b, 1);
   if (r == 0)
@@ -258,6 +351,21 @@ java::io::FileDescriptor::read (jbyteArr
   if (offset < 0 || count < 0 || offset + count > bsize)
     throw new java::lang::ArrayIndexOutOfBoundsException;
   jbyte *bytes = elements (buffer) + offset;
+#ifdef HAVE_MMAP
+  if (maddr)
+    {
+      if (mpos < mlen)
+	{
+	  if (count > mlen - mpos)
+	    count = mlen - mpos;
+	  memcpy (bytes, ((char *) maddr) + mpos, count);
+	  mpos += count;
+	}
+      else
+	count = -1;
+      return count;
+    }
+#endif
   int r = ::read (fd, bytes, count);
   if (r == 0)
     return -1;



More information about the Java-patches mailing list