diff --git a/buffer/src/main/java/io/netty/buffer/PoolArena.java b/buffer/src/main/java/io/netty/buffer/PoolArena.java index c4370b9ac6..056dd66445 100644 --- a/buffer/src/main/java/io/netty/buffer/PoolArena.java +++ b/buffer/src/main/java/io/netty/buffer/PoolArena.java @@ -354,8 +354,7 @@ abstract class PoolArena { static final class DirectArena extends PoolArena { - private static final boolean USE_UNSAFE_DIRECTBUF = - PlatformDependent.isUnaligned() && PlatformDependent.unsafeHasCopyMethods(); + private static final boolean USE_UNSAFE_DIRECTBUF = PlatformDependent.unsafeHasCopyMethods(); DirectArena(PooledByteBufAllocator parent, int pageSize, int maxOrder, int pageShifts, int chunkSize) { super(parent, pageSize, maxOrder, pageShifts, chunkSize); @@ -392,7 +391,7 @@ abstract class PoolArena { return; } - if (PlatformDependent.isUnaligned() && PlatformDependent.unsafeHasCopyMethods()) { + if (USE_UNSAFE_DIRECTBUF) { PlatformDependent.copyMemory( PlatformDependent.directBufferAddress(src) + srcOffset, PlatformDependent.directBufferAddress(dst) + dstOffset, length); diff --git a/common/src/main/java/io/netty/util/internal/PlatformDependent.java b/common/src/main/java/io/netty/util/internal/PlatformDependent.java index ac8cf6729d..466b2ecc9c 100644 --- a/common/src/main/java/io/netty/util/internal/PlatformDependent.java +++ b/common/src/main/java/io/netty/util/internal/PlatformDependent.java @@ -53,7 +53,6 @@ public final class PlatformDependent { private static final boolean CAN_USE_CHM_V8 = HAS_UNSAFE && JAVA_VERSION < 8; 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 long ARRAY_BASE_OFFSET = arrayBaseOffset0(); private static final boolean HAS_JAVASSIST = hasJavassist0(); @@ -109,13 +108,6 @@ public final class PlatformDependent { return CAN_FREE_DIRECT_BUFFER; } - /** - * Returns {@code true} if and only if {@code java.nio.Bits.unaligned()} is true. - */ - public static boolean isUnaligned() { - return IS_UNALIGNED; - } - /** * Returns {@code true} if unsafe has all needed copy methods which is not the case on latest openjdk6 atm. */ @@ -360,14 +352,6 @@ public final class PlatformDependent { return PlatformDependent0.canFreeDirectBuffer(); } - private static boolean isUnaligned0() { - if (!hasUnsafe()) { - return false; - } - - return PlatformDependent0.isUnaligned(); - } - private static boolean unsafeHasCopyMethods0() { if (!hasUnsafe()) { return false; diff --git a/common/src/main/java/io/netty/util/internal/PlatformDependent0.java b/common/src/main/java/io/netty/util/internal/PlatformDependent0.java index bdbbb978cd..90b7f87c70 100644 --- a/common/src/main/java/io/netty/util/internal/PlatformDependent0.java +++ b/common/src/main/java/io/netty/util/internal/PlatformDependent0.java @@ -31,6 +31,11 @@ final class PlatformDependent0 { private static final Unsafe UNSAFE; private static final long CLEANER_FIELD_OFFSET; private static final long ADDRESS_FIELD_OFFSET; + /** + * {@code true} if and only if the platform supports unaligned access. + * + * @see Wikipedia on segfault + */ private static final boolean UNALIGNED; private static final boolean HAS_COPY_METHODS; @@ -120,10 +125,6 @@ final class PlatformDependent0 { } static long directBufferAddress(ByteBuffer buffer) { - if (!isUnaligned()) { - throw new Error(); - } - return getLong(buffer, ADDRESS_FIELD_OFFSET); } @@ -137,10 +138,6 @@ final class PlatformDependent0 { } } - static boolean isUnaligned() { - return UNALIGNED; - } - static boolean hasCopyMethods() { return HAS_COPY_METHODS; } @@ -166,15 +163,37 @@ final class PlatformDependent0 { } static short getShort(long address) { - return UNSAFE.getShort(address); + if (UNALIGNED) { + return UNSAFE.getShort(address); + } else { + return (short)(getByte(address) << 8 | getByte(address + 1) & 0xff); + } } static int getInt(long address) { - return UNSAFE.getInt(address); + if (UNALIGNED) { + return UNSAFE.getInt(address); + } else { + return getByte(address) << 24 | + (getByte(address + 1) & 0xff) << 16 | + (getByte(address + 2) & 0xff) << 8 | + getByte(address + 3) & 0xff; + } } static long getLong(long address) { - return UNSAFE.getLong(address); + if (UNALIGNED) { + return UNSAFE.getLong(address); + } else { + return (long) getByte(address) << 56 | + ((long) getByte(address + 1) & 0xff) << 48 | + ((long) getByte(address + 2) & 0xff) << 40 | + ((long) getByte(address + 3) & 0xff) << 32 | + ((long) getByte(address + 4) & 0xff) << 24 | + ((long) getByte(address + 5) & 0xff) << 16 | + ((long) getByte(address + 6) & 0xff) << 8 | + (long) getByte(address + 7) & 0xff; + } } static void putByte(long address, byte value) { @@ -182,15 +201,38 @@ final class PlatformDependent0 { } static void putShort(long address, short value) { - UNSAFE.putShort(address, value); + if (UNALIGNED) { + UNSAFE.putShort(address, value); + } else { + putByte(address, (byte) (value >>> 8)); + putByte(address + 1, (byte) value); + } } static void putInt(long address, int value) { - UNSAFE.putInt(address, value); + if (UNALIGNED) { + UNSAFE.putInt(address, value); + } else { + putByte(address, (byte) (value >>> 24)); + putByte(address + 1, (byte) (value >>> 16)); + putByte(address + 2, (byte) (value >>> 8)); + putByte(address + 3, (byte) value); + } } static void putLong(long address, long value) { - UNSAFE.putLong(address, value); + if (UNALIGNED) { + UNSAFE.putLong(address, value); + } else { + putByte(address, (byte) (value >>> 56)); + putByte(address + 1, (byte) (value >>> 48)); + putByte(address + 2, (byte) (value >>> 40)); + putByte(address + 3, (byte) (value >>> 32)); + putByte(address + 4, (byte) (value >>> 24)); + putByte(address + 5, (byte) (value >>> 16)); + putByte(address + 6, (byte) (value >>> 8)); + putByte(address + 7, (byte) value); + } } static void copyMemory(long srcAddr, long dstAddr, long length) {