1 /* 2 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 /* 27 */ 28 29 #include "jni.h" 30 #include "jni_util.h" 31 #include "jlong.h" 32 #include <string.h> 33 34 #include "JNIHelp.h" 35 36 /* 37 * WARNING: 38 * 39 * Do not replace instances of: 40 * 41 * if (length > MBYTE) 42 * size = MBYTE; 43 * else 44 * size = length; 45 * 46 * with 47 * 48 * size = (length > MBYTE ? MBYTE : length); 49 * 50 * This expression causes a c compiler assertion failure when compiling on 51 * 32-bit sparc. 52 */ 53 54 #define MBYTE 1048576 55 56 #define GETCRITICAL(bytes, env, obj) { \ 57 bytes = (*env)->GetPrimitiveArrayCritical(env, obj, NULL); \ 58 if (bytes == NULL) \ 59 JNU_ThrowInternalError(env, "Unable to get array"); \ 60 } 61 62 #define RELEASECRITICAL(bytes, env, obj, mode) { \ 63 (*env)->ReleasePrimitiveArrayCritical(env, obj, bytes, mode); \ 64 } 65 66 #define SWAPSHORT(x) ((jshort)(((x) << 8) | (((x) >> 8) & 0xff))) 67 #define SWAPINT(x) ((jint)((SWAPSHORT((jshort)(x)) << 16) | \ 68 (SWAPSHORT((jshort)((x) >> 16)) & 0xffff))) 69 #define SWAPLONG(x) ((jlong)(((jlong)SWAPINT((jint)(x)) << 32) | \ 70 ((jlong)SWAPINT((jint)((x) >> 32)) & 0xffffffff))) 71 72 #define NATIVE_METHOD(className, functionName, signature) \ 73 { #functionName, signature, (void*)(Java_java_nio_ ## className ## _ ## functionName) } 74 75 JNIEXPORT void JNICALL 76 Java_java_nio_Bits_copyFromShortArray(JNIEnv *env, jobject this, jobject src, 77 jlong srcPos, jlong dstAddr, jlong length) 78 { 79 jbyte *bytes; 80 size_t size; 81 jshort *srcShort, *dstShort, *endShort; 82 jshort tmpShort; 83 84 dstShort = (jshort *)jlong_to_ptr(dstAddr); 85 86 while (length > 0) { 87 /* do not change this if-else statement, see WARNING above */ 88 if (length > MBYTE) 89 size = MBYTE; 90 else 91 size = (size_t)length; 92 93 GETCRITICAL(bytes, env, src); 94 95 srcShort = (jshort *)(bytes + srcPos); 96 endShort = srcShort + (size / sizeof(jshort)); 97 while (srcShort < endShort) { 98 tmpShort = *srcShort++; 99 *dstShort++ = SWAPSHORT(tmpShort); 100 } 101 102 RELEASECRITICAL(bytes, env, src, JNI_ABORT); 103 104 length -= size; 105 dstAddr += size; 106 srcPos += size; 107 } 108 } 109 110 JNIEXPORT void JNICALL 111 Java_java_nio_Bits_copyToShortArray(JNIEnv *env, jobject this, jlong srcAddr, 112 jobject dst, jlong dstPos, jlong length) 113 { 114 jbyte *bytes; 115 size_t size; 116 jshort *srcShort, *dstShort, *endShort; 117 jshort tmpShort; 118 119 srcShort = (jshort *)jlong_to_ptr(srcAddr); 120 121 while (length > 0) { 122 /* do not change this if-else statement, see WARNING above */ 123 if (length > MBYTE) 124 size = MBYTE; 125 else 126 size = (size_t)length; 127 128 GETCRITICAL(bytes, env, dst); 129 130 dstShort = (jshort *)(bytes + dstPos); 131 endShort = srcShort + (size / sizeof(jshort)); 132 while (srcShort < endShort) { 133 tmpShort = *srcShort++; 134 *dstShort++ = SWAPSHORT(tmpShort); 135 } 136 137 RELEASECRITICAL(bytes, env, dst, 0); 138 139 length -= size; 140 srcAddr += size; 141 dstPos += size; 142 } 143 } 144 145 JNIEXPORT void JNICALL 146 Java_java_nio_Bits_copyFromIntArray(JNIEnv *env, jobject this, jobject src, 147 jlong srcPos, jlong dstAddr, jlong length) 148 { 149 jbyte *bytes; 150 size_t size; 151 jint *srcInt, *dstInt, *endInt; 152 jint tmpInt; 153 154 dstInt = (jint *)jlong_to_ptr(dstAddr); 155 156 while (length > 0) { 157 /* do not change this code, see WARNING above */ 158 if (length > MBYTE) 159 size = MBYTE; 160 else 161 size = (size_t)length; 162 163 GETCRITICAL(bytes, env, src); 164 165 srcInt = (jint *)(bytes + srcPos); 166 endInt = srcInt + (size / sizeof(jint)); 167 while (srcInt < endInt) { 168 tmpInt = *srcInt++; 169 *dstInt++ = SWAPINT(tmpInt); 170 } 171 172 RELEASECRITICAL(bytes, env, src, JNI_ABORT); 173 174 length -= size; 175 dstAddr += size; 176 srcPos += size; 177 } 178 } 179 180 JNIEXPORT void JNICALL 181 Java_java_nio_Bits_copyToIntArray(JNIEnv *env, jobject this, jlong srcAddr, 182 jobject dst, jlong dstPos, jlong length) 183 { 184 jbyte *bytes; 185 size_t size; 186 jint *srcInt, *dstInt, *endInt; 187 jint tmpInt; 188 189 srcInt = (jint *)jlong_to_ptr(srcAddr); 190 191 while (length > 0) { 192 /* do not change this code, see WARNING above */ 193 if (length > MBYTE) 194 size = MBYTE; 195 else 196 size = (size_t)length; 197 198 GETCRITICAL(bytes, env, dst); 199 200 dstInt = (jint *)(bytes + dstPos); 201 endInt = srcInt + (size / sizeof(jint)); 202 while (srcInt < endInt) { 203 tmpInt = *srcInt++; 204 *dstInt++ = SWAPINT(tmpInt); 205 } 206 207 RELEASECRITICAL(bytes, env, dst, 0); 208 209 length -= size; 210 srcAddr += size; 211 dstPos += size; 212 } 213 } 214 215 JNIEXPORT void JNICALL 216 Java_java_nio_Bits_copyFromLongArray(JNIEnv *env, jobject this, jobject src, 217 jlong srcPos, jlong dstAddr, jlong length) 218 { 219 jbyte *bytes; 220 size_t size; 221 jlong *srcLong, *dstLong, *endLong; 222 jlong tmpLong; 223 224 dstLong = (jlong *)jlong_to_ptr(dstAddr); 225 226 while (length > 0) { 227 /* do not change this code, see WARNING above */ 228 if (length > MBYTE) 229 size = MBYTE; 230 else 231 size = (size_t)length; 232 233 GETCRITICAL(bytes, env, src); 234 235 srcLong = (jlong *)(bytes + srcPos); 236 endLong = srcLong + (size / sizeof(jlong)); 237 while (srcLong < endLong) { 238 tmpLong = *srcLong++; 239 *dstLong++ = SWAPLONG(tmpLong); 240 } 241 242 RELEASECRITICAL(bytes, env, src, JNI_ABORT); 243 244 length -= size; 245 dstAddr += size; 246 srcPos += size; 247 } 248 } 249 250 JNIEXPORT void JNICALL 251 Java_java_nio_Bits_copyToLongArray(JNIEnv *env, jobject this, jlong srcAddr, 252 jobject dst, jlong dstPos, jlong length) 253 { 254 jbyte *bytes; 255 size_t size; 256 jlong *srcLong, *dstLong, *endLong; 257 jlong tmpLong; 258 259 srcLong = (jlong *)jlong_to_ptr(srcAddr); 260 261 while (length > 0) { 262 /* do not change this code, see WARNING above */ 263 if (length > MBYTE) 264 size = MBYTE; 265 else 266 size = (size_t)length; 267 268 GETCRITICAL(bytes, env, dst); 269 270 dstLong = (jlong *)(bytes + dstPos); 271 endLong = srcLong + (size / sizeof(jlong)); 272 while (srcLong < endLong) { 273 tmpLong = *srcLong++; 274 *dstLong++ = SWAPLONG(tmpLong); 275 } 276 277 RELEASECRITICAL(bytes, env, dst, 0); 278 279 length -= size; 280 srcAddr += size; 281 dstPos += size; 282 } 283 } 284 285 static JNINativeMethod gMethods[] = { 286 NATIVE_METHOD(Bits, copyFromShortArray, "(Ljava/lang/Object;JJJ)V"), 287 NATIVE_METHOD(Bits, copyToShortArray, "(JLjava/lang/Object;JJ)V"), 288 NATIVE_METHOD(Bits, copyFromIntArray, "(Ljava/lang/Object;JJJ)V"), 289 NATIVE_METHOD(Bits, copyToIntArray, "(JLjava/lang/Object;JJ)V"), 290 NATIVE_METHOD(Bits, copyFromLongArray, "(Ljava/lang/Object;JJJ)V"), 291 NATIVE_METHOD(Bits, copyToLongArray, "(JLjava/lang/Object;JJ)V"), 292 }; 293 294 void register_java_nio_Bits(JNIEnv* env) { 295 jniRegisterNativeMethods(env, "java/nio/Bits", gMethods, NELEM(gMethods)); 296 } 297