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