Index: configure.ac
===================================================================
RCS file: /cvsroot/classpath/classpath/configure.ac,v
retrieving revision 1.95
diff -u -b -B -r1.95 configure.ac
--- configure.ac	15 Jul 2005 15:58:35 -0000	1.95
+++ configure.ac	19 Jul 2005 06:33:27 -0000
@@ -175,7 +175,8 @@
 		    sys/time.h \
 		    sys/select.h \
 		    crt_externs.h \
-                    fcntl.h])
+                    fcntl.h \
+		    sys/mman.h])
 
   AC_EGREP_HEADER(uint32_t, stdint.h, AC_DEFINE(HAVE_INT32_DEFINED, 1, [Define to 1 if you have uint32_t]))
   AC_EGREP_HEADER(uint32_t, inttypes.h, AC_DEFINE(HAVE_INT32_DEFINED, 1, [Define to 1 if you have uint32_t]))
@@ -189,7 +190,8 @@
 		  recvfrom send sendto setsockopt getsockopt time mktime \
 		  localtime_r \
 		  strerror_r \
-                  fcntl])
+                  fcntl \
+		  mmap munmap mincore msync getpagesize sysconf])
 
   AC_HEADER_TIME
   AC_STRUCT_TM
Index: include/java_nio_VMDirectByteBuffer.h
===================================================================
RCS file: /cvsroot/classpath/classpath/include/java_nio_VMDirectByteBuffer.h,v
retrieving revision 1.1
diff -u -b -B -r1.1 java_nio_VMDirectByteBuffer.h
--- include/java_nio_VMDirectByteBuffer.h	21 Nov 2004 11:03:46 -0000	1.1
+++ include/java_nio_VMDirectByteBuffer.h	19 Jul 2005 06:33:27 -0000
@@ -15,7 +15,8 @@
 JNIEXPORT void JNICALL Java_java_nio_VMDirectByteBuffer_free (JNIEnv *env, jclass, jobject);
 JNIEXPORT jbyte JNICALL Java_java_nio_VMDirectByteBuffer_get__Lgnu_classpath_RawData_2I (JNIEnv *env, jclass, jobject, jint);
 JNIEXPORT void JNICALL Java_java_nio_VMDirectByteBuffer_get__Lgnu_classpath_RawData_2I_3BII (JNIEnv *env, jclass, jobject, jint, jbyteArray, jint, jint);
-JNIEXPORT void JNICALL Java_java_nio_VMDirectByteBuffer_put (JNIEnv *env, jclass, jobject, jint, jbyte);
+JNIEXPORT void JNICALL Java_java_nio_VMDirectByteBuffer_put__Lgnu_classpath_RawData_2IB (JNIEnv *env, jclass, jobject, jint, jbyte);
+JNIEXPORT void JNICALL Java_java_nio_VMDirectByteBuffer_put__Lgnu_classpath_RawData_2I_3BII (JNIEnv *env, jclass, jobject, jint, jbyteArray, jint, jint);
 JNIEXPORT jobject JNICALL Java_java_nio_VMDirectByteBuffer_adjustAddress (JNIEnv *env, jclass, jobject, jint);
 JNIEXPORT void JNICALL Java_java_nio_VMDirectByteBuffer_shiftDown (JNIEnv *env, jclass, jobject, jint, jint, jint);
 
Index: java/nio/DirectByteBufferImpl.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/nio/DirectByteBufferImpl.java,v
retrieving revision 1.19
diff -u -b -B -r1.19 DirectByteBufferImpl.java
--- java/nio/DirectByteBufferImpl.java	2 Jul 2005 20:32:39 -0000	1.19
+++ java/nio/DirectByteBufferImpl.java	19 Jul 2005 06:33:27 -0000
@@ -179,6 +179,18 @@
     return this;
   }
   
