[#1061] Add workaround to not use PooledUnsafeDirectByteBuf when running on latest OpenJDK6 because of missing Unsafe method

This commit is contained in:
Norman Maurer 2013-02-19 12:21:08 +01:00
parent 4ed5b07e4e
commit 74738fbd08
4 changed files with 35 additions and 3 deletions

View File

@ -376,7 +376,7 @@ abstract class PoolArena<T> {
@Override @Override
protected PooledByteBuf<ByteBuffer> newByteBuf(int maxCapacity) { protected PooledByteBuf<ByteBuffer> newByteBuf(int maxCapacity) {
if (PlatformDependent.isUnaligned()) { if (PlatformDependent.isUnaligned() && PlatformDependent.unsafeHasCopyMethods()) {
return new PooledUnsafeDirectByteBuf(maxCapacity); return new PooledUnsafeDirectByteBuf(maxCapacity);
} else { } else {
return new PooledDirectByteBuf(maxCapacity); return new PooledDirectByteBuf(maxCapacity);
@ -389,7 +389,7 @@ abstract class PoolArena<T> {
return; return;
} }
if (PlatformDependent.isUnaligned()) { if (PlatformDependent.isUnaligned() && PlatformDependent.unsafeHasCopyMethods()) {
PlatformDependent.copyMemory( PlatformDependent.copyMemory(
PlatformDependent.directBufferAddress(src) + srcOffset, PlatformDependent.directBufferAddress(src) + srcOffset,
PlatformDependent.directBufferAddress(dst) + dstOffset, length); PlatformDependent.directBufferAddress(dst) + dstOffset, length);

View File

@ -30,7 +30,6 @@ import java.nio.channels.ScatteringByteChannel;
final class PooledUnsafeDirectByteBuf extends PooledByteBuf<ByteBuffer> { final class PooledUnsafeDirectByteBuf extends PooledByteBuf<ByteBuffer> {
private static final boolean NATIVE_ORDER = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN; private static final boolean NATIVE_ORDER = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
private long memoryAddress; private long memoryAddress;
PooledUnsafeDirectByteBuf(int maxCapacity) { PooledUnsafeDirectByteBuf(int maxCapacity) {

View File

@ -46,6 +46,7 @@ public final class PlatformDependent {
private static final boolean HAS_UNSAFE = hasUnsafe0(); private static final boolean HAS_UNSAFE = hasUnsafe0();
private static final boolean CAN_FREE_DIRECT_BUFFER = canFreeDirectBuffer0(); private static final boolean CAN_FREE_DIRECT_BUFFER = canFreeDirectBuffer0();
private static final boolean UNSAFE_HASE_COPY_METHODS = unsafeHasCopyMethods0();
private static final boolean IS_UNALIGNED = isUnaligned0(); private static final boolean IS_UNALIGNED = isUnaligned0();
private static final long ARRAY_BASE_OFFSET = arrayBaseOffset0(); private static final long ARRAY_BASE_OFFSET = arrayBaseOffset0();
@ -109,6 +110,13 @@ public final class PlatformDependent {
return IS_UNALIGNED; return IS_UNALIGNED;
} }
/**
* Returns {@code true} if unsafe has all needed copy methods which is not the case on latest openjdk6 atm.
*/
public static boolean unsafeHasCopyMethods() {
return UNSAFE_HASE_COPY_METHODS;
}
/** /**
* Returns {@code true} if and only if Javassist is available. * Returns {@code true} if and only if Javassist is available.
*/ */
@ -293,6 +301,13 @@ public final class PlatformDependent {
return PlatformDependent0.isUnaligned(); return PlatformDependent0.isUnaligned();
} }
private static boolean unsafeHasCopyMethods0() {
if (!hasUnsafe()) {
return false;
}
return PlatformDependent0.hasCopyMethods();
}
private static long arrayBaseOffset0() { private static long arrayBaseOffset0() {
if (!hasUnsafe()) { if (!hasUnsafe()) {
return -1; return -1;

View File

@ -32,6 +32,7 @@ final class PlatformDependent0 {
private static final long CLEANER_FIELD_OFFSET; private static final long CLEANER_FIELD_OFFSET;
private static final long ADDRESS_FIELD_OFFSET; private static final long ADDRESS_FIELD_OFFSET;
private static final boolean UNALIGNED; private static final boolean UNALIGNED;
private static final boolean HAS_COPY_METHODS;
static { static {
Unsafe unsafe; Unsafe unsafe;
@ -48,6 +49,7 @@ final class PlatformDependent0 {
CLEANER_FIELD_OFFSET = -1; CLEANER_FIELD_OFFSET = -1;
ADDRESS_FIELD_OFFSET = -1; ADDRESS_FIELD_OFFSET = -1;
UNALIGNED = false; UNALIGNED = false;
HAS_COPY_METHODS = false;
} else { } else {
ByteBuffer direct = ByteBuffer.allocateDirect(1); ByteBuffer direct = ByteBuffer.allocateDirect(1);
Field cleanerField; Field cleanerField;
@ -94,6 +96,18 @@ final class PlatformDependent0 {
} }
UNALIGNED = unaligned; UNALIGNED = unaligned;
boolean hasCopyMethods;
try {
// Unsafe does not shop all copy methods in latest openjdk update..
// https://github.com/netty/netty/issues/1061
// http://www.mail-archive.com/jdk6-dev@openjdk.java.net/msg00698.html
UNSAFE.getClass().getDeclaredMethod("copyMemory",
new Class[] { Object.class, long.class, Object.class, long.class, long.class });
hasCopyMethods = true;
} catch (Throwable ignore) {
hasCopyMethods = false;
}
HAS_COPY_METHODS = hasCopyMethods;
} }
} }
@ -127,6 +141,10 @@ final class PlatformDependent0 {
return UNALIGNED; return UNALIGNED;
} }
static boolean hasCopyMethods() {
return HAS_COPY_METHODS;
}
static long arrayBaseOffset() { static long arrayBaseOffset() {
return UNSAFE.arrayBaseOffset(byte[].class); return UNSAFE.arrayBaseOffset(byte[].class);
} }