1 /* 2 * Copyright 2000-2008 Sun Microsystems, Inc. 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. Sun designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 22 * CA 95054 USA or visit www.sun.com if you need additional information or 23 * have any questions. 24 */ 25 26 package java.nio; 27 28 import java.security.AccessController; 29 import java.security.PrivilegedAction; 30 import sun.misc.Unsafe; 31 import sun.misc.VM; 32 import javax.management.ObjectName; 33 import javax.management.MalformedObjectNameException; 34 35 /** 36 * Access to bits, native and otherwise. 37 */ 38 39 class Bits { // package-private 40 41 private Bits() { } 42 43 44 // -- Swapping -- 45 46 static short swap(short x) { 47 return (short)((x << 8) | 48 ((char)x >>> 8)); 49 } 50 51 static char swap(char x) { 52 return (char)((x << 8) | 53 (x >>> 8)); 54 } 55 56 static int swap(int x) { 57 return ((x << 24) | 58 ((x & 0x0000ff00) << 8) | 59 ((x & 0x00ff0000) >>> 8) | 60 (x >>> 24)); 61 } 62 63 static long swap(long x) { 64 return (((long)swap((int)x) << 32) | 65 ((long)swap((int)(x >>> 32)) & 0xffffffffL)); 66 } 67 68 69 // -- get/put char -- 70 71 static private char makeChar(byte b1, byte b0) { 72 return (char)((b1 << 8) | (b0 & 0xff)); 73 } 74 75 static char getCharL(ByteBuffer bb, int bi) { 76 return makeChar(bb._get(bi + 1), 77 bb._get(bi + 0)); 78 } 79 80 static char getCharL(long a) { 81 return makeChar(_get(a + 1), 82 _get(a + 0)); 83 } 84 85 static char getCharB(ByteBuffer bb, int bi) { 86 return makeChar(bb._get(bi + 0), 87 bb._get(bi + 1)); 88 } 89 90 static char getCharB(long a) { 91 return makeChar(_get(a + 0), 92 _get(a + 1)); 93 } 94 95 static char getChar(ByteBuffer bb, int bi, boolean bigEndian) { 96 return (bigEndian ? getCharB(bb, bi) : getCharL(bb, bi)); 97 } 98 99 static char getChar(long a, boolean bigEndian) { 100 return (bigEndian ? getCharB(a) : getCharL(a)); 101 } 102 103 private static byte char1(char x) { return (byte)(x >> 8); } 104 private static byte char0(char x) { return (byte)(x >> 0); } 105 106 static void putCharL(ByteBuffer bb, int bi, char x) { 107 bb._put(bi + 0, char0(x)); 108 bb._put(bi + 1, char1(x)); 109 } 110 111 static void putCharL(long a, char x) { 112 _put(a + 0, char0(x)); 113 _put(a + 1, char1(x)); 114 } 115 116 static void putCharB(ByteBuffer bb, int bi, char x) { 117 bb._put(bi + 0, char1(x)); 118 bb._put(bi + 1, char0(x)); 119 } 120 121 static void putCharB(long a, char x) { 122 _put(a + 0, char1(x)); 123 _put(a + 1, char0(x)); 124 } 125 126 static void putChar(ByteBuffer bb, int bi, char x, boolean bigEndian) { 127 if (bigEndian) 128 putCharB(bb, bi, x); 129 else 130 putCharL(bb, bi, x); 131 } 132 133 static void putChar(long a, char x, boolean bigEndian) { 134 if (bigEndian) 135 putCharB(a, x); 136 else 137 putCharL(a, x); 138 } 139 140 141 // -- get/put short -- 142 143 static private short makeShort(byte b1, byte b0) { 144 return (short)((b1 << 8) | (b0 & 0xff)); 145 } 146 147 static short getShortL(ByteBuffer bb, int bi) { 148 return makeShort(bb._get(bi + 1), 149 bb._get(bi + 0)); 150 } 151 152 static short getShortL(long a) { 153 return makeShort(_get(a + 1), 154 _get(a)); 155 } 156 157 static short getShortB(ByteBuffer bb, int bi) { 158 return makeShort(bb._get(bi + 0), 159 bb._get(bi + 1)); 160 } 161 162 static short getShortB(long a) { 163 return makeShort(_get(a), 164 _get(a + 1)); 165 } 166 167 static short getShort(ByteBuffer bb, int bi, boolean bigEndian) { 168 return (bigEndian ? getShortB(bb, bi) : getShortL(bb, bi)); 169 } 170 171 static short getShort(long a, boolean bigEndian) { 172 return (bigEndian ? getShortB(a) : getShortL(a)); 173 } 174 175 private static byte short1(short x) { return (byte)(x >> 8); } 176 private static byte short0(short x) { return (byte)(x >> 0); } 177 178 static void putShortL(ByteBuffer bb, int bi, short x) { 179 bb._put(bi + 0, short0(x)); 180 bb._put(bi + 1, short1(x)); 181 } 182 183 static void putShortL(long a, short x) { 184 _put(a, short0(x)); 185 _put(a + 1, short1(x)); 186 } 187 188 static void putShortB(ByteBuffer bb, int bi, short x) { 189 bb._put(bi + 0, short1(x)); 190 bb._put(bi + 1, short0(x)); 191 } 192 193 static void putShortB(long a, short x) { 194 _put(a, short1(x)); 195 _put(a + 1, short0(x)); 196 } 197 198 static void putShort(ByteBuffer bb, int bi, short x, boolean bigEndian) { 199 if (bigEndian) 200 putShortB(bb, bi, x); 201 else 202 putShortL(bb, bi, x); 203 } 204 205 static void putShort(long a, short x, boolean bigEndian) { 206 if (bigEndian) 207 putShortB(a, x); 208 else 209 putShortL(a, x); 210 } 211 212 213 // -- get/put int -- 214 215 static private int makeInt(byte b3, byte b2, byte b1, byte b0) { 216 return (((b3 & 0xff) << 24) | 217 ((b2 & 0xff) << 16) | 218 ((b1 & 0xff) << 8) | 219 ((b0 & 0xff) << 0)); 220 } 221 222 static int getIntL(ByteBuffer bb, int bi) { 223 return makeInt(bb._get(bi + 3), 224 bb._get(bi + 2), 225 bb._get(bi + 1), 226 bb._get(bi + 0)); 227 } 228 229 static int getIntL(long a) { 230 return makeInt(_get(a + 3), 231 _get(a + 2), 232 _get(a + 1), 233 _get(a + 0)); 234 } 235 236 static int getIntB(ByteBuffer bb, int bi) { 237 return makeInt(bb._get(bi + 0), 238 bb._get(bi + 1), 239 bb._get(bi + 2), 240 bb._get(bi + 3)); 241 } 242 243 static int getIntB(long a) { 244 return makeInt(_get(a + 0), 245 _get(a + 1), 246 _get(a + 2), 247 _get(a + 3)); 248 } 249 250 static int getInt(ByteBuffer bb, int bi, boolean bigEndian) { 251 return (bigEndian ? getIntB(bb, bi) : getIntL(bb, bi)); 252 } 253 254 static int getInt(long a, boolean bigEndian) { 255 return (bigEndian ? getIntB(a) : getIntL(a)); 256 } 257 258 private static byte int3(int x) { return (byte)(x >> 24); } 259 private static byte int2(int x) { return (byte)(x >> 16); } 260 private static byte int1(int x) { return (byte)(x >> 8); } 261 private static byte int0(int x) { return (byte)(x >> 0); } 262 263 static void putIntL(ByteBuffer bb, int bi, int x) { 264 bb._put(bi + 3, int3(x)); 265 bb._put(bi + 2, int2(x)); 266 bb._put(bi + 1, int1(x)); 267 bb._put(bi + 0, int0(x)); 268 } 269 270 static void putIntL(long a, int x) { 271 _put(a + 3, int3(x)); 272 _put(a + 2, int2(x)); 273 _put(a + 1, int1(x)); 274 _put(a + 0, int0(x)); 275 } 276 277 static void putIntB(ByteBuffer bb, int bi, int x) { 278 bb._put(bi + 0, int3(x)); 279 bb._put(bi + 1, int2(x)); 280 bb._put(bi + 2, int1(x)); 281 bb._put(bi + 3, int0(x)); 282 } 283 284 static void putIntB(long a, int x) { 285 _put(a + 0, int3(x)); 286 _put(a + 1, int2(x)); 287 _put(a + 2, int1(x)); 288 _put(a + 3, int0(x)); 289 } 290 291 static void putInt(ByteBuffer bb, int bi, int x, boolean bigEndian) { 292 if (bigEndian) 293 putIntB(bb, bi, x); 294 else 295 putIntL(bb, bi, x); 296 } 297 298 static void putInt(long a, int x, boolean bigEndian) { 299 if (bigEndian) 300 putIntB(a, x); 301 else 302 putIntL(a, x); 303 } 304 305 306 // -- get/put long -- 307 308 static private long makeLong(byte b7, byte b6, byte b5, byte b4, 309 byte b3, byte b2, byte b1, byte b0) 310 { 311 return ((((long)b7 & 0xff) << 56) | 312 (((long)b6 & 0xff) << 48) | 313 (((long)b5 & 0xff) << 40) | 314 (((long)b4 & 0xff) << 32) | 315 (((long)b3 & 0xff) << 24) | 316 (((long)b2 & 0xff) << 16) | 317 (((long)b1 & 0xff) << 8) | 318 (((long)b0 & 0xff) << 0)); 319 } 320 321 static long getLongL(ByteBuffer bb, int bi) { 322 return makeLong(bb._get(bi + 7), 323 bb._get(bi + 6), 324 bb._get(bi + 5), 325 bb._get(bi + 4), 326 bb._get(bi + 3), 327 bb._get(bi + 2), 328 bb._get(bi + 1), 329 bb._get(bi + 0)); 330 } 331 332 static long getLongL(long a) { 333 return makeLong(_get(a + 7), 334 _get(a + 6), 335 _get(a + 5), 336 _get(a + 4), 337 _get(a + 3), 338 _get(a + 2), 339 _get(a + 1), 340 _get(a + 0)); 341 } 342 343 static long getLongB(ByteBuffer bb, int bi) { 344 return makeLong(bb._get(bi + 0), 345 bb._get(bi + 1), 346 bb._get(bi + 2), 347 bb._get(bi + 3), 348 bb._get(bi + 4), 349 bb._get(bi + 5), 350 bb._get(bi + 6), 351 bb._get(bi + 7)); 352 } 353 354 static long getLongB(long a) { 355 return makeLong(_get(a + 0), 356 _get(a + 1), 357 _get(a + 2), 358 _get(a + 3), 359 _get(a + 4), 360 _get(a + 5), 361 _get(a + 6), 362 _get(a + 7)); 363 } 364 365 static long getLong(ByteBuffer bb, int bi, boolean bigEndian) { 366 return (bigEndian ? getLongB(bb, bi) : getLongL(bb, bi)); 367 } 368 369 static long getLong(long a, boolean bigEndian) { 370 return (bigEndian ? getLongB(a) : getLongL(a)); 371 } 372 373 private static byte long7(long x) { return (byte)(x >> 56); } 374 private static byte long6(long x) { return (byte)(x >> 48); } 375 private static byte long5(long x) { return (byte)(x >> 40); } 376 private static byte long4(long x) { return (byte)(x >> 32); } 377 private static byte long3(long x) { return (byte)(x >> 24); } 378 private static byte long2(long x) { return (byte)(x >> 16); } 379 private static byte long1(long x) { return (byte)(x >> 8); } 380 private static byte long0(long x) { return (byte)(x >> 0); } 381 382 static void putLongL(ByteBuffer bb, int bi, long x) { 383 bb._put(bi + 7, long7(x)); 384 bb._put(bi + 6, long6(x)); 385 bb._put(bi + 5, long5(x)); 386 bb._put(bi + 4, long4(x)); 387 bb._put(bi + 3, long3(x)); 388 bb._put(bi + 2, long2(x)); 389 bb._put(bi + 1, long1(x)); 390 bb._put(bi + 0, long0(x)); 391 } 392 393 static void putLongL(long a, long x) { 394 _put(a + 7, long7(x)); 395 _put(a + 6, long6(x)); 396 _put(a + 5, long5(x)); 397 _put(a + 4, long4(x)); 398 _put(a + 3, long3(x)); 399 _put(a + 2, long2(x)); 400 _put(a + 1, long1(x)); 401 _put(a + 0, long0(x)); 402 } 403 404 static void putLongB(ByteBuffer bb, int bi, long x) { 405 bb._put(bi + 0, long7(x)); 406 bb._put(bi + 1, long6(x)); 407 bb._put(bi + 2, long5(x)); 408 bb._put(bi + 3, long4(x)); 409 bb._put(bi + 4, long3(x)); 410 bb._put(bi + 5, long2(x)); 411 bb._put(bi + 6, long1(x)); 412 bb._put(bi + 7, long0(x)); 413 } 414 415 static void putLongB(long a, long x) { 416 _put(a + 0, long7(x)); 417 _put(a + 1, long6(x)); 418 _put(a + 2, long5(x)); 419 _put(a + 3, long4(x)); 420 _put(a + 4, long3(x)); 421 _put(a + 5, long2(x)); 422 _put(a + 6, long1(x)); 423 _put(a + 7, long0(x)); 424 } 425 426 static void putLong(ByteBuffer bb, int bi, long x, boolean bigEndian) { 427 if (bigEndian) 428 putLongB(bb, bi, x); 429 else 430 putLongL(bb, bi, x); 431 } 432 433 static void putLong(long a, long x, boolean bigEndian) { 434 if (bigEndian) 435 putLongB(a, x); 436 else 437 putLongL(a, x); 438 } 439 440 441 // -- get/put float -- 442 443 static float getFloatL(ByteBuffer bb, int bi) { 444 return Float.intBitsToFloat(getIntL(bb, bi)); 445 } 446 447 static float getFloatL(long a) { 448 return Float.intBitsToFloat(getIntL(a)); 449 } 450 451 static float getFloatB(ByteBuffer bb, int bi) { 452 return Float.intBitsToFloat(getIntB(bb, bi)); 453 } 454 455 static float getFloatB(long a) { 456 return Float.intBitsToFloat(getIntB(a)); 457 } 458 459 static float getFloat(ByteBuffer bb, int bi, boolean bigEndian) { 460 return (bigEndian ? getFloatB(bb, bi) : getFloatL(bb, bi)); 461 } 462 463 static float getFloat(long a, boolean bigEndian) { 464 return (bigEndian ? getFloatB(a) : getFloatL(a)); 465 } 466 467 static void putFloatL(ByteBuffer bb, int bi, float x) { 468 putIntL(bb, bi, Float.floatToRawIntBits(x)); 469 } 470 471 static void putFloatL(long a, float x) { 472 putIntL(a, Float.floatToRawIntBits(x)); 473 } 474 475 static void putFloatB(ByteBuffer bb, int bi, float x) { 476 putIntB(bb, bi, Float.floatToRawIntBits(x)); 477 } 478 479 static void putFloatB(long a, float x) { 480 putIntB(a, Float.floatToRawIntBits(x)); 481 } 482 483 static void putFloat(ByteBuffer bb, int bi, float x, boolean bigEndian) { 484 if (bigEndian) 485 putFloatB(bb, bi, x); 486 else 487 putFloatL(bb, bi, x); 488 } 489 490 static void putFloat(long a, float x, boolean bigEndian) { 491 if (bigEndian) 492 putFloatB(a, x); 493 else 494 putFloatL(a, x); 495 } 496 497 498 // -- get/put double -- 499 500 static double getDoubleL(ByteBuffer bb, int bi) { 501 return Double.longBitsToDouble(getLongL(bb, bi)); 502 } 503 504 static double getDoubleL(long a) { 505 return Double.longBitsToDouble(getLongL(a)); 506 } 507 508 static double getDoubleB(ByteBuffer bb, int bi) { 509 return Double.longBitsToDouble(getLongB(bb, bi)); 510 } 511 512 static double getDoubleB(long a) { 513 return Double.longBitsToDouble(getLongB(a)); 514 } 515 516 static double getDouble(ByteBuffer bb, int bi, boolean bigEndian) { 517 return (bigEndian ? getDoubleB(bb, bi) : getDoubleL(bb, bi)); 518 } 519 520 static double getDouble(long a, boolean bigEndian) { 521 return (bigEndian ? getDoubleB(a) : getDoubleL(a)); 522 } 523 524 static void putDoubleL(ByteBuffer bb, int bi, double x) { 525 putLongL(bb, bi, Double.doubleToRawLongBits(x)); 526 } 527 528 static void putDoubleL(long a, double x) { 529 putLongL(a, Double.doubleToRawLongBits(x)); 530 } 531 532 static void putDoubleB(ByteBuffer bb, int bi, double x) { 533 putLongB(bb, bi, Double.doubleToRawLongBits(x)); 534 } 535 536 static void putDoubleB(long a, double x) { 537 putLongB(a, Double.doubleToRawLongBits(x)); 538 } 539 540 static void putDouble(ByteBuffer bb, int bi, double x, boolean bigEndian) { 541 if (bigEndian) 542 putDoubleB(bb, bi, x); 543 else 544 putDoubleL(bb, bi, x); 545 } 546 547 static void putDouble(long a, double x, boolean bigEndian) { 548 if (bigEndian) 549 putDoubleB(a, x); 550 else 551 putDoubleL(a, x); 552 } 553 554 555 // -- Unsafe access -- 556 557 private static final Unsafe unsafe = Unsafe.getUnsafe(); 558 559 private static byte _get(long a) { 560 return unsafe.getByte(a); 561 } 562 563 private static void _put(long a, byte b) { 564 unsafe.putByte(a, b); 565 } 566 567 static Unsafe unsafe() { 568 return unsafe; 569 } 570 571 572 // -- Processor and memory-system properties -- 573 574 private static final ByteOrder byteOrder; 575 576 static ByteOrder byteOrder() { 577 if (byteOrder == null) 578 throw new Error("Unknown byte order"); 579 return byteOrder; 580 } 581 582 static { 583 long a = unsafe.allocateMemory(8); 584 try { 585 unsafe.putLong(a, 0x0102030405060708L); 586 byte b = unsafe.getByte(a); 587 switch (b) { 588 case 0x01: byteOrder = ByteOrder.BIG_ENDIAN; break; 589 case 0x08: byteOrder = ByteOrder.LITTLE_ENDIAN; break; 590 default: 591 assert false; 592 byteOrder = null; 593 } 594 } finally { 595 unsafe.freeMemory(a); 596 } 597 } 598 599 600 private static int pageSize = -1; 601 602 static int pageSize() { 603 if (pageSize == -1) 604 pageSize = unsafe().pageSize(); 605 return pageSize; 606 } 607 608 609 private static boolean unaligned; 610 private static boolean unalignedKnown = false; 611 612 static boolean unaligned() { 613 if (unalignedKnown) 614 return unaligned; 615 String arch = AccessController.doPrivileged( 616 new sun.security.action.GetPropertyAction("os.arch")); 617 unaligned = arch.equals("i386") || arch.equals("x86") 618 || arch.equals("amd64"); 619 unalignedKnown = true; 620 return unaligned; 621 } 622 623 624 // -- Direct memory management -- 625 626 // A user-settable upper limit on the maximum amount of allocatable 627 // direct buffer memory. This value may be changed during VM 628 // initialization if it is launched with "-XX:MaxDirectMemorySize=<size>". 629 private static volatile long maxMemory = VM.maxDirectMemory(); 630 private static volatile long reservedMemory; 631 private static volatile long usedMemory; 632 private static volatile long count; 633 private static boolean memoryLimitSet = false; 634 635 // These methods should be called whenever direct memory is allocated or 636 // freed. They allow the user to control the amount of direct memory 637 // which a process may access. All sizes are specified in bytes. 638 static void reserveMemory(long size, int cap) { 639 640 synchronized (Bits.class) { 641 if (!memoryLimitSet && VM.isBooted()) { 642 maxMemory = VM.maxDirectMemory(); 643 memoryLimitSet = true; 644 } 645 if (size <= maxMemory - reservedMemory) { 646 reservedMemory += size; 647 usedMemory += cap; 648 count++; 649 return; 650 } 651 } 652 653 System.gc(); 654 try { 655 Thread.sleep(100); 656 } catch (InterruptedException x) { 657 // Restore interrupt status 658 Thread.currentThread().interrupt(); 659 } 660 synchronized (Bits.class) { 661 if (reservedMemory + size > maxMemory) 662 throw new OutOfMemoryError("Direct buffer memory"); 663 reservedMemory += size; 664 usedMemory += cap; 665 count++; 666 } 667 668 } 669 670 static synchronized void unreserveMemory(long size, int cap) { 671 if (reservedMemory > 0) { 672 reservedMemory -= size; 673 usedMemory -= cap; 674 count--; 675 assert (reservedMemory > -1); 676 } 677 } 678 679 // -- Management interface for monitoring of direct buffer usage -- 680 681 static { 682 // setup access to this package in SharedSecrets 683 sun.misc.SharedSecrets.setJavaNioAccess( 684 new sun.misc.JavaNioAccess() { 685 @Override 686 public BufferPoolMXBean getDirectBufferPoolMXBean() { 687 return LazyInitialization.directBufferPoolMXBean; 688 } 689 } 690 ); 691 } 692 693 // Lazy initialization of management interface 694 private static class LazyInitialization { 695 static final BufferPoolMXBean directBufferPoolMXBean = directBufferPoolMXBean(); 696 697 private static BufferPoolMXBean directBufferPoolMXBean() { 698 final String pool = "direct"; 699 final ObjectName obj; 700 try { 701 obj = new ObjectName("java.nio:type=BufferPool,name=" + pool); 702 } catch (MalformedObjectNameException x) { 703 throw new AssertionError(x); 704 } 705 return new BufferPoolMXBean() { 706 @Override 707 public ObjectName getObjectName() { 708 return obj; 709 } 710 @Override 711 public String getName() { 712 return pool; 713 } 714 @Override 715 public long getCount() { 716 return Bits.count; 717 } 718 @Override 719 public long getTotalCapacity() { 720 return Bits.usedMemory; 721 } 722 @Override 723 public long getMemoryUsed() { 724 return Bits.reservedMemory; 725 } 726 }; 727 } 728 } 729 730 // -- Bulk get/put acceleration -- 731 732 // These numbers represent the point at which we have empirically 733 // determined that the average cost of a JNI call exceeds the expense 734 // of an element by element copy. These numbers may change over time. 735 static final int JNI_COPY_TO_ARRAY_THRESHOLD = 6; 736 static final int JNI_COPY_FROM_ARRAY_THRESHOLD = 6; 737 738 // This number limits the number of bytes to copy per call to Unsafe's 739 // copyMemory method. A limit is imposed to allow for safepoint polling 740 // during a large copy 741 static final long UNSAFE_COPY_THRESHOLD = 1024L * 1024L; 742 743 // These methods do no bounds checking. Verification that the copy will not 744 // result in memory corruption should be done prior to invocation. 745 // All positions and lengths are specified in bytes. 746 747 /** 748 * Copy from given source array to destination address. 749 * 750 * @param src 751 * source array 752 * @param srcBaseOffset 753 * offset of first element of storage in source array 754 * @param srcPos 755 * offset within source array of the first element to read 756 * @param dstAddr 757 * destination address 758 * @param length 759 * number of bytes to copy 760 */ 761 static void copyFromArray(Object src, long srcBaseOffset, long srcPos, 762 long dstAddr, long length) 763 { 764 long offset = srcBaseOffset + srcPos; 765 while (length > 0) { 766 long size = (length > UNSAFE_COPY_THRESHOLD) ? UNSAFE_COPY_THRESHOLD : length; 767 unsafe.copyMemory(src, offset, null, dstAddr, size); 768 length -= size; 769 offset += size; 770 dstAddr += size; 771 } 772 } 773 774 /** 775 * Copy from source address into given destination array. 776 * 777 * @param srcAddr 778 * source address 779 * @param dst 780 * destination array 781 * @param dstBaseOffset 782 * offset of first element of storage in destination array 783 * @param dstPos 784 * offset within destination array of the first element to write 785 * @param length 786 * number of bytes to copy 787 */ 788 static void copyToArray(long srcAddr, Object dst, long dstBaseOffset, long dstPos, 789 long length) 790 { 791 long offset = dstBaseOffset + dstPos; 792 while (length > 0) { 793 long size = (length > UNSAFE_COPY_THRESHOLD) ? UNSAFE_COPY_THRESHOLD : length; 794 unsafe.copyMemory(null, srcAddr, dst, offset, size); 795 length -= size; 796 srcAddr += size; 797 offset += size; 798 } 799 } 800 801 static void copyFromCharArray(Object src, long srcPos, long dstAddr, 802 long length) 803 { 804 copyFromShortArray(src, srcPos, dstAddr, length); 805 } 806 807 static void copyToCharArray(long srcAddr, Object dst, long dstPos, 808 long length) 809 { 810 copyToShortArray(srcAddr, dst, dstPos, length); 811 } 812 813 static native void copyFromShortArray(Object src, long srcPos, long dstAddr, 814 long length); 815 static native void copyToShortArray(long srcAddr, Object dst, long dstPos, 816 long length); 817 818 static native void copyFromIntArray(Object src, long srcPos, long dstAddr, 819 long length); 820 static native void copyToIntArray(long srcAddr, Object dst, long dstPos, 821 long length); 822 823 static native void copyFromLongArray(Object src, long srcPos, long dstAddr, 824 long length); 825 static native void copyToLongArray(long srcAddr, Object dst, long dstPos, 826 long length); 827 828 }