History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/java/nio/Bits.java (1 of 18352 files). Show all

Unified · Split

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