harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hinde...@apache.org
Subject svn commit: r936256 - in /harmony/enhanced/java/trunk/classlib/modules: luni/src/main/java/org/apache/harmony/luni/platform/ luni/src/main/native/luni/shared/ luni/src/main/native/luni/unix/ luni/src/main/native/luni/windows/ nio/src/main/java/common/o...
Date Wed, 21 Apr 2010 11:14:47 GMT
Author: hindessm
Date: Wed Apr 21 11:14:46 2010
New Revision: 936256

URL: http://svn.apache.org/viewvc?rev=936256&view=rev
Log:
Refactor the FileChannelImpl.write to be more like the SocketChannelImpl
version.  In particular, pass objects to the native code rather than
addresses since otherwise aggressive optimazations may GC them (as there
are no more references to them) while we are still using the addresses.

Modified:
    harmony/enhanced/java/trunk/classlib/modules/luni/src/main/java/org/apache/harmony/luni/platform/IFileSystem.java
    harmony/enhanced/java/trunk/classlib/modules/luni/src/main/java/org/apache/harmony/luni/platform/OSFileSystem.java
    harmony/enhanced/java/trunk/classlib/modules/luni/src/main/native/luni/shared/OSFileSystem.c
    harmony/enhanced/java/trunk/classlib/modules/luni/src/main/native/luni/unix/OSFileSystemLinux32.c
    harmony/enhanced/java/trunk/classlib/modules/luni/src/main/native/luni/unix/OSNetworkSystemLinux.c
    harmony/enhanced/java/trunk/classlib/modules/luni/src/main/native/luni/unix/exports.txt
    harmony/enhanced/java/trunk/classlib/modules/luni/src/main/native/luni/windows/OSFileSystemWin32.c
    harmony/enhanced/java/trunk/classlib/modules/nio/src/main/java/common/org/apache/harmony/nio/internal/FileChannelImpl.java