+  public ByteBuffer put (byte[] src, int offset, int length)
+  {
+    checkArraySize (src.length, offset, length);
+    checkForUnderflow (length);
+
+    int index = position ();
+    VMDirectByteBuffer.put (address, index, src, offset, length);
+    position (index + length);
+
+    return this;
+  }
+
   void shiftDown(int dst_offset, int src_offset, int count)
   {
     VMDirectByteBuffer.shiftDown(address, dst_offset, src_offset, count);
Index: java/nio/MappedByteBufferImpl.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/nio/MappedByteBufferImpl.java,v
retrieving revision 1.17
diff -u -b -B -r1.17 MappedByteBufferImpl.java
Index: native/jni/java-nio/gnu_java_nio_channels_FileChannelImpl.c
===================================================================
RCS file: /cvsroot/classpath/classpath/native/jni/java-nio/gnu_java_nio_channels_FileChannelImpl.c,v
retrieving revision 1.18
diff -u -b -B -r1.18 gnu_java_nio_channels_FileChannelImpl.c
--- native/jni/java-nio/gnu_java_nio_channels_FileChannelImpl.c	11 Jul 2005 17:27:55 -0000	1.18
+++ native/jni/java-nio/gnu_java_nio_channels_FileChannelImpl.c	19 Jul 2005 06:33:27 -0000
@@ -56,6 +56,10 @@
 #include <fcntl.h>
 #endif /* HAVE_FCNTL_H */
 
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif /* HAVE_SYS_MMAN_H */
+
 /* These values must be kept in sync with FileChannelImpl.java.  */
 #define FILECHANNELIMPL_READ   1
 #define FILECHANNELIMPL_WRITE  2
@@ -91,6 +95,10 @@
 #define CONVERT_SSIZE_T_TO_JINT(x) ((jint)(x & 0xFFFFFFFF))
 #define CONVERT_JINT_TO_SSIZE_T(x) (x)
 
+/* Align a value up or down to a multiple of the pagesize. */
+#define ALIGN_DOWN(p,s) ((p) - ((p) % (s)))
+#define ALIGN_UP(p,s) ((p) + ((s) - ((p) % (s))))
+
 /* cached fieldID of gnu.java.nio.channels.FileChannelImpl.fd */
 static jfieldID native_fd_fieldID;
 
@@ -503,13 +511,110 @@
 }
 
 JNIEXPORT jobject JNICALL
-Java_gnu_java_nio_channels_FileChannelImpl_mapImpl (JNIEnv * env,
-						    jobject obj
-						    __attribute__ ((__unused__)), jchar mode __attribute__ ((__unused__)), jlong position __attribute__ ((__unused__)), jint size __attribute__ ((__unused__)))
+Java_gnu_java_nio_channels_FileChannelImpl_mapImpl (JNIEnv *env, jobject obj,
+						    jchar mode, jlong position, jint size)
 {
+#ifdef HAVE_MMAP
+  jclass MappedByteBufferImpl_class;
+  jclass RawData_class;
+  jmethodID MappedByteBufferImpl_init;
+  jmethodID RawData_init;
+  jobject RawData_instance;
+  long pagesize;
+  int prot, flags;
+  int fd;
+  void *p;
+
+  /* FIXME: should we just assume we're on an OS modern enough to
+     have 'sysconf'? And not check for 'getpagesize'? */
+#if defined(HAVE_GETPAGESIZE)
+  pagesize = getpagesize ();
+#elif defined(HAVE_SYSCONF)
+  pagesize = sysconf (_SC_PAGESIZE);
+#else
+  JCL_ThrowException (env, IO_EXCEPTION,
+		      "can't determine memory page size");
+  return NULL;
+#endif /* HAVE_GETPAGESIZE/HAVE_SYSCONF */
+
+  prot = PROT_READ;
+  if (mode == '+')
+    prot |= PROT_WRITE;
+  flags = (mode == 'c' ? MAP_PRIVATE : MAP_SHARED);
+  fd = get_native_fd (env, obj);
+  p = mmap (NULL, (size_t) ALIGN_UP (size, pagesize), prot, flags,
+	    fd, ALIGN_DOWN (position, pagesize));
+  if (p == MAP_FAILED)
+    {
+      JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+      return NULL;
+    }
+
+  /* Unalign the mapped value back up, since we aligned offset
+     down to a multiple of the page size. */
+  p += position % pagesize;
+
+#if (SIZEOF_VOID_P == 4)
+  RawData_class = (*env)->FindClass (env, "gnu/classpath/RawData32");
+  if (RawData_class != NULL)
+    {
+      RawData_init = (*env)->GetMethodID (env, RawData_class,
+					  "<init>", "(I)V");
+    }
+#elif (SIZEOF_VOID_P == 8)
+  RawData_class = (*env)->FindClass (env, "gnu/classpath/RawData64");
+  if (RawData_class != NULL)
+    {
+      RawData_init = (*env)->GetMethodID (env, RawData_class,
+					  "<init>", "(J)V");
+    }
+#else
+  JCL_ThrowException (env, IO_EXCEPTION,
+		      "pointer size not supported");
+  return NULL;
+#endif /* SIZEOF_VOID_P */
+
+  if ((*env)->ExceptionOccurred (env))
+    {
+      munmap (p, ALIGN_UP (size, pagesize));
+      return NULL;
+    }
+
+#if (SIZEOF_VOID_P == 4)
+  RawData_instance = (*env)->NewObject (env, RawData_class,
+					RawData_init, (jint) p);
+#elif (SIZEOF_VOID_P == 8)
+  RawData_instance = (*env)->NewObject (env, RawData_class,
+					RawData_init, (jlong) p);
+#endif /* SIZEOF_VOID_P */
+
+  MappedByteBufferImpl_class = (*env)->FindClass (env,
+						  "java/nio/MappedByteBufferImpl");
+  if (MappedByteBufferImpl_class != NULL)
+    {
+      MappedByteBufferImpl_init =
+	(*env)->GetMethodID (env, MappedByteBufferImpl_class,
+			     "<init>", "(Lgnu/classpath/RawData;IZ)V");
+    }
+
+  if ((*env)->ExceptionOccurred (env))
+    {
+      munmap (p, ALIGN_UP (size, pagesize));
+      return NULL;
+    }
+
+  return (*env)->NewObject (env, MappedByteBufferImpl_class,
+			    MappedByteBufferImpl_init, RawData_instance,
+			    (jint) size, mode == 'r');
+#else
+  (void) obj;
+  (void) mode;
+  (void) position;
+  (void) size;
   JCL_ThrowException (env, IO_EXCEPTION,
-		      "java.nio.FileChannelImpl.nio_mmap_file(): not implemented");
+		      "memory-mapped files not implemented");
   return 0;
