Author: mturk Date: Wed Apr 22 12:02:02 2009 New Revision: 767476 URL: http://svn.apache.org/viewvc?rev=767476&view=rev Log: Support DirectByteBuffers from Pointer. Some DirectByteBuffer methods could be removed
Modified: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/DirectByteBuffer.java commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Memory.java commons/sandbox/runtime/trunk/src/main/native/shared/dbb.c commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestDirectByteBuffer.java Modified: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/DirectByteBuffer.java URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/DirectByteBuffer.java?rev=767476&r1=767475&r2=767476&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/DirectByteBuffer.java (original) +++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/DirectByteBuffer.java Wed Apr 22 12:02:02 2009 @@ -39,25 +39,32 @@ // No class instance } - private static native ByteBuffer alloc0(int size) + private static native ByteBuffer alloc0(long size) throws OutOfMemoryError, IllegalArgumentException; - private static native ByteBuffer alloc1(int size) + private static native ByteBuffer alloc1(long size) throws OutOfMemoryError, IllegalArgumentException; - private static native ByteBuffer[] alloc2(int[] sizes, int off, int len) + private static native ByteBuffer[] alloc2(long[] sizes, long off, int len) throws OutOfMemoryError, IllegalArgumentException, IndexOutOfBoundsException; - private static native ByteBuffer[] alloc3(int[] sizes, int off, int len) + private static native ByteBuffer[] alloc3(long[] sizes, long off, int len) throws OutOfMemoryError, IllegalArgumentException, IndexOutOfBoundsException; - private static native ByteBuffer attach(long mem, int offset, int size) + private static native ByteBuffer alloc4(Pointer ptr, long off, long len) + throws NullPointerException, IllegalArgumentException, + IndexOutOfBoundsException; + + private static native ByteBuffer alloc5(Pointer ptr) + throws NullPointerException; + + private static native ByteBuffer attach(long mem, long offset, long size) throws NullPointerException, IllegalArgumentException; - private static native void copy0(ByteBuffer src, int srcPos, ByteBuffer dst, - int dstPos, int count) + private static native void copy0(ByteBuffer src, long srcPos, ByteBuffer dst, + long dstPos, int count) throws NullPointerException, IllegalArgumentException, IndexOutOfBoundsException; @@ -69,7 +76,7 @@ * @throws OutOfMemoryError if memory cannot be allocated from the system. * @throws IllegalArgumentException if {...@code size} is invalid. */ - public static ByteBuffer allocate(int size) + public static ByteBuffer allocate(long size) throws OutOfMemoryError, IllegalArgumentException { return alloc0(size); @@ -84,7 +91,7 @@ * @throws OutOfMemoryError if memory cannot be allocated from the system. * @throws IllegalArgumentException if {...@code size} is invalid. */ - public static ByteBuffer allocateAndClear(int size) + public static ByteBuffer allocateAndClear(long size) throws OutOfMemoryError, IllegalArgumentException { return alloc1(size); @@ -122,7 +129,7 @@ * @throws IndexOutOfBoundsException if copying would cause access of * data outside array bounds. */ - public static ByteBuffer[] allocate(int sizes[], int off, int len) + public static ByteBuffer[] allocate(long sizes[], long off, int len) throws NullPointerException, IllegalArgumentException, IndexOutOfBoundsException { @@ -153,7 +160,7 @@ * @throws IllegalArgumentException if {...@code off} or {...@code len} * is invalid. */ - public static ByteBuffer[] allocate(int sizes[]) + public static ByteBuffer[] allocate(long sizes[]) throws NullPointerException, IllegalArgumentException { return alloc2(sizes, 0, sizes.length); @@ -180,7 +187,7 @@ * @throws IndexOutOfBoundsException if copying would cause access of * data outside array bounds. */ - public static ByteBuffer[] allocateAndClear(int sizes[], int off, int len) + public static ByteBuffer[] allocateAndClear(long sizes[], long off, int len) throws NullPointerException, IllegalArgumentException, IndexOutOfBoundsException { @@ -212,10 +219,10 @@ * @throws IllegalArgumentException if {...@code off} or {...@code len} * is invalid. */ - public static ByteBuffer[] allocateAndClear(int sizes[]) + public static ByteBuffer[] allocateAndClear(long sizes[]) throws NullPointerException, IllegalArgumentException { - return alloc3(sizes, 0, sizes.length); + return alloc3(sizes, 0L, sizes.length); } /** @@ -239,13 +246,60 @@ * @throws IllegalArgumentException if {...@code offset} or * {...@code size} are invalid. */ - public static ByteBuffer allocate(long mem, int offset, int size) + public static ByteBuffer allocate(long mem, long offset, long size) throws NullPointerException, IllegalArgumentException { return attach(mem, offset, size); } /** + * Allocate a new {...@code ByteBuffer} from {...@link Pointer} memory area. + * <p> + * <b>Warning:</b><br/> + * Allocated array elements share the same memory segment + * so the {...@code free()} must <b>not</b> be called on the retured + * {...@code ByteBuffer}, neither it can be used after the {...@code ptr} + * has been destroyed. + * </p> + * @param ptr Memory area to use. + * @return The {...@code ByteBuffer} backed by the {...@code ptr} memory area. + * + * @throws NullPointerException if {...@code ptr} is null. + */ + public static ByteBuffer allocate(Pointer ptr) + throws NullPointerException + { + return alloc5(ptr); + } + + /** + * Allocate a new {...@code ByteBuffer} from {...@link Pointer} memory area. + * <p> + * <b>Warning:</b><br/> + * Allocated array elements share the same memory segment + * so the {...@code free()} must <b>not</b> be called on the retured + * {...@code ByteBuffer}, neither it can be used after the {...@code ptr} + * has been destroyed. + * </p> + * @param ptr Memory area to use. + * @param off Start offset of the {...@code ptr} memory area. + * @param len The length of the {...@code ptr} memory areat to use. + * @return The {...@code ByteBuffer} backed by the {...@code ptr} memory area. + * + * @throws NullPointerException if {...@code ptr} is null. + * @throws IllegalArgumentException if {...@code off} or {...@code len} + * is invalid. + * @throws IndexOutOfBoundsException if copying would cause access of + * data outside array bounds. + */ + public static ByteBuffer allocate(Pointer ptr, long off, long len) + throws NullPointerException, IllegalArgumentException, + IndexOutOfBoundsException + { + return alloc4(ptr, off, len); + } + + /** * Allocate a new ByteBuffer from already allocated ByteBuffer. * @param buf The ByteBuffer who's memory to use * @param offset Offset from the memory to use @@ -256,7 +310,7 @@ * @throws IllegalArgumentException if {...@code offset} or * {...@code size} are invalid. */ - public static ByteBuffer allocate(ByteBuffer buf, int offset, int size) + public static ByteBuffer allocate(ByteBuffer buf, long offset, long size) throws NullPointerException, IllegalArgumentException { return attach(address(buf), offset, size); @@ -340,8 +394,8 @@ * @throws IndexOutOfBoundsException if copying would cause access of * data outside ByteBuffer bounds. */ - public static void copy(ByteBuffer src, int srcPos, ByteBuffer dst, - int dstPos, int length) + public static void copy(ByteBuffer src, long srcPos, ByteBuffer dst, + long dstPos, int length) throws NullPointerException, IllegalArgumentException, IndexOutOfBoundsException { Modified: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Memory.java URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Memory.java?rev=767476&r1=767475&r2=767476&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Memory.java (original) +++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/Memory.java Wed Apr 22 12:02:02 2009 @@ -192,7 +192,7 @@ * @param ptr {...@code Pointer} whose content to use. * @param offset starting position in the memory. * @param length the number of bytes use. - * @return new {...@link byte} array with values from {...@code src} memory area. + * @return new {...@code byte} array with values from {...@code src} memory area. * * @throws IllegalArgumentException if the {...@code offset} * is {...@code negative} or {...@code length} Modified: commons/sandbox/runtime/trunk/src/main/native/shared/dbb.c URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/shared/dbb.c?rev=767476&r1=767475&r2=767476&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/shared/dbb.c (original) +++ commons/sandbox/runtime/trunk/src/main/native/shared/dbb.c Wed Apr 22 12:02:02 2009 @@ -23,12 +23,13 @@ #include "acr_private.h" #include "acr_error.h" #include "acr_clazz.h" +#include "acr_pointer.h" /** * DirectByteBuffer utilities */ ACR_JNI_EXPORT_DECLARE(jobject, DirectByteBuffer, alloc0)(ACR_JNISTDARGS, - jint size) + jlong size) { void *mem; size_t sz = (size_t)ACR_ALIGN_DEFAULT(size); @@ -54,7 +55,7 @@ } ACR_JNI_EXPORT_DECLARE(jobject, DirectByteBuffer, alloc1)(ACR_JNISTDARGS, - jint size) + jlong size) { size_t sz = (size_t)ACR_ALIGN_DEFAULT((size)); void *mem; @@ -80,11 +81,11 @@ } ACR_JNI_EXPORT_DECLARE(jobject, DirectByteBuffer, alloc2)(ACR_JNISTDARGS, - jintArray sizes, - jint off, jint len) + jlongArray sizes, + jlong off, jint len) { jint i; - jint *ia; + jlong *ia; jsize is; size_t sz = 0; void *mem; @@ -109,7 +110,7 @@ return NULL; } - if (!(ia = (*_E)->GetIntArrayElements(_E, sizes, NULL))) { + if (!(ia = (*_E)->GetLongArrayElements(_E, sizes, NULL))) { ACR_ThrowException(_E, THROW_FMARK, ACR_EX_EINVAL, ACR_EISNULL); return NULL; @@ -127,7 +128,7 @@ for (i = 0; i < len; i++) { size_t n = ACR_ALIGN_DEFAULT(ia[i + off]); jobject bb = (*_E)->NewDirectByteBuffer(_E, (char *)mem + offset, - (jlong)ia[i + off]); + ia[i + off]); if (bb == NULL) { /* One of the constructors failed. * The entire ByteBuffer[] array is invalid. @@ -156,16 +157,16 @@ } cleanup: - (*_E)->ReleaseIntArrayElements(_E, sizes, ia, JNI_ABORT); + (*_E)->ReleaseLongArrayElements(_E, sizes, ia, JNI_ABORT); return rv; } ACR_JNI_EXPORT_DECLARE(jobject, DirectByteBuffer, alloc3)(ACR_JNISTDARGS, - jintArray sizes, - jint off, jint len) + jlongArray sizes, + jlong off, jint len) { jint i; - jint *ia; + jlong *ia; jsize is; size_t sz = 0; void *mem; @@ -190,7 +191,7 @@ return NULL; } - if (!(ia = (*_E)->GetIntArrayElements(_E, sizes, NULL))) { + if (!(ia = (*_E)->GetLongArrayElements(_E, sizes, NULL))) { ACR_ThrowException(_E, THROW_FMARK, ACR_EX_EINVAL, ACR_EISNULL); return NULL; @@ -208,7 +209,7 @@ for (i = 0; i < len; i++) { size_t n = ACR_ALIGN_DEFAULT(ia[i + off]); jobject bb = (*_E)->NewDirectByteBuffer(_E, (char *)mem + offset, - (jlong)ia[i + off]); + ia[i + off]); if (bb == NULL) { /* One of the constructors failed. * The entire ByteBuffer[] array is invalid. @@ -237,14 +238,56 @@ } cleanup: - (*_E)->ReleaseIntArrayElements(_E, sizes, ia, JNI_ABORT); + (*_E)->ReleaseLongArrayElements(_E, sizes, ia, JNI_ABORT); return rv; } +ACR_JNI_EXPORT_DECLARE(jobject, DirectByteBuffer, alloc4)(ACR_JNISTDARGS, + jobject src, jlong off, + jlong siz) +{ + size_t so = (size_t)off; + size_t ss = (size_t)siz; + size_t sl; + char *sp = (char *)ACR_PointerGet(_E, src, &sl); + + UNREFERENCED_O; + + if (!sp) { + ACR_ThrowException(_E, THROW_NMARK, ACR_EX_ENULL, 0); + return NULL; + } + if (off < 0L || siz < 1L) { + ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EINVAL, 0); + return NULL; + } + if ((so + ss) > sl) { + ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EINDEX, 0); + return NULL; + } + + return (*_E)->NewDirectByteBuffer(_E, sp + so, ss); +} + +ACR_JNI_EXPORT_DECLARE(jobject, DirectByteBuffer, alloc5)(ACR_JNISTDARGS, + jobject src) +{ + size_t sl; + void *sp = ACR_PointerGet(_E, src, &sl); + + UNREFERENCED_O; + + if (!sp) { + ACR_ThrowException(_E, THROW_NMARK, ACR_EX_ENULL, 0); + return NULL; + } + return (*_E)->NewDirectByteBuffer(_E, sp, sl); +} + ACR_JNI_EXPORT_DECLARE(jobject, DirectByteBuffer, attach)(ACR_JNISTDARGS, jlong addr, - jint offset, - jint size) + jlong offset, + jlong size) { char *mem = J2P(addr, char *); @@ -265,7 +308,7 @@ ACR_EINVALSIZ); return NULL; } - return (*_E)->NewDirectByteBuffer(_E, mem + (size_t)offset, (jlong)size); + return (*_E)->NewDirectByteBuffer(_E, mem + (size_t)offset, size); } ACR_JNI_EXPORT_DECLARE(void, DirectByteBuffer, free)(ACR_JNISTDARGS, jobject bb) @@ -339,9 +382,9 @@ ACR_JNI_EXPORT_DECLARE(void, DirectByteBuffer, copy0)(ACR_JNISTDARGS, jobject srcb, - jint srco, + jlong srco, jobject dstb, - jint dsto, + jlong dsto, jint count) { void *d; @@ -362,19 +405,19 @@ ACR_EINVALSIZ); return; } - if ((jlong)(count + srco) > ss) { + if ((count + srco) > ss) { ACR_ThrowException(_E, THROW_FMARK, ACR_EX_EINDEX, ACR_ERANGE); return; } - if ((jlong)(count + dsto) > ds) { + if ((count + dsto) > ds) { ACR_ThrowException(_E, THROW_FMARK, ACR_EX_EINDEX, ACR_ERANGE); return; } if ((s = (*_E)->GetDirectBufferAddress(_E, srcb))) { if ((d = (*_E)->GetDirectBufferAddress(_E, dstb))) { - memcpy((char *)d + dsto, (char *)s + srco, (size_t)count); + memcpy((char *)d + (size_t)dsto, (char *)s + (size_t)srco, (size_t)count); } else { ACR_ThrowException(_E, THROW_FMARK, ACR_EX_ENULL, Modified: commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestDirectByteBuffer.java URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestDirectByteBuffer.java?rev=767476&r1=767475&r2=767476&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestDirectByteBuffer.java (original) +++ commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestDirectByteBuffer.java Wed Apr 22 12:02:02 2009 @@ -80,6 +80,53 @@ */ } + public void testPointer() + throws Exception + { + // ptr, bb1 and bb2 share the same memory + Pointer ptr = Memory.malloc(1000); + ByteBuffer bb = DirectByteBuffer.allocate(ptr); + assertTrue("Direct", bb.isDirect()); + assertEquals("Capacity", 1000, bb.capacity()); + assertEquals("Address", DirectByteBuffer.address(bb), ptr.address().longValue()); + /* + * Call to the free crashes the JVM ! + * Also call to the any operation on any + * Byte buffer will probably crash the JVM after the + * memory is free'd + * bb.putInt(0xcafebabe); might write to something else + * DirectByteBuffer.free(bb); will free already free'd memory + * causing core. + */ + } + + public void testPointerShare() + throws Exception + { + // ptr, bb1 and bb2 share the same memory + Pointer ptr = Memory.malloc(1000); + ByteBuffer bb1 = DirectByteBuffer.allocate(ptr, 0, 1000); + long a = DirectByteBuffer.address(bb1); + ByteBuffer bb2 = DirectByteBuffer.allocate(a, 0, 1000); + bb1.putInt(0xcafebabe); + assertTrue("Direct", bb2.isDirect()); + assertEquals("Capacity", 1000, bb2.capacity()); + assertEquals("Value", 0xcafebabe, bb2.getInt()); + assertEquals("Address", a, ptr.address().longValue()); + assertEquals("Address", DirectByteBuffer.address(bb2), ptr.address().longValue()); + /* + * Call to the free crashes the JVM ! + * Also call to the any operation on any + * Byte buffer will probably crash the JVM after the + * memory is free'd + * bb2.putInt(0xcafebabe); might write to something else + * DirectByteBuffer.free(bb1); will free already free'd memory + * causing core. + * DirectByteBuffer.free(bb2); will free already free'd memory + * causing core. + */ + } + public void testMemset() throws Exception { @@ -111,7 +158,7 @@ public void testArrayCreate() throws Exception { - int [] sizes = { 100, 10, 100, 1000 }; + long [] sizes = { 100, 10, 100, 1000 }; ByteBuffer[] a = DirectByteBuffer.allocate(sizes, 0, sizes.length); assertNotNull("Array", a); @@ -129,7 +176,7 @@ public void testArrayCreateIdx() throws Exception { - int [] sizes = { 100, 10, 100, 1000 }; + long [] sizes = { 100, 10, 100, 1000 }; ByteBuffer[] a = DirectByteBuffer.allocate(sizes, 2, 2); assertNotNull("Array", a); @@ -147,7 +194,7 @@ public void testArrayCreateAndClear() throws Exception { - int [] sizes = { 100, 10, 100 , 1000}; + long [] sizes = { 100, 10, 100 , 1000}; ByteBuffer[] a = DirectByteBuffer.allocateAndClear(sizes, 0, sizes.length); assertNotNull("Array", a);