diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/java/com/jogamp/common/nio/Buffers.java | 54 | ||||
-rw-r--r-- | src/junit/com/jogamp/common/nio/TestBuffers.java (renamed from src/junit/com/jogamp/common/nio/BuffersTest.java) | 10 | ||||
-rw-r--r-- | src/junit/com/jogamp/common/nio/TestByteBufferCopyStream.java | 11 | ||||
-rw-r--r-- | src/junit/com/jogamp/common/nio/TestCachedBufferFactory.java (renamed from src/junit/com/jogamp/common/nio/CachedBufferFactoryTest.java) | 6 |
4 files changed, 68 insertions, 13 deletions
diff --git a/src/java/com/jogamp/common/nio/Buffers.java b/src/java/com/jogamp/common/nio/Buffers.java index fb23627..5125ee8 100644 --- a/src/java/com/jogamp/common/nio/Buffers.java +++ b/src/java/com/jogamp/common/nio/Buffers.java @@ -39,6 +39,7 @@ */ package com.jogamp.common.nio; +import java.lang.reflect.Field; import java.lang.reflect.Method; import java.nio.Buffer; import java.nio.ByteBuffer; @@ -56,6 +57,7 @@ import com.jogamp.common.util.ReflectionUtil; import com.jogamp.common.util.ValueConv; import jogamp.common.Debug; +import jogamp.common.os.PlatformPropsImpl; /** * Utility methods allowing easy {@link java.nio.Buffer} manipulations. @@ -1165,22 +1167,42 @@ public class Buffers { * Access to NIO {@link sun.misc.Cleaner}, allowing caller to deterministically clean a given {@link sun.nio.ch.DirectBuffer}. */ public static class Cleaner { + private static final Object theUnsafe; private static final Method mbbCleaner; private static final Method cClean; private static final boolean hasCleaner; /** OK to be lazy on thread synchronization, just for early out **/ private static volatile boolean cleanerError; static { + final Object[] _theUnsafe = { null }; final Method[] _mbbCleaner = { null }; final Method[] _cClean = { null }; if( AccessController.doPrivileged(new PrivilegedAction<Boolean>() { @Override public Boolean run() { try { - _mbbCleaner[0] = ReflectionUtil.getMethod("sun.nio.ch.DirectBuffer", "cleaner", null, Buffers.class.getClassLoader()); - _mbbCleaner[0].setAccessible(true); - _cClean[0] = Class.forName("sun.misc.Cleaner").getMethod("clean"); - _cClean[0].setAccessible(true); + if(PlatformPropsImpl.JAVA_9) { + // Using: sun.misc.Unsafe { public void invokeCleaner(java.nio.ByteBuffer directBuffer); } + _mbbCleaner[0] = null; + final Class<?> unsafeClass = Class.forName("sun.misc.Unsafe"); + { + final Field f = unsafeClass.getDeclaredField("theUnsafe"); + f.setAccessible(true); + _theUnsafe[0] = f.get(null); + } + _cClean[0] = unsafeClass.getMethod("invokeCleaner", java.nio.ByteBuffer.class); + _cClean[0].setAccessible(true); + } else { + _mbbCleaner[0] = ReflectionUtil.getMethod("sun.nio.ch.DirectBuffer", "cleaner", null, Buffers.class.getClassLoader()); + _mbbCleaner[0].setAccessible(true); + final Class<?> cleanerType = _mbbCleaner[0].getReturnType(); + // Java >= 9: jdk.internal.ref.Cleaner (NOT accessible!) + // "Unable to make public void jdk.internal.ref.Cleaner.clean() accessible: + // module java.base does not "exports jdk.internal.ref" to unnamed module" + // Java <= 8: sun.misc.Cleaner OK + _cClean[0] = cleanerType.getMethod("clean"); + _cClean[0].setAccessible(true); + } return Boolean.TRUE; } catch(final Throwable t) { if( DEBUG ) { @@ -1189,27 +1211,43 @@ public class Buffers { } return Boolean.FALSE; } } } ).booleanValue() ) { + theUnsafe = _theUnsafe[0]; mbbCleaner = _mbbCleaner[0]; cClean = _cClean[0]; - hasCleaner = null != mbbCleaner && null != cClean; + hasCleaner = PlatformPropsImpl.JAVA_9 ? null != theUnsafe && null != cClean : null != mbbCleaner && null != cClean; } else { + theUnsafe = null; mbbCleaner = null; cClean = null; hasCleaner = false; } cleanerError = !hasCleaner; + if( DEBUG ) { + System.err.print("Buffers.Cleaner.init: hasCleaner: "+hasCleaner+", cleanerError "+cleanerError); + if( null != mbbCleaner ) { + System.err.print(", using Cleaner class: "+mbbCleaner.getReturnType().getName()); + } + if( null != theUnsafe ) { + System.err.print(", using sun.misc.Unsafe::invokeCleaner(..);"); + } + System.err.println(); + } } /** * If {@code b} is an direct NIO buffer, i.e {@link sun.nio.ch.DirectBuffer}, * calls it's {@link sun.misc.Cleaner} instance {@code clean()} method. * @return {@code true} if successful, otherwise {@code false}. */ - public static boolean clean(final Buffer b) { - if( !hasCleaner || cleanerError || !b.isDirect() ) { + public static boolean clean(final ByteBuffer bb) { + if( !hasCleaner || cleanerError || !bb.isDirect() ) { return false; } try { - cClean.invoke(mbbCleaner.invoke(b)); + if( PlatformPropsImpl.JAVA_9 ) { + cClean.invoke(theUnsafe, bb); + } else { + cClean.invoke(mbbCleaner.invoke(bb)); + } return true; } catch(final Throwable t) { cleanerError = true; diff --git a/src/junit/com/jogamp/common/nio/BuffersTest.java b/src/junit/com/jogamp/common/nio/TestBuffers.java index c267100..89b5671 100644 --- a/src/junit/com/jogamp/common/nio/BuffersTest.java +++ b/src/junit/com/jogamp/common/nio/TestBuffers.java @@ -53,7 +53,7 @@ import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters; @FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class BuffersTest extends SingletonJunitCase { +public class TestBuffers extends SingletonJunitCase { @Test public void test01PositionLimitCapacityAfterArrayAllocation() { @@ -156,8 +156,14 @@ public class BuffersTest extends SingletonJunitCase { assertEquals(42, onetwothree.get(2)); } + @Test + public void test20Cleaner() { + final ByteBuffer byteBuffer = Buffers.newDirectByteBuffer(1024); + Buffers.Cleaner.clean(byteBuffer); + } + public static void main(final String args[]) throws IOException { - final String tstname = BuffersTest.class.getName(); + final String tstname = TestBuffers.class.getName(); org.junit.runner.JUnitCore.main(tstname); } } diff --git a/src/junit/com/jogamp/common/nio/TestByteBufferCopyStream.java b/src/junit/com/jogamp/common/nio/TestByteBufferCopyStream.java index 9524e91..aef0d3e 100644 --- a/src/junit/com/jogamp/common/nio/TestByteBufferCopyStream.java +++ b/src/junit/com/jogamp/common/nio/TestByteBufferCopyStream.java @@ -52,6 +52,8 @@ public class TestByteBufferCopyStream extends SingletonJunitCase { final MappedByteBufferInputStream.CacheMode srcCacheMode, final int srcSliceShift, final String dstFileName, final MappedByteBufferInputStream.CacheMode dstCacheMode, final int dstSliceShift ) throws IOException { + System.err.println("Test: source[CacheMode "+srcCacheMode+", SliceShift "+srcSliceShift+"]"); + System.err.println(" destin[CacheMode "+dstCacheMode+", SliceShift "+dstSliceShift+"]"); final Runtime runtime = Runtime.getRuntime(); final long[] usedMem0 = { 0 }; final long[] freeMem0 = { 0 }; @@ -60,6 +62,7 @@ public class TestByteBufferCopyStream extends SingletonJunitCase { final String prefix = "test "+String.format(TestByteBufferInputStream.PrintPrecision+" MiB", size/TestByteBufferInputStream.MIB); TestByteBufferInputStream.dumpMem(prefix+" before", runtime, -1, -1, usedMem0, freeMem0 ); + final long t0 = Platform.currentTimeMillis(); final File srcFile = new File(srcFileName); srcFile.delete(); srcFile.createNewFile(); @@ -72,6 +75,7 @@ public class TestByteBufferCopyStream extends SingletonJunitCase { _input.close(); input = new RandomAccessFile(srcFile, "r"); } + final long t1 = Platform.currentTimeMillis(); final MappedByteBufferInputStream mis = new MappedByteBufferInputStream(input.getChannel(), FileChannel.MapMode.READ_ONLY, srcCacheMode, @@ -131,12 +135,19 @@ public class TestByteBufferCopyStream extends SingletonJunitCase { output.close(); srcFile.delete(); dstFile.delete(); + final long t5 = Platform.currentTimeMillis(); TestByteBufferInputStream.dumpMem(prefix+" after ", runtime, usedMem0[0], freeMem0[0], usedMem1, freeMem1 ); System.gc(); + final long t6 = Platform.currentTimeMillis(); try { Thread.sleep(500); } catch (final InterruptedException e) { } TestByteBufferInputStream.dumpMem(prefix+" gc'ed ", runtime, usedMem0[0], freeMem0[0], usedMem1, freeMem1 ); + System.err.println("Performance Stats: "); + System.err.printf("- File-Create %6d ms\n", t1-t0); + System.err.printf("- File-Copy %6d ms\n", t5-t1); + System.err.printf("- GC %6d ms\n", t6-t5); + System.err.printf("- Total %6d ms\n", t6-t0); } if( null != ioe || null != oome ) { if( null != oome ) { diff --git a/src/junit/com/jogamp/common/nio/CachedBufferFactoryTest.java b/src/junit/com/jogamp/common/nio/TestCachedBufferFactory.java index 6b9409f..6ed1b91 100644 --- a/src/junit/com/jogamp/common/nio/CachedBufferFactoryTest.java +++ b/src/junit/com/jogamp/common/nio/TestCachedBufferFactory.java @@ -55,7 +55,7 @@ import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters; @FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class CachedBufferFactoryTest extends SingletonJunitCase { +public class TestCachedBufferFactory extends SingletonJunitCase { private final int BUFFERCOUNT = 120; @@ -210,7 +210,7 @@ public class CachedBufferFactoryTest extends SingletonJunitCase { public static void main(final String[] args) { - CachedBufferFactoryTest test = new CachedBufferFactoryTest(); + TestCachedBufferFactory test = new TestCachedBufferFactory(); out.print("warmup..."); Object obj = null; @@ -221,7 +221,7 @@ public class CachedBufferFactoryTest extends SingletonJunitCase { } out.println("done"); - test = new CachedBufferFactoryTest(); + test = new TestCachedBufferFactory(); gc(); for (int i = 0; i < 10; i++) { |