+#endif /* HAVE_MMAP */
 }
 
 /*
Index: native/jni/java-nio/java_nio_MappedByteBufferImpl.c
===================================================================
RCS file: /cvsroot/classpath/classpath/native/jni/java-nio/java_nio_MappedByteBufferImpl.c,v
retrieving revision 1.4
diff -u -b -B -r1.4 java_nio_MappedByteBufferImpl.c
--- native/jni/java-nio/java_nio_MappedByteBufferImpl.c	2 Jul 2005 20:32:55 -0000	1.4
+++ native/jni/java-nio/java_nio_MappedByteBufferImpl.c	19 Jul 2005 06:33:27 -0000
@@ -1,5 +1,5 @@
 /* java_nio_MappedByteBufferImpl.c - Native methods for MappedByteBufferImpl
-   Copyright (C) 2004  Free Software Foundation, Inc.
+   Copyright (C) 2004,2005  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -43,41 +43,175 @@
 
 #include "java_nio_MappedByteBufferImpl.h"
 
+#include <errno.h>
+#include <string.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif /* HAVE_SYS_MMAN_H */
+
 #define IO_EXCEPTION "java/io/IOException"
 
+/* FIXME these is defined in gnu_java_nio_channels_FileChannelImpl
+   too; should be someplace common. */
+#define ALIGN_DOWN(p,s) ((p) - ((p) % (s)))
+#define ALIGN_UP(p,s) ((p) + ((s) - ((p) % (s))))
+
+static long
+get_pagesize (void)
+{
+#ifdef HAVE_GETPAGESIZE
+  return getpagesize ();
+#else
+#ifdef HAVE_SYSCONF
+  return sysconf (_SC_PAGESIZE);
+#endif /* HAVE_SYSCONF */
+#endif /* HAVE_GETPAGESIZE */
+}
+
+static void
+get_raw_values (JNIEnv *env, jobject this, void **address, size_t *size)
+{
+  const long pagesize = get_pagesize ();
+  jfieldID MappedByteBufferImpl_address;
+  jfieldID MappedByteBufferImpl_size;
+  jfieldID RawData_data;
+  jobject MappedByteBufferImpl_address_value;
+
+  *address = NULL;
+  MappedByteBufferImpl_address
+    = (*env)->GetFieldID (env, (*env)->GetObjectClass (env, this),
+			  "address", "Lgnu/classpath/RawData;");
+  MappedByteBufferImpl_size
+    = (*env)->GetFieldID (env, (*env)->GetObjectClass (env, this),
+			  "size", "I");
+  if (MappedByteBufferImpl_address != NULL)
+    {
+      MappedByteBufferImpl_address_value =
+	(*env)->GetObjectField (env, this, MappedByteBufferImpl_address);
+    }
+  if ((*env)->ExceptionOccurred (env))
+    return;
+
+#if (SIZEOF_VOID_P == 4)
+  RawData_data =
+    (*env)->GetFieldID (env, (*env)->GetObjectClass (env, MappedByteBufferImpl_address_value),
+			"data", "I");
+  *address = (void *)
+    ALIGN_DOWN ((*env)->GetIntField (env, MappedByteBufferImpl_address_value,
+				     RawData_data), pagesize);
+#endif /* SIZEOF_VOID_P == 4 */
+#if (SIZEOF_VOID_P == 8)
+  RawData_data =
+    (*env)->GetFieldID (env, (*env)->GetObjectClass (MappedByteBufferImpl_address_value),
+			"data", "J");
+  *address = (void *)
+    ALIGN_DOWN ((*env)->GetLongField (env, MappedByteBufferImpl_address_value,
+				      RawData_data), pagesize);
+#endif /* SIZEOF_VOID_P == 8 */
+
+  *size = (size_t)
+    ALIGN_UP ((*env)->GetIntField (env, this, MappedByteBufferImpl_size),
+	      pagesize);
+}
+
 JNIEXPORT void JNICALL
