src/java.base/share/native/libjava/Bits.c

Print this page

        

@@ -50,20 +50,42 @@
 #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)))
 
+/* The destination buffer passed to Java_java_nio_Bits_copyFromShor<type>tArray
+ * function and the source buffer passed to Java_java_nio_Bits_copyTo<type>Array
+ * may not be aligned on <type>'s boundary. Inform the compiler about this via
+ * 'unaligned' attribute, provided it supports this attribute. Fro recent 
+ * compilers, use __has_attribute preprocessor predicate; if it is not available,
+ * we know that GCC supports it.
+ */
+#ifndef __has_attribute
+#define __has_attribute(x) 0
+#endif
+
+#if defined(__GNUC__) || __has_attribute(aligned)
+typedef jshort __attribute__((aligned(1))) jshort_unaligned;
+typedef jint __attribute__((aligned(1))) jint_unaligned;
+typedef jlong __attribute__((aligned(1))) jlong_unaligned;
+#else
+typedef jshort jshort_unaligned;
+typedef jint jint_unaligned;
+typedef jlong jlong_unaligned;
+#endif
+
 JNIEXPORT void JNICALL
 Java_java_nio_Bits_copyFromShortArray(JNIEnv *env, jclass clazz, jobject src,
                                       jlong srcPos, jlong dstAddr, jlong length)
 {
     jbyte *bytes;
     size_t size;
-    jshort *srcShort, *dstShort, *endShort;
+    jshort *srcShort, *endShort;
+    jshort_unaligned *dstShort;
     jshort tmpShort;
 
-    dstShort = (jshort *)jlong_to_ptr(dstAddr);
+    dstShort = (jshort_unaligned *)jlong_to_ptr(dstAddr);
 
     while (length > 0) {
         size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE;
 
         GETCRITICAL_OR_RETURN(bytes, env, src);

@@ -86,14 +108,15 @@
 Java_java_nio_Bits_copyToShortArray(JNIEnv *env, jclass clazz, jlong srcAddr,
                                     jobject dst, jlong dstPos, jlong length)
 {
     jbyte *bytes;
     size_t size;
-    jshort *srcShort, *dstShort, *endShort;
+    jshort_unaligned *srcShort, *endShort;
+    jshort *dstShort;
     jshort tmpShort;
 
-    srcShort = (jshort *)jlong_to_ptr(srcAddr);
+    srcShort = (jshort_unaligned *)jlong_to_ptr(srcAddr);
 
     while (length > 0) {
         size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE;
 
         GETCRITICAL_OR_RETURN(bytes, env, dst);

@@ -116,14 +139,15 @@
 Java_java_nio_Bits_copyFromIntArray(JNIEnv *env, jclass clazz, jobject src,
                                     jlong srcPos, jlong dstAddr, jlong length)
 {
     jbyte *bytes;
     size_t size;
-    jint *srcInt, *dstInt, *endInt;
+    jint *srcInt, *endInt;
+    jint_unaligned *dstInt;
     jint tmpInt;
 
-    dstInt = (jint *)jlong_to_ptr(dstAddr);
+    dstInt = (jint_unaligned *)jlong_to_ptr(dstAddr);
 
     while (length > 0) {
         size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE;
 
         GETCRITICAL_OR_RETURN(bytes, env, src);

@@ -146,14 +170,15 @@
 Java_java_nio_Bits_copyToIntArray(JNIEnv *env, jclass clazz, jlong srcAddr,
                                   jobject dst, jlong dstPos, jlong length)
 {
     jbyte *bytes;
     size_t size;
-    jint *srcInt, *dstInt, *endInt;
+    jint_unaligned *srcInt, *endInt;
+    jint *dstInt;
     jint tmpInt;
 
-    srcInt = (jint *)jlong_to_ptr(srcAddr);
+    srcInt = (jint_unaligned *)jlong_to_ptr(srcAddr);
 
     while (length > 0) {
         size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE;
 
         GETCRITICAL_OR_RETURN(bytes, env, dst);

@@ -176,14 +201,15 @@
 Java_java_nio_Bits_copyFromLongArray(JNIEnv *env, jclass clazz, jobject src,
                                      jlong srcPos, jlong dstAddr, jlong length)
 {
     jbyte *bytes;
     size_t size;
-    jlong *srcLong, *dstLong, *endLong;
+    jlong *srcLong, *endLong;
+    jlong_unaligned *dstLong;
     jlong tmpLong;
 
-    dstLong = (jlong *)jlong_to_ptr(dstAddr);
+    dstLong = (jlong_unaligned *)jlong_to_ptr(dstAddr);
 
     while (length > 0) {
         size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE;
 
         GETCRITICAL_OR_RETURN(bytes, env, src);

@@ -206,14 +232,15 @@
 Java_java_nio_Bits_copyToLongArray(JNIEnv *env, jclass clazz, jlong srcAddr,
                                    jobject dst, jlong dstPos, jlong length)
 {
     jbyte *bytes;
     size_t size;
-    jlong *srcLong, *dstLong, *endLong;
+    jlong_unaligned *srcLong, *endLong;
+    jlong *dstLong;
     jlong tmpLong;
 
-    srcLong = (jlong *)jlong_to_ptr(srcAddr);
+    srcLong = (jlong_unaligned *)jlong_to_ptr(srcAddr);
 
     while (length > 0) {
         size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE;
 
         GETCRITICAL_OR_RETURN(bytes, env, dst);