733 // determined that the average cost of a JNI call exceeds the expense |
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. |
734 // of an element by element copy. These numbers may change over time. |
735 static final int JNI_COPY_TO_ARRAY_THRESHOLD = 6; |
735 static final int JNI_COPY_TO_ARRAY_THRESHOLD = 6; |
736 static final int JNI_COPY_FROM_ARRAY_THRESHOLD = 6; |
736 static final int JNI_COPY_FROM_ARRAY_THRESHOLD = 6; |
737 |
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 |
738 // These methods do no bounds checking. Verification that the copy will not |
743 // These methods do no bounds checking. Verification that the copy will not |
739 // result in memory corruption should be done prior to invocation. |
744 // result in memory corruption should be done prior to invocation. |
740 // All positions and lengths are specified in bytes. |
745 // All positions and lengths are specified in bytes. |
741 |
746 |
742 static native void copyFromByteArray(Object src, long srcPos, long dstAddr, |
747 /** |
743 long length); |
748 * Copy from given source array to destination address. |
744 static native void copyToByteArray(long srcAddr, Object dst, long dstPos, |
749 * |
745 long length); |
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 } |
746 |
800 |
747 static void copyFromCharArray(Object src, long srcPos, long dstAddr, |
801 static void copyFromCharArray(Object src, long srcPos, long dstAddr, |
748 long length) |
802 long length) |
749 { |
803 { |
750 copyFromShortArray(src, srcPos, dstAddr, length); |
804 copyFromShortArray(src, srcPos, dstAddr, length); |