-Java_java_nio_MappedByteBufferImpl_unmapImpl (JNIEnv * env,
-					      jclass class
-					      __attribute__ ((__unused__)))
+Java_java_nio_MappedByteBufferImpl_unmapImpl (JNIEnv *env, jobject this)
 {
+#ifdef HAVE_MUNMAP
+  void *address;
+  size_t size;
+
+  get_raw_values (env, this, &address, &size);
+
+  if (address == NULL)
+    return;
+
+  if (munmap (address, size) != 0)
+    {
+      JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+      return;
+    }
+#else
   JCL_ThrowException (env, IO_EXCEPTION,
-		      "java.nio.MappedByteBufferImpl.unmapImpl(): not implemented");
+		      "unmapping files not implemented");
+#endif /* HAVE_MUNMAP */
 }
 
 JNIEXPORT jboolean JNICALL
-Java_java_nio_MappedByteBufferImpl_isLoadedImpl (JNIEnv * env,
-						 jclass class
-						 __attribute__ ((__unused__)))
+Java_java_nio_MappedByteBufferImpl_isLoadedImpl (JNIEnv * env, jobject this)
 {
-  JCL_ThrowException (env, IO_EXCEPTION,
-		      "java.nio.MappedByteBufferImpl.isLoadedImpl(): not implemented");
-  return 0;
+#ifdef HAVE_MINCORE
+  void *address;
+  size_t size;
+  unsigned char *vec;
+  size_t count;
+  int i;
+  const long pagesize = get_pagesize ();
+
+  get_raw_values (env, this, &address, &size);
+  if (address == NULL)
+    return JNI_FALSE;
+  count = (size_t) ((size + pagesize - 1) / pagesize);
+  vec = (unsigned char *) malloc (count * sizeof (unsigned char));
+  if (mincore (address, size, vec) != 0)
+    {
+      free (vec);
+      JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+      return JNI_FALSE;
+    }
+
+  for (i = 0; i < count; i++)
+    {
+      if ((vec[i] & 1) == 0)
+	return JNI_FALSE;
+    }
+  return JNI_TRUE;
+#else
+  return JNI_FALSE;
+#endif
 }
 
 JNIEXPORT void JNICALL
-Java_java_nio_MappedByteBufferImpl_loadImpl (JNIEnv * env,
-					     jclass clazz
-					     __attribute__ ((__unused__)))
+Java_java_nio_MappedByteBufferImpl_loadImpl (JNIEnv *env, jobject this)
 {
-  JCL_ThrowException (env, IO_EXCEPTION,
-		      "java.nio.MappedByteBufferImpl.loadImpl(): not implemented");
+  void *address;
+  size_t size;
+  int i;
+  const long pagesize = get_pagesize ();
+  int foo = 0;
+
+  get_raw_values (env, this, &address, &size);
+
+  /* FIXME: I'd bet dollars for donuts the compiler optimizes this
+     away. How can we load memory into core??? */
+  for (i = 0; i < size; i += pagesize)
+    {
+      foo += ((int *) address)[i];
+    }
 }
 
 JNIEXPORT void JNICALL
