--- old/src/java.base/share/classes/jdk/internal/misc/Unsafe.java 2016-02-05 13:30:06.917439881 -0800 +++ new/src/java.base/share/classes/jdk/internal/misc/Unsafe.java 2016-02-05 13:30:06.701436118 -0800 @@ -458,9 +458,19 @@ copyMemory(null, srcAddress, null, destAddress, bytes); } + private boolean isPrimitiveArray(Class c) { + Class componentType = c.getComponentType(); + return componentType != null && componentType.isPrimitive(); + } + + private native void copySwapMemory0(Object srcBase, long srcOffset, + Object destBase, long destOffset, + long bytes, long elemSize); + + /** - * Copies all elements from one block of memory to another block, byte swapping the - * elements on the fly. + * Copies all elements from one block of memory to another block, + * *unconditionally* byte swapping the elements on the fly. * *

This method determines each block's base address by means of two parameters, * and so it provides (in effect) a double-register addressing mode, @@ -469,9 +479,42 @@ * * @since 9 */ - public native void copySwapMemory(Object srcBase, long srcOffset, - Object destBase, long destOffset, - long bytes, long elemSize); + public void copySwapMemory(Object srcBase, long srcOffset, + Object destBase, long destOffset, + long bytes, long elemSize) { + if (bytes < 0 || srcOffset < 0 || destOffset < 0) { + throw new IllegalArgumentException(); + } + if (elemSize != 2 && elemSize != 4 && elemSize != 8) { + throw new IllegalArgumentException(); + } + if (bytes % elemSize != 0) { + throw new IllegalArgumentException(); + } + if ((srcBase == null && srcOffset == 0) || + (destBase == null && destOffset == 0)) { + throw new NullPointerException(); + } + + // Must be off-heap, or primitive heap arrays + if ((srcBase != null && !isPrimitiveArray(srcBase.getClass())) || + (destBase != null && !isPrimitiveArray(destBase.getClass()))) { + throw new IllegalArgumentException(); + } + + // Sanity check size and offsets on 32-bit platforms. Most + // significant 32 bits must be zero. + if (ADDRESS_SIZE == 4 && + (bytes >>> 32 != 0 || srcOffset >>> 32 != 0 || destOffset >>> 32 != 0)) { + throw new IllegalArgumentException(); + } + + if (bytes == 0) { + return; + } + + copySwapMemory0(srcBase, srcOffset, destBase, destOffset, bytes, elemSize); + } /** * Copies all elements from one block of memory to another block, byte swapping the