Modified: harmony/enhanced/java/trunk/classlib/modules/luni/src/main/java/org/apache/harmony/luni/platform/IFileSystem.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/trunk/classlib/modules/luni/src/main/java/org/apache/harmony/luni/platform/IFileSystem.java?rev=936256&r1=936255&r2=936256&view=diff
==============================================================================
--- harmony/enhanced/java/trunk/classlib/modules/luni/src/main/java/org/apache/harmony/luni/platform/IFileSystem.java
(original)
+++ harmony/enhanced/java/trunk/classlib/modules/luni/src/main/java/org/apache/harmony/luni/platform/IFileSystem.java
Wed Apr 21 11:14:46 2010
@@ -66,7 +66,7 @@ public interface IFileSystem {
     public long readv(long fileDescriptor, long[] addresses, int[] offsets,
             int[] lengths, int size) throws IOException;
 
-    public long writev(long fileDescriptor, long[] addresses, int[] offsets,
+    public long writev(long fileDescriptor, Object[] buffers, int[] offsets,
             int[] lengths, int size) throws IOException;
 
     // Required to support direct byte buffers

Modified: harmony/enhanced/java/trunk/classlib/modules/luni/src/main/java/org/apache/harmony/luni/platform/OSFileSystem.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/trunk/classlib/modules/luni/src/main/java/org/apache/harmony/luni/platform/OSFileSystem.java?rev=936256&r1=936255&r2=936256&view=diff
==============================================================================
--- harmony/enhanced/java/trunk/classlib/modules/luni/src/main/java/org/apache/harmony/luni/platform/OSFileSystem.java
(original)
+++ harmony/enhanced/java/trunk/classlib/modules/luni/src/main/java/org/apache/harmony/luni/platform/OSFileSystem.java
Wed Apr 21 11:14:46 2010
@@ -28,6 +28,10 @@ import java.io.UnsupportedEncodingExcept
  */
 class OSFileSystem implements IFileSystem {
 
+    static {
+        oneTimeInitializationImpl();
+    }
+
     private static final OSFileSystem singleton = new OSFileSystem();
 
     public static OSFileSystem getOSFileSystem() {
@@ -38,6 +42,8 @@ class OSFileSystem implements IFileSyste
         super();
     }
 
+    private native static void oneTimeInitializationImpl();
+
     private final void validateLockArgs(int type, long start, long length) {
         if ((type != IFileSystem.SHARED_LOCK_TYPE)
                 && (type != IFileSystem.EXCLUSIVE_LOCK_TYPE)) {
@@ -194,18 +200,8 @@ class OSFileSystem implements IFileSyste
     private native long readvImpl(long fileDescriptor, long[] addresses,
             int[] offsets, int[] lengths, int size);
 
-    public long writev(long fileDescriptor, long[] addresses, int[] offsets,
-            int[] lengths, int size) throws IOException {
-        long bytesWritten = writevImpl(fileDescriptor, addresses, offsets,
-                lengths, size);
-        if (bytesWritten < 0) {
-            throw new IOException();
-        }
-        return bytesWritten;
-    }
-
-    private native long writevImpl(long fileDescriptor, long[] addresses,
-            int[] offsets, int[] lengths, int size);
+    public native long writev(long fileDescriptor, Object[] buffers,
+            int[] offsets, int[] lengths, int size) throws IOException;
 
     private native int closeImpl(long fileDescriptor);
 

Modified: harmony/enhanced/java/trunk/classlib/modules/luni/src/main/native/luni/shared/OSFileSystem.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/trunk/classlib/modules/luni/src/main/native/luni/shared/OSFileSystem.c?rev=936256&r1=936255&r2=936256&view=diff
==============================================================================
--- harmony/enhanced/java/trunk/classlib/modules/luni/src/main/native/luni/shared/OSFileSystem.c
(original)
+++ harmony/enhanced/java/trunk/classlib/modules/luni/src/main/native/luni/shared/OSFileSystem.c
Wed Apr 21 11:14:46 2010
@@ -23,11 +23,37 @@
 #include "iohelp.h"
 #include "exceptions.h"
 #include "nethelp.h"
+#include "harmonyglob.h"
 #include "OSFileSystem.h"
 #include "IFileSystem.h"
 
 /*
  * Class:     org_apache_harmony_luni_platform_OSFileSystem
+ * Method:    oneTimeInitializationImpl
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_org_apache_harmony_luni_platform_OSFileSystem_oneTimeInitializationImpl
+  (JNIEnv * env, jclass clazz)
+{
+  jclass lookupClass;
+  jobject globalRef;
+
+  if (HARMONY_CACHE_GET (env, CLS_java_nio_DirectByteBuffer)) {
+    /* Cache is already initialized */
+    return;
+  }
+  lookupClass = (*env)->FindClass (env, "java/nio/DirectByteBuffer");
+  if (!lookupClass)
+    return;
+  globalRef = (*env)->NewGlobalRef (env, lookupClass);
+  if (!globalRef)
+    return;
+  HARMONY_CACHE_SET (env, CLS_java_nio_DirectByteBuffer, globalRef);
+}
+
+/*
+ * Class:     org_apache_harmony_luni_platform_OSFileSystem
  * Method:    readDirectImpl
  * Signature: (JJI)J
  */

Modified: harmony/enhanced/java/trunk/classlib/modules/luni/src/main/native/luni/unix/OSFileSystemLinux32.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/trunk/classlib/modules/luni/src/main/native/luni/unix/OSFileSystemLinux32.c?rev=936256&r1=936255&r2=936256&view=diff
==============================================================================
--- harmony/enhanced/java/trunk/classlib/modules/luni/src/main/native/luni/unix/OSFileSystemLinux32.c
(original)
+++ harmony/enhanced/java/trunk/classlib/modules/luni/src/main/native/luni/unix/OSFileSystemLinux32.c
Wed Apr 21 11:14:46 2010
@@ -32,7 +32,9 @@
 #include "vmi.h"
 #include "iohelp.h"
 #include "nethelp.h"
+#include "harmonyglob.h"
 #include "hysock.h"
+#include "exceptions.h"
 
 #include "IFileSystem.h"
 #include "OSFileSystem.h"
@@ -190,44 +192,101 @@ JNIEXPORT jlong JNICALL Java_org_apache_
 
 /*
  * Class:     org_apache_harmony_luni_platform_OSFileSystem
- * Method:    writevImpl
+ * Method:    writev
  * Signature: (J[J[I[I)J
  */
-JNIEXPORT jlong JNICALL Java_org_apache_harmony_luni_platform_OSFileSystem_writevImpl
-  (JNIEnv *env, jobject thiz, jlong fd, jlongArray jbuffers, jintArray joffsets, jintArray
jlengths, jint size){
+JNIEXPORT jlong JNICALL
+Java_org_apache_harmony_luni_platform_OSFileSystem_writev
+  (JNIEnv *env, jobject thiz, jlong fd, jobjectArray buffers, jintArray offset, jintArray
counts, jint length){
   PORT_ACCESS_FROM_ENV (env);
-  jboolean bufsCopied = JNI_FALSE;
-  jboolean offsetsCopied = JNI_FALSE;
-  jboolean lengthsCopied = JNI_FALSE;
-  jlong *bufs;
-  jint *offsets;
-  jint *lengths;
-  int i = 0;
-  long totalWritten = 0;
-  struct iovec *vectors = (struct iovec *)hymem_allocate_memory(size * sizeof(struct iovec));
-  if(vectors == NULL){
-    return -1;
-  }
-  bufs = (*env)->GetLongArrayElements(env, jbuffers, &bufsCopied);
-  offsets = (*env)->GetIntArrayElements(env, joffsets, &offsetsCopied);
-  lengths = (*env)->GetIntArrayElements(env, jlengths, &lengthsCopied);
-  while(i < size){
-    vectors[i].iov_base = (void *)((IDATA)(bufs[i]+offsets[i]));
-    vectors[i].iov_len = lengths[i];
-    i++;
+  jobject buffer;
+  jobject* toBeReleasedBuffers;
+  jint *noffset;
+  jboolean isDirectBuffer = JNI_FALSE;
+  jint result = 0;
+  jclass byteBufferClass;
+  struct iovec* vect;
+  int i;
+
+  vect = (struct iovec*) hymem_allocate_memory(sizeof(struct iovec) * length);
+  if (vect == NULL) {
+    throwNewOutOfMemoryError(env, "");
+    return 0;
+  }
+
+  toBeReleasedBuffers =
+    (jobject*) hymem_allocate_memory(sizeof(jobject) * length);
+  if (toBeReleasedBuffers == NULL) {
+    throwNewOutOfMemoryError(env, "");
+    goto free_resources;
+  }
+  memset(toBeReleasedBuffers, 0, sizeof(jobject)*length);
+
+  byteBufferClass = HARMONY_CACHE_GET (env, CLS_java_nio_DirectByteBuffer);
+  noffset = (*env)->GetIntArrayElements(env, offset, NULL);
+  if (noffset == NULL) {
+    throwNewOutOfMemoryError(env, "");
+    goto free_resources;
+  }
+
+  for (i = 0; i < length; ++i) {
+    jint *cts;
+    U_8* base;
+    buffer = (*env)->GetObjectArrayElement(env, buffers, i);
+    isDirectBuffer = (*env)->IsInstanceOf(env, buffer, byteBufferClass);
+    if (isDirectBuffer) {
+      base =
+        (U_8 *)(jbyte *)(IDATA) (*env)->GetDirectBufferAddress(env, buffer);
+      if (base == NULL) {
+        throwNewOutOfMemoryError(env, "");
+        goto free_resources;
+      }
+      toBeReleasedBuffers[i] = NULL;
+    } else {
+      base =
+        (U_8 *)(jbyte *)(IDATA) (*env)->GetByteArrayElements(env, buffer, NULL);
+      if (base == NULL) {
+        throwNewOutOfMemoryError(env, "");
+        goto free_resources;
+      }
+      toBeReleasedBuffers[i] = buffer;
+    }
+    vect[i].iov_base = base + noffset[i];
+
+    cts = (*env)->GetPrimitiveArrayCritical(env, counts, NULL);
+    vect[i].iov_len = cts[i];
+    (*env)->ReleasePrimitiveArrayCritical(env, counts, cts, JNI_ABORT);
   }
-  totalWritten = writev(fd - FD_BIAS, vectors, size);
-  if(bufsCopied){
-    (*env)->ReleaseLongArrayElements(env, jbuffers, bufs, JNI_ABORT);
+
+  result = writev(fd - FD_BIAS, vect, length);
+
+  if (0 > result) {
+    if (errno != EAGAIN) {
+      throwJavaIoIOException(env, "");
+    }
+    result = 0;
   }
-  if(offsetsCopied){
-    (*env)->ReleaseIntArrayElements(env, joffsets, offsets, JNI_ABORT);
+
+ free_resources:
+  
+  if (toBeReleasedBuffers != NULL) {
+    for (i = 0; i < length; ++i) {
+      if (toBeReleasedBuffers[i] != NULL) {
+        (*env)->ReleaseByteArrayElements(env, toBeReleasedBuffers[i],
+                                         vect[i].iov_base - noffset[i],
+                                         JNI_ABORT);
+      }
+    }
   }
-  if(lengthsCopied){
-    (*env)->ReleaseIntArrayElements(env, jlengths, lengths, JNI_ABORT);
+
+  if (noffset != NULL) {
+    (*env)->ReleaseIntArrayElements(env, offset, noffset, JNI_ABORT);
   }
-  hymem_free_memory(vectors);
-  return totalWritten;
+
+  hymem_free_memory(toBeReleasedBuffers);
+  hymem_free_memory(vect);
+
+  return (jint) result;
 }
 
 /*

Modified: harmony/enhanced/java/trunk/classlib/modules/luni/src/main/native/luni/unix/OSNetworkSystemLinux.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/trunk/classlib/modules/luni/src/main/native/luni/unix/OSNetworkSystemLinux.c?rev=936256&r1=936255&r2=936256&view=diff
==============================================================================
--- harmony/enhanced/java/trunk/classlib/modules/luni/src/main/native/luni/unix/OSNetworkSystemLinux.c
(original)
+++ harmony/enhanced/java/trunk/classlib/modules/luni/src/main/native/luni/unix/OSNetworkSystemLinux.c
Wed Apr 21 11:14:46 2010
@@ -803,6 +803,7 @@ Java_org_apache_harmony_luni_platform_OS
   result = writev(SOCKET_CAST (socketP), vect, length);
 
   if (0 > result) {
+    /* TOFIX? man write(2) on linux implies we should check EWOULDBLOCK too */
     if (errno != EAGAIN) {
       throwJavaNetSocketException(env, result);
     }

Modified: harmony/enhanced/java/trunk/classlib/modules/luni/src/main/native/luni/unix/exports.txt
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/trunk/classlib/modules/luni/src/main/native/luni/unix/exports.txt?rev=936256&r1=936255&r2=936256&view=diff
==============================================================================
--- harmony/enhanced/java/trunk/classlib/modules/luni/src/main/native/luni/unix/exports.txt
(original)
+++ harmony/enhanced/java/trunk/classlib/modules/luni/src/main/native/luni/unix/exports.txt
Wed Apr 21 11:14:46 2010
@@ -120,9 +120,10 @@ JNI_OnUnload
 Java_org_apache_harmony_luni_util_FloatingPointParser_parseDblImpl
 Java_org_apache_harmony_luni_util_FloatingPointParser_parseFltImpl
 Java_org_apache_harmony_luni_util_NumberConverter_bigIntDigitGeneratorInstImpl
+Java_org_apache_harmony_luni_platform_OSFileSystem_oneTimeInitializationImpl
 Java_org_apache_harmony_luni_platform_OSFileSystem_truncateImpl
 Java_org_apache_harmony_luni_platform_OSFileSystem_getAllocGranularity
-Java_org_apache_harmony_luni_platform_OSFileSystem_writevImpl
+Java_org_apache_harmony_luni_platform_OSFileSystem_writev
 Java_org_apache_harmony_luni_platform_OSFileSystem_readvImpl
 Java_org_apache_harmony_luni_platform_OSFileSystem_writeImpl
 Java_org_apache_harmony_luni_platform_OSFileSystem_openImpl

Modified: harmony/enhanced/java/trunk/classlib/modules/luni/src/main/native/luni/windows/OSFileSystemWin32.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/trunk/classlib/modules/luni/src/main/native/luni/windows/OSFileSystemWin32.c?rev=936256&r1=936255&r2=936256&view=diff
==============================================================================
--- harmony/enhanced/java/trunk/classlib/modules/luni/src/main/native/luni/windows/OSFileSystemWin32.c
(original)
+++ harmony/enhanced/java/trunk/classlib/modules/luni/src/main/native/luni/windows/OSFileSystemWin32.c
Wed Apr 21 11:14:46 2010
@@ -27,6 +27,7 @@
 #include <stdio.h>
 #include "IFileSystem.h"
 #include "OSFileSystem.h"
+#include "harmonyglob.h"
 
 /**
  * Lock the file identified by the given handle.
@@ -173,19 +174,62 @@ JNIEXPORT jlong JNICALL Java_org_apache_
  * Method:    writevImpl
  * Signature: (J[J[I[I)J
  */
-JNIEXPORT jlong JNICALL Java_org_apache_harmony_luni_platform_OSFileSystem_writevImpl
-  (JNIEnv *env, jobject thiz, jlong fd, jlongArray jbuffers, jintArray joffsets, jintArray
jlengths, jint size){
+JNIEXPORT jlong JNICALL
+Java_org_apache_harmony_luni_platform_OSFileSystem_writev
+  (JNIEnv *env, jobject thiz, jlong fd, jobjectArray buffers, jintArray offset, jintArray
counts, jint length){
   PORT_ACCESS_FROM_ENV (env);
-  jboolean bufsCopied = JNI_FALSE;
-  jboolean offsetsCopied = JNI_FALSE;
-  jboolean lengthsCopied = JNI_FALSE;
-  jlong *bufs = (*env)->GetLongArrayElements(env, jbuffers, &bufsCopied);
-  jint *offsets = (*env)->GetIntArrayElements(env, joffsets, &offsetsCopied);
-  jint *lengths = (*env)->GetIntArrayElements(env, jlengths, &lengthsCopied);
-  long totalWritten = 0;  
-  int i = 0;
-  while(i<size){
-    long bytesWritten = hyfile_write ((IDATA) fd, (void *) (*(bufs+i)+*(offsets+i)), (IDATA)
*(lengths+i));
+  jint *noffset = NULL;
+  jint *lengths = NULL;
+  jboolean isDirectBuffer = JNI_FALSE;
+  long totalWritten = 0;
+  int i;
+  jclass byteBufferClass;
+
+  byteBufferClass = HARMONY_CACHE_GET (env, CLS_java_nio_DirectByteBuffer);
+
+  noffset = (*env)->GetIntArrayElements(env, offset, NULL);
+  if (noffset == NULL) {
+    throwNewOutOfMemoryError(env, "");
+    goto free_resources;
+  }
+
+  lengths = (*env)->GetIntArrayElements(env, counts, NULL);
+  if (lengths == NULL) {
+    throwNewOutOfMemoryError(env, "");
+    goto free_resources;
+  }
+
+  for (i = 0; i < length; ++i) {
+    long bytesWritten;
+    jobject toRelease = NULL;
+    U_8* buf;
+    jobject buffer = (*env)->GetObjectArrayElement(env, buffers, i);
+    isDirectBuffer = (*env)->IsInstanceOf(env, buffer, byteBufferClass);
+    if (isDirectBuffer) {
+      buf =
+        (U_8 *)(jbyte *)(IDATA) (*env)->GetDirectBufferAddress(env, buffer);
+      if (buf == NULL) {
+        throwNewOutOfMemoryError(env, "Failed to get direct buffer address");
+        goto free_resources;
+      }
+      toRelease = NULL;
+    } else {
+      buf =
+        (U_8 *)(jbyte *)(IDATA) (*env)->GetByteArrayElements(env, buffer, NULL);
+      if (buf == NULL) {
+        throwNewOutOfMemoryError(env, "");
+        goto free_resources;
+      }
+      toRelease = buffer;
+    }
+          
+    bytesWritten =
+      hyfile_write ((IDATA) fd,
+                    (void *) (buf + noffset[i]), (IDATA) lengths[i]);
+    if (toRelease != NULL) {
+      (*env)->ReleaseByteArrayElements(env, toRelease, buf, JNI_ABORT);
+    }
+
     if(bytesWritten == -1 && hyerror_last_error_number() == HYPORT_ERROR_FILE_LOCKED){
         throwNewExceptionByName(env, "java/io/IOException", netLookupErrorString(env, HYPORT_ERROR_FILE_LOCKED));
 	break;
@@ -195,17 +239,19 @@ JNIEXPORT jlong JNICALL Java_org_apache_
         break;
     }
     totalWritten += bytesWritten;
-    i++;
+   
   }
-  if(bufsCopied){
-    (*env)->ReleaseLongArrayElements(env, jbuffers, bufs, JNI_ABORT);
-  }
-  if(offsetsCopied){
-    (*env)->ReleaseIntArrayElements(env, joffsets, offsets, JNI_ABORT);
+
+ free_resources:
+
+  if (noffset != NULL) {
+    (*env)->ReleaseIntArrayElements(env, offset, noffset, JNI_ABORT);
   }
-  if(lengthsCopied){
-    (*env)->ReleaseIntArrayElements(env, jlengths, lengths, JNI_ABORT);
+
+  if (lengths != NULL) {
+    (*env)->ReleaseIntArrayElements(env, counts, lengths, JNI_ABORT);
   }
+
   return totalWritten;
 }
 

Modified: harmony/enhanced/java/trunk/classlib/modules/nio/src/main/java/common/org/apache/harmony/nio/internal/FileChannelImpl.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/trunk/classlib/modules/nio/src/main/java/common/org/apache/harmony/nio/internal/FileChannelImpl.java?rev=936256&r1=936255&r2=936256&view=diff
==============================================================================
--- harmony/enhanced/java/trunk/classlib/modules/nio/src/main/java/common/org/apache/harmony/nio/internal/FileChannelImpl.java
(original)
+++ harmony/enhanced/java/trunk/classlib/modules/nio/src/main/java/common/org/apache/harmony/nio/internal/FileChannelImpl.java
Wed Apr 21 11:14:46 2010
@@ -577,25 +577,25 @@ public abstract class FileChannelImpl ex
         if (0 == count) {
             return 0;
         }
-        long[] handles = new long[length];
+        Object[] src = new Object[length];
         int[] offsets = new int[length];
         int[] lengths = new int[length];
-        ByteBuffer[] bufferRefs = new ByteBuffer[length];
         for (int i = 0; i < length; i++) {
             ByteBuffer buffer = buffers[i + offset];
             if (!buffer.isDirect()) {
                 ByteBuffer directBuffer = ByteBuffer.allocateDirect(buffer
                         .remaining());
+                int oldPosition = buffer.position();
                 directBuffer.put(buffer);
+                buffer.position(oldPosition);
                 directBuffer.flip();
-                buffer = directBuffer;
+                src[i] = directBuffer;
                 offsets[i] = 0;
             } else {
+                src[i] = buffer;
                 offsets[i] = buffer.position();
             }
-            handles[i] = ((DirectBuffer) buffer).getEffectiveAddress().toLong();
             lengths[i] = buffer.remaining();
-            bufferRefs[i] = buffer;
         }
 
         long bytesWritten = 0;
@@ -603,7 +603,7 @@ public abstract class FileChannelImpl ex
         synchronized (repositioningLock) {
             try {
                 begin();
-                bytesWritten = fileSystem.writev(handle, handles, offsets,
+                bytesWritten = fileSystem.writev(handle, src, offsets,
                         lengths, length);
                 completed = true;
             } finally {



Mime
View raw message