diff --git a/make/mapfiles/libjava/mapfile-vers b/make/mapfiles/libjava/mapfile-vers index 09b25bfb0d58cd9742c06f2793b97758eb87be27..1168c79951debe58a8c1ec806d735e30db4ea0e4 100644 --- a/make/mapfiles/libjava/mapfile-vers +++ b/make/mapfiles/libjava/mapfile-vers @@ -1,5 +1,5 @@ # -# Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -222,12 +222,7 @@ SUNWprivate_1.1 { Java_java_lang_UNIXProcess_waitForProcessExit; Java_java_lang_UNIXProcess_forkAndExec; Java_java_lang_UNIXProcess_destroyProcess; - Java_java_nio_Bits_copyFromShortArray; - Java_java_nio_Bits_copyToShortArray; - Java_java_nio_Bits_copyFromIntArray; - Java_java_nio_Bits_copyToIntArray; - Java_java_nio_Bits_copyFromLongArray; - Java_java_nio_Bits_copyToLongArray; + Java_java_nio_Bits_copySwapMemory0; Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2; Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2Ljava_security_AccessControlContext_2; Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedExceptionAction_2; diff --git a/src/share/classes/java/nio/Bits.java b/src/share/classes/java/nio/Bits.java index 7711b5a58cf70ec8496be4eaa9081fce7e889dc1..53ba46c650532bb418169d623e82c7fb59dcb5c1 100644 --- a/src/share/classes/java/nio/Bits.java +++ b/src/share/classes/java/nio/Bits.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -835,31 +835,191 @@ class Bits { // package-private } } - static void copyFromCharArray(Object src, long srcPos, long dstAddr, - long length) - { - copyFromShortArray(src, srcPos, dstAddr, length); + /** + * Copy and unconditionally byte swap 16 bit elements from a heap array to off-heap memory + * + * @param src + * the source array, must be a 16-bit primitive array type + * @param srcPos + * byte offset within source array of the first element to read + * @param dstAddr + * destination address + * @param length + * number of bytes to copy + */ + static void copyFromCharArray(Object src, long srcPos, long dstAddr, long length) { + copySwapMemory(src, unsafe.arrayBaseOffset(src.getClass()) + srcPos, null, dstAddr, length, 2); } - static void copyToCharArray(long srcAddr, Object dst, long dstPos, - long length) - { - copyToShortArray(srcAddr, dst, dstPos, length); + /** + * Copy and unconditionally byte swap 16 bit elements from off-heap memory to a heap array + * + * @param srcAddr + * source address + * @param dst + * destination array, must be a 16-bit primitive array type + * @param dstPos + * byte offset within the destination array of the first element to write + * @param length + * number of bytes to copy + */ + static void copyToCharArray(long srcAddr, Object dst, long dstPos, long length) { + copySwapMemory(null, srcAddr, dst, unsafe.arrayBaseOffset(dst.getClass()) + dstPos, length, 2); } - static native void copyFromShortArray(Object src, long srcPos, long dstAddr, - long length); - static native void copyToShortArray(long srcAddr, Object dst, long dstPos, - long length); + /** + * Copy and unconditionally byte swap 16 bit elements from a heap array to off-heap memory + * + * @param src + * the source array, must be a 16-bit primitive array type + * @param srcPos + * byte offset within source array of the first element to read + * @param dstAddr + * destination address + * @param length + * number of bytes to copy + */ + static void copyFromShortArray(Object src, long srcPos, long dstAddr, long length) { + copySwapMemory(src, unsafe.arrayBaseOffset(src.getClass()) + srcPos, null, dstAddr, length, 2); + } - static native void copyFromIntArray(Object src, long srcPos, long dstAddr, - long length); - static native void copyToIntArray(long srcAddr, Object dst, long dstPos, - long length); + /** + * Copy and unconditionally byte swap 16 bit elements from off-heap memory to a heap array + * + * @param srcAddr + * source address + * @param dst + * destination array, must be a 16-bit primitive array type + * @param dstPos + * byte offset within the destination array of the first element to write + * @param length + * number of bytes to copy + */ + static void copyToShortArray(long srcAddr, Object dst, long dstPos, long length) { + copySwapMemory(null, srcAddr, dst, unsafe.arrayBaseOffset(dst.getClass()) + dstPos, length, 2); + } + + /** + * Copy and unconditionally byte swap 32 bit elements from a heap array to off-heap memory + * + * @param src + * the source array, must be a 32-bit primitive array type + * @param srcPos + * byte offset within source array of the first element to read + * @param dstAddr + * destination address + * @param length + * number of bytes to copy + */ + static void copyFromIntArray(Object src, long srcPos, long dstAddr, long length) { + copySwapMemory(src, unsafe.arrayBaseOffset(src.getClass()) + srcPos, null, dstAddr, length, 4); + } + + /** + * Copy and unconditionally byte swap 32 bit elements from off-heap memory to a heap array + * + * @param srcAddr + * source address + * @param dst + * destination array, must be a 32-bit primitive array type + * @param dstPos + * byte offset within the destination array of the first element to write + * @param length + * number of bytes to copy + */ + static void copyToIntArray(long srcAddr, Object dst, long dstPos, long length) { + copySwapMemory(null, srcAddr, dst, unsafe.arrayBaseOffset(dst.getClass()) + dstPos, length, 4); + } - static native void copyFromLongArray(Object src, long srcPos, long dstAddr, - long length); - static native void copyToLongArray(long srcAddr, Object dst, long dstPos, - long length); + /** + * Copy and unconditionally byte swap 64 bit elements from a heap array to off-heap memory + * + * @param src + * the source array, must be a 64-bit primitive array type + * @param srcPos + * byte offset within source array of the first element to read + * @param dstAddr + * destination address + * @param length + * number of bytes to copy + */ + static void copyFromLongArray(Object src, long srcPos, long dstAddr, long length) { + copySwapMemory(src, unsafe.arrayBaseOffset(src.getClass()) + srcPos, null, dstAddr, length, 8); + } + + /** + * Copy and unconditionally byte swap 64 bit elements from off-heap memory to a heap array + * + * @param srcAddr + * source address + * @param dst + * destination array, must be a 64-bit primitive array type + * @param dstPos + * byte offset within the destination array of the first element to write + * @param length + * number of bytes to copy + */ + static void copyToLongArray(long srcAddr, Object dst, long dstPos, long length) { + copySwapMemory(null, srcAddr, dst, unsafe.arrayBaseOffset(dst.getClass()) + dstPos, length, 8); + } + + private static boolean isPrimitiveArray(Class c) { + Class componentType = c.getComponentType(); + return componentType != null && componentType.isPrimitive(); + } + + private native static 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, + * *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, + * as discussed in {@link sun.misc.Unsafe#getInt(Object,long)}. When the + * object reference is null, the offset supplies an absolute base address. + * + * @since 8u201 + */ + private static void copySwapMemory(Object srcBase, long srcOffset, + Object destBase, long destOffset, + long bytes, long elemSize) { + if (bytes < 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 && (srcOffset < 0 || !isPrimitiveArray(srcBase.getClass()))) { + throw new IllegalArgumentException(); + } + if (destBase != null && (destOffset < 0 || !isPrimitiveArray(destBase.getClass()))) { + throw new IllegalArgumentException(); + } + + // Sanity check size and offsets on 32-bit platforms. Most + // significant 32 bits must be zero. + if (unsafe.addressSize() == 4 && + (bytes >>> 32 != 0 || srcOffset >>> 32 != 0 || destOffset >>> 32 != 0)) { + throw new IllegalArgumentException(); + } + + if (bytes == 0) { + return; + } + + copySwapMemory0(srcBase, srcOffset, destBase, destOffset, bytes, elemSize); + } } diff --git a/src/share/javavm/export/jvm.h b/src/share/javavm/export/jvm.h index 611120f25b093bb98f944b95b6ca70a3fb06be82..2dc2e202127e2f471cf8eb2c799c3825e4ad25dd 100644 --- a/src/share/javavm/export/jvm.h +++ b/src/share/javavm/export/jvm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -117,6 +117,14 @@ JVM_InitProperties(JNIEnv *env, jobject p); JNIEXPORT void JNICALL JVM_OnExit(void (*func)(void)); +/* + * java.nio.Bits + */ +JNIEXPORT void JNICALL +JVM_CopySwapMemory(JNIEnv *env, jobject srcObj, jlong srcOffset, + jobject dstObj, jlong dstOffset, jlong size, + jlong elemSize); + /* * java.lang.Runtime */ diff --git a/src/share/native/java/nio/Bits.c b/src/share/native/java/nio/Bits.c index 8bc3ff7fecfdb6d489f9233f461dfeaf6663db4e..c509bb65487b0498a23192a8801dc6c12a9d39c1 100644 --- a/src/share/native/java/nio/Bits.c +++ b/src/share/native/java/nio/Bits.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,259 +23,13 @@ * questions. */ -/* - */ - -#include "jni.h" -#include "jni_util.h" -#include "jlong.h" -#include - -/* - * WARNING: - * - * Do not replace instances of: - * - * if (length > MBYTE) - * size = MBYTE; - * else - * size = length; - * - * with - * - * size = (length > MBYTE ? MBYTE : length); - * - * This expression causes a c compiler assertion failure when compiling on - * 32-bit sparc. - */ - -#define MBYTE 1048576 - -#define GETCRITICAL_OR_RETURN(bytes, env, obj) { \ - bytes = (*env)->GetPrimitiveArrayCritical(env, obj, NULL); \ - if (bytes == NULL) { \ - if ((*env)->ExceptionOccurred(env) == NULL) \ - JNU_ThrowInternalError(env, "Unable to get array"); \ - return; \ - } \ -} - -#define RELEASECRITICAL(bytes, env, obj, mode) { \ - (*env)->ReleasePrimitiveArrayCritical(env, obj, bytes, mode); \ -} - -#define SWAPSHORT(x) ((jshort)(((x) << 8) | (((x) >> 8) & 0xff))) -#define SWAPINT(x) ((jint)((SWAPSHORT((jshort)(x)) << 16) | \ - (SWAPSHORT((jshort)((x) >> 16)) & 0xffff))) -#define SWAPLONG(x) ((jlong)(((jlong)SWAPINT((jint)(x)) << 32) | \ - ((jlong)SWAPINT((jint)((x) >> 32)) & 0xffffffff))) - -JNIEXPORT void JNICALL -Java_java_nio_Bits_copyFromShortArray(JNIEnv *env, jobject this, jobject src, - jlong srcPos, jlong dstAddr, jlong length) -{ - jbyte *bytes; - size_t size; - jshort *srcShort, *dstShort, *endShort; - jshort tmpShort; - - dstShort = (jshort *)jlong_to_ptr(dstAddr); - - while (length > 0) { - /* do not change this if-else statement, see WARNING above */ - if (length > MBYTE) - size = MBYTE; - else - size = (size_t)length; - - GETCRITICAL_OR_RETURN(bytes, env, src); - - srcShort = (jshort *)(bytes + srcPos); - endShort = srcShort + (size / sizeof(jshort)); - while (srcShort < endShort) { - tmpShort = *srcShort++; - *dstShort++ = SWAPSHORT(tmpShort); - } - - RELEASECRITICAL(bytes, env, src, JNI_ABORT); - - length -= size; - dstAddr += size; - srcPos += size; - } -} - -JNIEXPORT void JNICALL -Java_java_nio_Bits_copyToShortArray(JNIEnv *env, jobject this, jlong srcAddr, - jobject dst, jlong dstPos, jlong length) -{ - jbyte *bytes; - size_t size; - jshort *srcShort, *dstShort, *endShort; - jshort tmpShort; - - srcShort = (jshort *)jlong_to_ptr(srcAddr); - - while (length > 0) { - /* do not change this if-else statement, see WARNING above */ - if (length > MBYTE) - size = MBYTE; - else - size = (size_t)length; - - GETCRITICAL_OR_RETURN(bytes, env, dst); - - dstShort = (jshort *)(bytes + dstPos); - endShort = srcShort + (size / sizeof(jshort)); - while (srcShort < endShort) { - tmpShort = *srcShort++; - *dstShort++ = SWAPSHORT(tmpShort); - } - - RELEASECRITICAL(bytes, env, dst, 0); - - length -= size; - srcAddr += size; - dstPos += size; - } -} - -JNIEXPORT void JNICALL -Java_java_nio_Bits_copyFromIntArray(JNIEnv *env, jobject this, jobject src, - jlong srcPos, jlong dstAddr, jlong length) -{ - jbyte *bytes; - size_t size; - jint *srcInt, *dstInt, *endInt; - jint tmpInt; - - dstInt = (jint *)jlong_to_ptr(dstAddr); - - while (length > 0) { - /* do not change this code, see WARNING above */ - if (length > MBYTE) - size = MBYTE; - else - size = (size_t)length; - - GETCRITICAL_OR_RETURN(bytes, env, src); - - srcInt = (jint *)(bytes + srcPos); - endInt = srcInt + (size / sizeof(jint)); - while (srcInt < endInt) { - tmpInt = *srcInt++; - *dstInt++ = SWAPINT(tmpInt); - } - - RELEASECRITICAL(bytes, env, src, JNI_ABORT); - - length -= size; - dstAddr += size; - srcPos += size; - } -} - -JNIEXPORT void JNICALL -Java_java_nio_Bits_copyToIntArray(JNIEnv *env, jobject this, jlong srcAddr, - jobject dst, jlong dstPos, jlong length) -{ - jbyte *bytes; - size_t size; - jint *srcInt, *dstInt, *endInt; - jint tmpInt; - - srcInt = (jint *)jlong_to_ptr(srcAddr); - - while (length > 0) { - /* do not change this code, see WARNING above */ - if (length > MBYTE) - size = MBYTE; - else - size = (size_t)length; - - GETCRITICAL_OR_RETURN(bytes, env, dst); - - dstInt = (jint *)(bytes + dstPos); - endInt = srcInt + (size / sizeof(jint)); - while (srcInt < endInt) { - tmpInt = *srcInt++; - *dstInt++ = SWAPINT(tmpInt); - } - - RELEASECRITICAL(bytes, env, dst, 0); - - length -= size; - srcAddr += size; - dstPos += size; - } -} +#include "jvm.h" JNIEXPORT void JNICALL -Java_java_nio_Bits_copyFromLongArray(JNIEnv *env, jobject this, jobject src, - jlong srcPos, jlong dstAddr, jlong length) -{ - jbyte *bytes; - size_t size; - jlong *srcLong, *dstLong, *endLong; - jlong tmpLong; - - dstLong = (jlong *)jlong_to_ptr(dstAddr); - - while (length > 0) { - /* do not change this code, see WARNING above */ - if (length > MBYTE) - size = MBYTE; - else - size = (size_t)length; - - GETCRITICAL_OR_RETURN(bytes, env, src); - - srcLong = (jlong *)(bytes + srcPos); - endLong = srcLong + (size / sizeof(jlong)); - while (srcLong < endLong) { - tmpLong = *srcLong++; - *dstLong++ = SWAPLONG(tmpLong); - } - - RELEASECRITICAL(bytes, env, src, JNI_ABORT); - - length -= size; - dstAddr += size; - srcPos += size; - } -} - -JNIEXPORT void JNICALL -Java_java_nio_Bits_copyToLongArray(JNIEnv *env, jobject this, jlong srcAddr, - jobject dst, jlong dstPos, jlong length) -{ - jbyte *bytes; - size_t size; - jlong *srcLong, *dstLong, *endLong; - jlong tmpLong; - - srcLong = (jlong *)jlong_to_ptr(srcAddr); - - while (length > 0) { - /* do not change this code, see WARNING above */ - if (length > MBYTE) - size = MBYTE; - else - size = (size_t)length; - - GETCRITICAL_OR_RETURN(bytes, env, dst); - - dstLong = (jlong *)(bytes + dstPos); - endLong = srcLong + (size / sizeof(jlong)); - while (srcLong < endLong) { - tmpLong = *srcLong++; - *dstLong++ = SWAPLONG(tmpLong); - } - - RELEASECRITICAL(bytes, env, dst, 0); - - length -= size; - srcAddr += size; - dstPos += size; - } +Java_java_nio_Bits_copySwapMemory0(JNIEnv *env, jclass cls, jobject srcObj, + jlong srcOffset, jobject dstObj, + jlong dstOffset, jlong size, + jlong elemSize) { + JVM_CopySwapMemory(env, srcObj, srcOffset, dstObj, dstOffset, + size, elemSize); }