-Java_java_nio_MappedByteBufferImpl_forceImpl (JNIEnv * env,
-					      jclass class
-					      __attribute__ ((__unused__)))
+Java_java_nio_MappedByteBufferImpl_forceImpl (JNIEnv *env, jobject this)
 {
+#ifdef HAVE_MSYNC
+  void *address;
+  size_t size;
+
+  get_raw_values (env, this, &address, &size);
+
+  if (address == NULL)
+    return;
+
+  /* FIXME: is using MS_SYNC ok? Should we use MS_INVALIDATE? */
+  if (msync (address, size, MS_SYNC) != 0)
+    {
+      JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+    }
+#else
   JCL_ThrowException (env, IO_EXCEPTION,
-		      "java.nio.MappedByteBufferImpl.forceImpl(): not implemented");
+		      "forcing mapped files to disk not implemented");
+#endif /* HAVE_MSYNC */
 }
Index: native/jni/java-nio/java_nio_VMDirectByteBuffer.c
===================================================================
RCS file: /cvsroot/classpath/classpath/native/jni/java-nio/java_nio_VMDirectByteBuffer.c,v
retrieving revision 1.6
diff -u -b -B -r1.6 java_nio_VMDirectByteBuffer.c
--- native/jni/java-nio/java_nio_VMDirectByteBuffer.c	2 Jul 2005 20:32:55 -0000	1.6
+++ native/jni/java-nio/java_nio_VMDirectByteBuffer.c	19 Jul 2005 06:33:27 -0000
@@ -179,7 +179,7 @@
 }
 
 JNIEXPORT void JNICALL
-Java_java_nio_VMDirectByteBuffer_put
+Java_java_nio_VMDirectByteBuffer_put__Lgnu_classpath_RawData_2IB
   (JNIEnv * env, jclass clazz __attribute__ ((__unused__)),
    jobject address, jint index, jbyte value)
 {
@@ -193,8 +193,20 @@
    jobject address, jint index, jbyteArray dst, jint dst_offset, jint dst_len)
 {
   jbyte *src = (jbyte *) NIOGetPointer (env, address) + index;
-  memcpy ((*env)->GetByteArrayElements (env, dst, NULL) + dst_offset, src,
-	  dst_len);
+  jbyte *_dst = (*env)->GetByteArrayElements (env, dst, NULL) + dst_offset;
+  memcpy (_dst, src, dst_len);
+  (*env)->ReleaseByteArrayElements (env, dst, _dst, 0);
+}
+
+JNIEXPORT void JNICALL
+Java_java_nio_VMDirectByteBuffer_put__Lgnu_classpath_RawData_2I_3BII
+  (JNIEnv *env, jclass clazz __attribute__ ((__unused__)),
+   jobject address, jint index, jbyteArray src, jint src_offset, jint src_len)
+{
+  jbyte *_src = (*env)->GetByteArrayElements (env, src, NULL) + src_offset;
+  jbyte *dst = NIOGetPointer (env, address) + index;
+  (*env)->ReleaseByteArrayElements (env, src, _src, 0);
+  memcpy (dst, _src, src_len);
 }
 
 JNIEXPORT void JNICALL
Index: vm/reference/java/nio/VMDirectByteBuffer.java
===================================================================
RCS file: /cvsroot/classpath/classpath/vm/reference/java/nio/VMDirectByteBuffer.java,v
retrieving revision 1.2
diff -u -b -B -r1.2 VMDirectByteBuffer.java
--- vm/reference/java/nio/VMDirectByteBuffer.java	2 Jul 2005 20:33:08 -0000	1.2
+++ vm/reference/java/nio/VMDirectByteBuffer.java	19 Jul 2005 06:33:27 -0000
@@ -61,6 +61,7 @@
   static native byte get(RawData address, int index);
   static native void get(RawData address, int index, byte[] dst, int offset, int length);
   static native void put(RawData address, int index, byte value);
+  static native void put(RawData address, int index, byte[] src, int offset, int length);
   static native RawData adjustAddress(RawData address, int offset);
   static native void shiftDown(RawData address, int dst_offset, int src_offset, int count);
 }
