1 /* 2 * Copyright (c) 2000, 2016, 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 package java.nio; 27 28 import java.util.concurrent.atomic.AtomicLong; 29 import java.util.concurrent.locks.ReentrantLock; 30 31 import jdk.internal.misc.*; 32 import jdk.internal.ref.CleanerFactory; 33 34 /** 35 * Access to bits, native and otherwise. 36 */ 37 38 class Bits { // package-private 39 40 private Bits() { } 41 42 43 // -- Swapping -- 44 45 static short swap(short x) { 46 return Short.reverseBytes(x); 47 } 48 49 static char swap(char x) { 50 return Character.reverseBytes(x); 51 } 52 53 static int swap(int x) { 54 return Integer.reverseBytes(x); 55 } 56 57 static long swap(long x) { 58 return Long.reverseBytes(x); 59 } 60 61 62 // -- get/put char -- 63 64 private static char makeChar(byte b1, byte b0) { 65 return (char)((b1 << 8) | (b0 & 0xff)); 66 } 67 68 static char getCharL(ByteBuffer bb, int bi) { 69 return makeChar(bb._get(bi + 1), 70 bb._get(bi )); 71 } 72 73 static char getCharL(long a) { 74 return makeChar(_get(a + 1), 75 _get(a )); 76 } 77 78 static char getCharB(ByteBuffer bb, int bi) { 79 return makeChar(bb._get(bi ), 80 bb._get(bi + 1)); 81 } 82 83 static char getCharB(long a) { 84 return makeChar(_get(a ), 85 _get(a + 1)); 86 } 87 88 static char getChar(ByteBuffer bb, int bi, boolean bigEndian) { 89 return bigEndian ? getCharB(bb, bi) : getCharL(bb, bi); 90 } 91 92 static char getChar(long a, boolean bigEndian) { 93 return bigEndian ? getCharB(a) : getCharL(a); 94 } 95 96 private static byte char1(char x) { return (byte)(x >> 8); } 97 private static byte char0(char x) { return (byte)(x ); } 98 99 static void putCharL(ByteBuffer bb, int bi, char x) { 100 bb._put(bi , char0(x)); 101 bb._put(bi + 1, char1(x)); 102 } 103 104 static void putCharL(long a, char x) { 105 _put(a , char0(x)); 106 _put(a + 1, char1(x)); 107 } 108 109 static void putCharB(ByteBuffer bb, int bi, char x) { 110 bb._put(bi , char1(x)); 111 bb._put(bi + 1, char0(x)); 112 } 113 114 static void putCharB(long a, char x) { 115 _put(a , char1(x)); 116 _put(a + 1, char0(x)); 117 } 118 119 static void putChar(ByteBuffer bb, int bi, char x, boolean bigEndian) { 120 if (bigEndian) 121 putCharB(bb, bi, x); 122 else 123 putCharL(bb, bi, x); 124 } 125 126 static void putChar(long a, char x, boolean bigEndian) { 127 if (bigEndian) 128 putCharB(a, x); 129 else 130 putCharL(a, x); 131 } 132 133 134 // -- get/put short -- 135 136 private static short makeShort(byte b1, byte b0) { 137 return (short)((b1 << 8) | (b0 & 0xff)); 138 } 139 140 static short getShortL(ByteBuffer bb, int bi) { 141 return makeShort(bb._get(bi + 1), 142 bb._get(bi )); 143 } 144 145 static short getShortL(long a) { 146 return makeShort(_get(a + 1), 147 _get(a )); 148 } 149 150 static short getShortB(ByteBuffer bb, int bi) { 151 return makeShort(bb._get(bi ), 152 bb._get(bi + 1)); 153 } 154 155 static short getShortB(long a) { 156 return makeShort(_get(a ), 157 _get(a + 1)); 158 } 159 160 static short getShort(ByteBuffer bb, int bi, boolean bigEndian) { 161 return bigEndian ? getShortB(bb, bi) : getShortL(bb, bi); 162 } 163 164 static short getShort(long a, boolean bigEndian) { 165 return bigEndian ? getShortB(a) : getShortL(a); 166 } 167 168 private static byte short1(short x) { return (byte)(x >> 8); } 169 private static byte short0(short x) { return (byte)(x ); } 170 171 static void putShortL(ByteBuffer bb, int bi, short x) { 172 bb._put(bi , short0(x)); 173 bb._put(bi + 1, short1(x)); 174 } 175 176 static void putShortL(long a, short x) { 177 _put(a , short0(x)); 178 _put(a + 1, short1(x)); 179 } 180 181 static void putShortB(ByteBuffer bb, int bi, short x) { 182 bb._put(bi , short1(x)); 183 bb._put(bi + 1, short0(x)); 184 } 185 186 static void putShortB(long a, short x) { 187 _put(a , short1(x)); 188 _put(a + 1, short0(x)); 189 } 190 191 static void putShort(ByteBuffer bb, int bi, short x, boolean bigEndian) { 192 if (bigEndian) 193 putShortB(bb, bi, x); 194 else 195 putShortL(bb, bi, x); 196 } 197 198 static void putShort(long a, short x, boolean bigEndian) { 199 if (bigEndian) 200 putShortB(a, x); 201 else 202 putShortL(a, x); 203 } 204 205 206 // -- get/put int -- 207 208 private static int makeInt(byte b3, byte b2, byte b1, byte b0) { 209 return (((b3 ) << 24) | 210 ((b2 & 0xff) << 16) | 211 ((b1 & 0xff) << 8) | 212 ((b0 & 0xff) )); 213 } 214 215 static int getIntL(ByteBuffer bb, int bi) { 216 return makeInt(bb._get(bi + 3), 217 bb._get(bi + 2), 218 bb._get(bi + 1), 219 bb._get(bi )); 220 } 221 222 static int getIntL(long a) { 223 return makeInt(_get(a + 3), 224 _get(a + 2), 225 _get(a + 1), 226 _get(a )); 227 } 228 229 static int getIntB(ByteBuffer bb, int bi) { 230 return makeInt(bb._get(bi ), 231 bb._get(bi + 1), 232 bb._get(bi + 2), 233 bb._get(bi + 3)); 234 } 235 236 static int getIntB(long a) { 237 return makeInt(_get(a ), 238 _get(a + 1), 239 _get(a + 2), 240 _get(a + 3)); 241 } 242 243 static int getInt(ByteBuffer bb, int bi, boolean bigEndian) { 244 return bigEndian ? getIntB(bb, bi) : getIntL(bb, bi) ; 245 } 246 247 static int getInt(long a, boolean bigEndian) { 248 return bigEndian ? getIntB(a) : getIntL(a) ; 249 } 250 251 private static byte int3(int x) { return (byte)(x >> 24); } 252 private static byte int2(int x) { return (byte)(x >> 16); } 253 private static byte int1(int x) { return (byte)(x >> 8); } 254 private static byte int0(int x) { return (byte)(x ); } 255 256 static void putIntL(ByteBuffer bb, int bi, int x) { 257 bb._put(bi + 3, int3(x)); 258 bb._put(bi + 2, int2(x)); 259 bb._put(bi + 1, int1(x)); 260 bb._put(bi , int0(x)); 261 } 262 263 static void putIntL(long a, int x) { 264 _put(a + 3, int3(x)); 265 _put(a + 2, int2(x)); 266 _put(a + 1, int1(x)); 267 _put(a , int0(x)); 268 } 269 270 static void putIntB(ByteBuffer bb, int bi, int x) { 271 bb._put(bi , int3(x)); 272 bb._put(bi + 1, int2(x)); 273 bb._put(bi + 2, int1(x)); 274 bb._put(bi + 3, int0(x)); 275 } 276 277 static void putIntB(long a, int x) { 278 _put(a , int3(x)); 279 _put(a + 1, int2(x)); 280 _put(a + 2, int1(x)); 281 _put(a + 3, int0(x)); 282 } 283 284 static void putInt(ByteBuffer bb, int bi, int x, boolean bigEndian) { 285 if (bigEndian) 286 putIntB(bb, bi, x); 287 else 288 putIntL(bb, bi, x); 289 } 290 291 static void putInt(long a, int x, boolean bigEndian) { 292 if (bigEndian) 293 putIntB(a, x); 294 else 295 putIntL(a, x); 296 } 297 298 299 // -- get/put long -- 300 301 private static long makeLong(byte b7, byte b6, byte b5, byte b4, 302 byte b3, byte b2, byte b1, byte b0) 303 { 304 return ((((long)b7 ) << 56) | 305 (((long)b6 & 0xff) << 48) | 306 (((long)b5 & 0xff) << 40) | 307 (((long)b4 & 0xff) << 32) | 308 (((long)b3 & 0xff) << 24) | 309 (((long)b2 & 0xff) << 16) | 310 (((long)b1 & 0xff) << 8) | 311 (((long)b0 & 0xff) )); 312 } 313 314 static long getLongL(ByteBuffer bb, int bi) { 315 return makeLong(bb._get(bi + 7), 316 bb._get(bi + 6), 317 bb._get(bi + 5), 318 bb._get(bi + 4), 319 bb._get(bi + 3), 320 bb._get(bi + 2), 321 bb._get(bi + 1), 322 bb._get(bi )); 323 } 324 325 static long getLongL(long a) { 326 return makeLong(_get(a + 7), 327 _get(a + 6), 328 _get(a + 5), 329 _get(a + 4), 330 _get(a + 3), 331 _get(a + 2), 332 _get(a + 1), 333 _get(a )); 334 } 335 336 static long getLongB(ByteBuffer bb, int bi) { 337 return makeLong(bb._get(bi ), 338 bb._get(bi + 1), 339 bb._get(bi + 2), 340 bb._get(bi + 3), 341 bb._get(bi + 4), 342 bb._get(bi + 5), 343 bb._get(bi + 6), 344 bb._get(bi + 7)); 345 } 346 347 static long getLongB(long a) { 348 return makeLong(_get(a ), 349 _get(a + 1), 350 _get(a + 2), 351 _get(a + 3), 352 _get(a + 4), 353 _get(a + 5), 354 _get(a + 6), 355 _get(a + 7)); 356 } 357 358 static long getLong(ByteBuffer bb, int bi, boolean bigEndian) { 359 return bigEndian ? getLongB(bb, bi) : getLongL(bb, bi); 360 } 361 362 static long getLong(long a, boolean bigEndian) { 363 return bigEndian ? getLongB(a) : getLongL(a); 364 } 365 366 private static byte long7(long x) { return (byte)(x >> 56); } 367 private static byte long6(long x) { return (byte)(x >> 48); } 368 private static byte long5(long x) { return (byte)(x >> 40); } 369 private static byte long4(long x) { return (byte)(x >> 32); } 370 private static byte long3(long x) { return (byte)(x >> 24); } 371 private static byte long2(long x) { return (byte)(x >> 16); } 372 private static byte long1(long x) { return (byte)(x >> 8); } 373 private static byte long0(long x) { return (byte)(x ); } 374 375 static void putLongL(ByteBuffer bb, int bi, long x) { 376 bb._put(bi + 7, long7(x)); 377 bb._put(bi + 6, long6(x)); 378 bb._put(bi + 5, long5(x)); 379 bb._put(bi + 4, long4(x)); 380 bb._put(bi + 3, long3(x)); 381 bb._put(bi + 2, long2(x)); 382 bb._put(bi + 1, long1(x)); 383 bb._put(bi , long0(x)); 384 } 385 386 static void putLongL(long a, long x) { 387 _put(a + 7, long7(x)); 388 _put(a + 6, long6(x)); 389 _put(a + 5, long5(x)); 390 _put(a + 4, long4(x)); 391 _put(a + 3, long3(x)); 392 _put(a + 2, long2(x)); 393 _put(a + 1, long1(x)); 394 _put(a , long0(x)); 395 } 396 397 static void putLongB(ByteBuffer bb, int bi, long x) { 398 bb._put(bi , long7(x)); 399 bb._put(bi + 1, long6(x)); 400 bb._put(bi + 2, long5(x)); 401 bb._put(bi + 3, long4(x)); 402 bb._put(bi + 4, long3(x)); 403 bb._put(bi + 5, long2(x)); 404 bb._put(bi + 6, long1(x)); 405 bb._put(bi + 7, long0(x)); 406 } 407 408 static void putLongB(long a, long x) { 409 _put(a , long7(x)); 410 _put(a + 1, long6(x)); 411 _put(a + 2, long5(x)); 412 _put(a + 3, long4(x)); 413 _put(a + 4, long3(x)); 414 _put(a + 5, long2(x)); 415 _put(a + 6, long1(x)); 416 _put(a + 7, long0(x)); 417 } 418 419 static void putLong(ByteBuffer bb, int bi, long x, boolean bigEndian) { 420 if (bigEndian) 421 putLongB(bb, bi, x); 422 else 423 putLongL(bb, bi, x); 424 } 425 426 static void putLong(long a, long x, boolean bigEndian) { 427 if (bigEndian) 428 putLongB(a, x); 429 else 430 putLongL(a, x); 431 } 432 433 434 // -- get/put float -- 435 436 static float getFloatL(ByteBuffer bb, int bi) { 437 return Float.intBitsToFloat(getIntL(bb, bi)); 438 } 439 440 static float getFloatL(long a) { 441 return Float.intBitsToFloat(getIntL(a)); 442 } 443 444 static float getFloatB(ByteBuffer bb, int bi) { 445 return Float.intBitsToFloat(getIntB(bb, bi)); 446 } 447 448 static float getFloatB(long a) { 449 return Float.intBitsToFloat(getIntB(a)); 450 } 451 452 static float getFloat(ByteBuffer bb, int bi, boolean bigEndian) { 453 return bigEndian ? getFloatB(bb, bi) : getFloatL(bb, bi); 454 } 455 456 static float getFloat(long a, boolean bigEndian) { 457 return bigEndian ? getFloatB(a) : getFloatL(a); 458 } 459 460 static void putFloatL(ByteBuffer bb, int bi, float x) { 461 putIntL(bb, bi, Float.floatToRawIntBits(x)); 462 } 463 464 static void putFloatL(long a, float x) { 465 putIntL(a, Float.floatToRawIntBits(x)); 466 } 467 468 static void putFloatB(ByteBuffer bb, int bi, float x) { 469 putIntB(bb, bi, Float.floatToRawIntBits(x)); 470 } 471 472 static void putFloatB(long a, float x) { 473 putIntB(a, Float.floatToRawIntBits(x)); 474 } 475 476 static void putFloat(ByteBuffer bb, int bi, float x, boolean bigEndian) { 477 if (bigEndian) 478 putFloatB(bb, bi, x); 479 else 480 putFloatL(bb, bi, x); 481 } 482 483 static void putFloat(long a, float x, boolean bigEndian) { 484 if (bigEndian) 485 putFloatB(a, x); 486 else 487 putFloatL(a, x); 488 } 489 490 491 // -- get/put double -- 492 493 static double getDoubleL(ByteBuffer bb, int bi) { 494 return Double.longBitsToDouble(getLongL(bb, bi)); 495 } 496 497 static double getDoubleL(long a) { 498 return Double.longBitsToDouble(getLongL(a)); 499 } 500 501 static double getDoubleB(ByteBuffer bb, int bi) { 502 return Double.longBitsToDouble(getLongB(bb, bi)); 503 } 504 505 static double getDoubleB(long a) { 506 return Double.longBitsToDouble(getLongB(a)); 507 } 508 509 static double getDouble(ByteBuffer bb, int bi, boolean bigEndian) { 510 return bigEndian ? getDoubleB(bb, bi) : getDoubleL(bb, bi); 511 } 512 513 static double getDouble(long a, boolean bigEndian) { 514 return bigEndian ? getDoubleB(a) : getDoubleL(a); 515 } 516 517 static void putDoubleL(ByteBuffer bb, int bi, double x) { 518 putLongL(bb, bi, Double.doubleToRawLongBits(x)); 519 } 520 521 static void putDoubleL(long a, double x) { 522 putLongL(a, Double.doubleToRawLongBits(x)); 523 } 524 525 static void putDoubleB(ByteBuffer bb, int bi, double x) { 526 putLongB(bb, bi, Double.doubleToRawLongBits(x)); 527 } 528 529 static void putDoubleB(long a, double x) { 530 putLongB(a, Double.doubleToRawLongBits(x)); 531 } 532 533 static void putDouble(ByteBuffer bb, int bi, double x, boolean bigEndian) { 534 if (bigEndian) 535 putDoubleB(bb, bi, x); 536 else 537 putDoubleL(bb, bi, x); 538 } 539 540 static void putDouble(long a, double x, boolean bigEndian) { 541 if (bigEndian) 542 putDoubleB(a, x); 543 else 544 putDoubleL(a, x); 545 } 546 547 548 // -- Unsafe access -- 549 550 private static final Unsafe unsafe = Unsafe.getUnsafe(); 551 552 private static byte _get(long a) { 553 return unsafe.getByte(a); 554 } 555 556 private static void _put(long a, byte b) { 557 unsafe.putByte(a, b); 558 } 559 560 static Unsafe unsafe() { 561 return unsafe; 562 } 563 564 565 // -- Processor and memory-system properties -- 566 567 private static final ByteOrder byteOrder 568 = unsafe.isBigEndian() ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN; 569 570 static ByteOrder byteOrder() { 571 return byteOrder; 572 } 573 574 private static int pageSize = -1; 575 576 static int pageSize() { 577 if (pageSize == -1) 578 pageSize = unsafe().pageSize(); 579 return pageSize; 580 } 581 582 static int pageCount(long size) { 583 return (int)(size + (long)pageSize() - 1L) / pageSize(); 584 } 585 586 private static boolean unaligned = unsafe.unalignedAccess(); 587 588 static boolean unaligned() { 589 return unaligned; 590 } 591 592 593 // -- Direct memory management -- 594 595 // A user-settable upper limit on the maximum amount of allocatable 596 // direct buffer memory. This value may be changed during VM 597 // initialization if it is launched with "-XX:MaxDirectMemorySize=<size>". 598 private static volatile long maxMemory = VM.maxDirectMemory(); 599 private static final AtomicLong reservedMemory = new AtomicLong(); 600 private static final AtomicLong totalCapacity = new AtomicLong(); 601 private static final AtomicLong count = new AtomicLong(); 602 private static volatile boolean memoryLimitSet; 603 604 // max. number of sleeps during try-reserving with exponentially 605 // increasing delay before throwing OutOfMemoryError: 606 // 1, 2, 4, 8, 16, 32, 64, 128, 256 (total 511 ms ~ 0.5 s) 607 // which means that OOME will be thrown after 0.5 s of trying 608 private static final int MAX_SLEEPS = 9; 609 610 private static final ReentrantLock reservationQueue = new ReentrantLock(true); 611 612 // These methods should be called whenever direct memory is allocated or 613 // freed. They allow the user to control the amount of direct memory 614 // which a process may access. All sizes are specified in bytes. 615 static void reserveMemory(long size, int cap) { 616 617 if (!memoryLimitSet && VM.isBooted()) { 618 maxMemory = VM.maxDirectMemory(); 619 memoryLimitSet = true; 620 } 621 622 // optimist! 623 if (tryReserveMemory(size, cap)) { 624 return; 625 } 626 627 // reservation threads that don't succeed at first must queue so that 628 // some of them don't starve while others succeed. 629 reservationQueue.lock(); 630 try { 631 JavaLangRefAccess jlra = SharedSecrets.getJavaLangRefAccess(); 632 633 // retry reservation while helping the Cleaner thread process enqueued 634 // Cleanable(s) which includes the ones that free direct buffer memory 635 // until the queue drains out 636 do { 637 if (tryReserveMemory(size, cap)) { 638 return; 639 } 640 } while (jlra.cleanNextPendingCleanable(CleanerFactory.cleaner())); 641 642 // trigger GC's Reference discovery 643 System.gc(); 644 // make sure all newly discovered Reference(s) are enqueued 645 jlra.enqueuePendingReferences(); 646 647 // retry reservation while helping the Cleaner thread process enqueued 648 // Cleanable(s) which includes the ones that free direct buffer memory 649 // until the queue drains out 650 do { 651 if (tryReserveMemory(size, cap)) { 652 return; 653 } 654 } while (jlra.cleanNextPendingCleanable(CleanerFactory.cleaner())); 655 656 // no luck 657 throw new OutOfMemoryError("Direct buffer memory"); 658 } finally { 659 reservationQueue.unlock(); 660 } 661 } 662 663 private static boolean tryReserveMemory(long size, int cap) { 664 665 // -XX:MaxDirectMemorySize limits the total capacity rather than the 666 // actual memory usage, which will differ when buffers are page 667 // aligned. 668 long totalCap; 669 while (cap <= maxMemory - (totalCap = totalCapacity.get())) { 670 if (totalCapacity.compareAndSet(totalCap, totalCap + cap)) { 671 reservedMemory.addAndGet(size); 672 count.incrementAndGet(); 673 return true; 674 } 675 } 676 677 return false; 678 } 679 680 681 static void unreserveMemory(long size, int cap) { 682 long cnt = count.decrementAndGet(); 683 long reservedMem = reservedMemory.addAndGet(-size); 684 long totalCap = totalCapacity.addAndGet(-cap); 685 assert cnt >= 0 && reservedMem >= 0 && totalCap >= 0; 686 } 687 688 // -- Monitoring of direct buffer usage -- 689 690 static { 691 // setup access to this package in SharedSecrets 692 SharedSecrets.setJavaNioAccess( 693 new JavaNioAccess() { 694 @Override 695 public JavaNioAccess.BufferPool getDirectBufferPool() { 696 return new JavaNioAccess.BufferPool() { 697 @Override 698 public String getName() { 699 return "direct"; 700 } 701 @Override 702 public long getCount() { 703 return Bits.count.get(); 704 } 705 @Override 706 public long getTotalCapacity() { 707 return Bits.totalCapacity.get(); 708 } 709 @Override 710 public long getMemoryUsed() { 711 return Bits.reservedMemory.get(); 712 } 713 }; 714 } 715 @Override 716 public ByteBuffer newDirectByteBuffer(long addr, int cap, Object ob) { 717 return new DirectByteBuffer(addr, cap, ob); 718 } 719 @Override 720 public void truncate(Buffer buf) { 721 buf.truncate(); 722 } 723 }); 724 } 725 726 // -- Bulk get/put acceleration -- 727 728 // These numbers represent the point at which we have empirically 729 // determined that the average cost of a JNI call exceeds the expense 730 // of an element by element copy. These numbers may change over time. 731 static final int JNI_COPY_TO_ARRAY_THRESHOLD = 6; 732 static final int JNI_COPY_FROM_ARRAY_THRESHOLD = 6; 733 734 // This number limits the number of bytes to copy per call to Unsafe's 735 // copyMemory method. A limit is imposed to allow for safepoint polling 736 // during a large copy 737 static final long UNSAFE_COPY_THRESHOLD = 1024L * 1024L; 738 739 // These methods do no bounds checking. Verification that the copy will not 740 // result in memory corruption should be done prior to invocation. 741 // All positions and lengths are specified in bytes. 742 743 /** 744 * Copy from given source array to destination address. 745 * 746 * @param src 747 * source array 748 * @param srcBaseOffset 749 * offset of first element of storage in source array 750 * @param srcPos 751 * offset within source array of the first element to read 752 * @param dstAddr 753 * destination address 754 * @param length 755 * number of bytes to copy 756 */ 757 static void copyFromArray(Object src, long srcBaseOffset, long srcPos, 758 long dstAddr, long length) 759 { 760 long offset = srcBaseOffset + srcPos; 761 while (length > 0) { 762 long size = (length > UNSAFE_COPY_THRESHOLD) ? UNSAFE_COPY_THRESHOLD : length; 763 unsafe.copyMemory(src, offset, null, dstAddr, size); 764 length -= size; 765 offset += size; 766 dstAddr += size; 767 } 768 } 769 770 /** 771 * Copy from source address into given destination array. 772 * 773 * @param srcAddr 774 * source address 775 * @param dst 776 * destination array 777 * @param dstBaseOffset 778 * offset of first element of storage in destination array 779 * @param dstPos 780 * offset within destination array of the first element to write 781 * @param length 782 * number of bytes to copy 783 */ 784 static void copyToArray(long srcAddr, Object dst, long dstBaseOffset, long dstPos, 785 long length) 786 { 787 long offset = dstBaseOffset + dstPos; 788 while (length > 0) { 789 long size = (length > UNSAFE_COPY_THRESHOLD) ? UNSAFE_COPY_THRESHOLD : length; 790 unsafe.copyMemory(null, srcAddr, dst, offset, size); 791 length -= size; 792 srcAddr += size; 793 offset += size; 794 } 795 } 796 797 /** 798 * Copy and unconditionally byte swap 16 bit elements from a heap array to off-heap memory 799 * 800 * @param src 801 * the source array, must be a 16-bit primitive array type 802 * @param srcPos 803 * byte offset within source array of the first element to read 804 * @param dstAddr 805 * destination address 806 * @param length 807 * number of bytes to copy 808 */ 809 static void copyFromCharArray(Object src, long srcPos, long dstAddr, long length) { 810 unsafe.copySwapMemory(src, unsafe.arrayBaseOffset(src.getClass()) + srcPos, null, dstAddr, length, 2); 811 } 812 813 /** 814 * Copy and unconditionally byte swap 16 bit elements from off-heap memory to a heap array 815 * 816 * @param srcAddr 817 * source address 818 * @param dst 819 * destination array, must be a 16-bit primitive array type 820 * @param dstPos 821 * byte offset within the destination array of the first element to write 822 * @param length 823 * number of bytes to copy 824 */ 825 static void copyToCharArray(long srcAddr, Object dst, long dstPos, long length) { 826 unsafe.copySwapMemory(null, srcAddr, dst, unsafe.arrayBaseOffset(dst.getClass()) + dstPos, length, 2); 827 } 828 829 /** 830 * Copy and unconditionally byte swap 16 bit elements from a heap array to off-heap memory 831 * 832 * @param src 833 * the source array, must be a 16-bit primitive array type 834 * @param srcPos 835 * byte offset within source array of the first element to read 836 * @param dstAddr 837 * destination address 838 * @param length 839 * number of bytes to copy 840 */ 841 static void copyFromShortArray(Object src, long srcPos, long dstAddr, long length) { 842 unsafe.copySwapMemory(src, unsafe.arrayBaseOffset(src.getClass()) + srcPos, null, dstAddr, length, 2); 843 } 844 845 /** 846 * Copy and unconditionally byte swap 16 bit elements from off-heap memory to a heap array 847 * 848 * @param srcAddr 849 * source address 850 * @param dst 851 * destination array, must be a 16-bit primitive array type 852 * @param dstPos 853 * byte offset within the destination array of the first element to write 854 * @param length 855 * number of bytes to copy 856 */ 857 static void copyToShortArray(long srcAddr, Object dst, long dstPos, long length) { 858 unsafe.copySwapMemory(null, srcAddr, dst, unsafe.arrayBaseOffset(dst.getClass()) + dstPos, length, 2); 859 } 860 861 /** 862 * Copy and unconditionally byte swap 32 bit elements from a heap array to off-heap memory 863 * 864 * @param src 865 * the source array, must be a 32-bit primitive array type 866 * @param srcPos 867 * byte offset within source array of the first element to read 868 * @param dstAddr 869 * destination address 870 * @param length 871 * number of bytes to copy 872 */ 873 static void copyFromIntArray(Object src, long srcPos, long dstAddr, long length) { 874 unsafe.copySwapMemory(src, unsafe.arrayBaseOffset(src.getClass()) + srcPos, null, dstAddr, length, 4); 875 } 876 877 /** 878 * Copy and unconditionally byte swap 32 bit elements from off-heap memory to a heap array 879 * 880 * @param srcAddr 881 * source address 882 * @param dst 883 * destination array, must be a 32-bit primitive array type 884 * @param dstPos 885 * byte offset within the destination array of the first element to write 886 * @param length 887 * number of bytes to copy 888 */ 889 static void copyToIntArray(long srcAddr, Object dst, long dstPos, long length) { 890 unsafe.copySwapMemory(null, srcAddr, dst, unsafe.arrayBaseOffset(dst.getClass()) + dstPos, length, 4); 891 } 892 893 /** 894 * Copy and unconditionally byte swap 64 bit elements from a heap array to off-heap memory 895 * 896 * @param src 897 * the source array, must be a 64-bit primitive array type 898 * @param srcPos 899 * byte offset within source array of the first element to read 900 * @param dstAddr 901 * destination address 902 * @param length 903 * number of bytes to copy 904 */ 905 static void copyFromLongArray(Object src, long srcPos, long dstAddr, long length) { 906 unsafe.copySwapMemory(src, unsafe.arrayBaseOffset(src.getClass()) + srcPos, null, dstAddr, length, 8); 907 } 908 909 /** 910 * Copy and unconditionally byte swap 64 bit elements from off-heap memory to a heap array 911 * 912 * @param srcAddr 913 * source address 914 * @param dst 915 * destination array, must be a 64-bit primitive array type 916 * @param dstPos 917 * byte offset within the destination array of the first element to write 918 * @param length 919 * number of bytes to copy 920 */ 921 static void copyToLongArray(long srcAddr, Object dst, long dstPos, long length) { 922 unsafe.copySwapMemory(null, srcAddr, dst, unsafe.arrayBaseOffset(dst.getClass()) + dstPos, length, 8); 923 } 924 }