Return-Path: Delivered-To: apmail-harmony-commits-archive@www.apache.org Received: (qmail 85249 invoked from network); 21 Apr 2010 11:15:35 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 21 Apr 2010 11:15:35 -0000 Received: (qmail 76051 invoked by uid 500); 21 Apr 2010 11:15:35 -0000 Delivered-To: apmail-harmony-commits-archive@harmony.apache.org Received: (qmail 75394 invoked by uid 500); 21 Apr 2010 11:15:33 -0000 Mailing-List: contact commits-help@harmony.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@harmony.apache.org Delivered-To: mailing list commits@harmony.apache.org Received: (qmail 75386 invoked by uid 99); 21 Apr 2010 11:15:32 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 21 Apr 2010 11:15:32 +0000 X-ASF-Spam-Status: No, hits=-1651.0 required=10.0 tests=ALL_TRUSTED,AWL X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 21 Apr 2010 11:15:30 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 9761723889D2; Wed, 21 Apr 2010 11:14:47 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit 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 -0000 To: commits@harmony.apache.org From: hindessm@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20100421111447.9761723889D2@eris.apache.org> 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 #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(iGetIntArrayElements(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 {