1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  * Copyright (c) 2000, 2021, 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.VM;
32 import jdk.internal.access.SharedSecrets;
33 import jdk.internal.misc.Unsafe;
34 
35 import java.util.concurrent.atomic.AtomicLong;
36 
37 /**
38  * Access to bits, native and otherwise.
39  */
40 
41 class Bits {                            // package-private
42 
Bits()43     private Bits() { }
44 
45 
46     // -- Swapping --
47 
swap(short x)48     static short swap(short x) {
49         return Short.reverseBytes(x);
50     }
51 
swap(char x)52     static char swap(char x) {
53         return Character.reverseBytes(x);
54     }
55 
swap(int x)56     static int swap(int x) {
57         return Integer.reverseBytes(x);
58     }
59 
swap(long x)60     static long swap(long x) {
61         return Long.reverseBytes(x);
62     }
63 
64     // BEGIN Android-added: Getter / Setters needed due to unsupported ScopedMemoryAccess.
65     // -- get/put char --
66 
makeChar(byte b1, byte b0)67     static private char makeChar(byte b1, byte b0) {
68         return (char)((b1 << 8) | (b0 & 0xff));
69     }
70 
getCharL(ByteBuffer bb, int bi)71     static char getCharL(ByteBuffer bb, int bi) {
72         return makeChar(bb._get(bi + 1),
73                         bb._get(bi    ));
74     }
75 
getCharL(long a)76     static char getCharL(long a) {
77         return makeChar(_get(a + 1),
78                         _get(a    ));
79     }
80 
getCharB(ByteBuffer bb, int bi)81     static char getCharB(ByteBuffer bb, int bi) {
82         return makeChar(bb._get(bi    ),
83                         bb._get(bi + 1));
84     }
85 
getCharB(long a)86     static char getCharB(long a) {
87         return makeChar(_get(a    ),
88                         _get(a + 1));
89     }
90 
getChar(ByteBuffer bb, int bi, boolean bigEndian)91     static char getChar(ByteBuffer bb, int bi, boolean bigEndian) {
92         return bigEndian ? getCharB(bb, bi) : getCharL(bb, bi);
93     }
94 
getChar(long a, boolean bigEndian)95     static char getChar(long a, boolean bigEndian) {
96         return bigEndian ? getCharB(a) : getCharL(a);
97     }
98 
char1(char x)99     private static byte char1(char x) { return (byte)(x >> 8); }
char0(char x)100     private static byte char0(char x) { return (byte)(x     ); }
101 
putCharL(ByteBuffer bb, int bi, char x)102     static void putCharL(ByteBuffer bb, int bi, char x) {
103         bb._put(bi    , char0(x));
104         bb._put(bi + 1, char1(x));
105     }
106 
putCharL(long a, char x)107     static void putCharL(long a, char x) {
108         _put(a    , char0(x));
109         _put(a + 1, char1(x));
110     }
111 
putCharB(ByteBuffer bb, int bi, char x)112     static void putCharB(ByteBuffer bb, int bi, char x) {
113         bb._put(bi    , char1(x));
114         bb._put(bi + 1, char0(x));
115     }
116 
putCharB(long a, char x)117     static void putCharB(long a, char x) {
118         _put(a    , char1(x));
119         _put(a + 1, char0(x));
120     }
121 
putChar(ByteBuffer bb, int bi, char x, boolean bigEndian)122     static void putChar(ByteBuffer bb, int bi, char x, boolean bigEndian) {
123         if (bigEndian)
124             putCharB(bb, bi, x);
125         else
126             putCharL(bb, bi, x);
127     }
128 
putChar(long a, char x, boolean bigEndian)129     static void putChar(long a, char x, boolean bigEndian) {
130         if (bigEndian)
131             putCharB(a, x);
132         else
133             putCharL(a, x);
134     }
135 
136 
137     // -- get/put short --
138 
makeShort(byte b1, byte b0)139     static private short makeShort(byte b1, byte b0) {
140         return (short)((b1 << 8) | (b0 & 0xff));
141     }
142 
getShortL(ByteBuffer bb, int bi)143     static short getShortL(ByteBuffer bb, int bi) {
144         return makeShort(bb._get(bi + 1),
145                          bb._get(bi    ));
146     }
147 
getShortL(long a)148     static short getShortL(long a) {
149         return makeShort(_get(a + 1),
150                          _get(a    ));
151     }
152 
getShortB(ByteBuffer bb, int bi)153     static short getShortB(ByteBuffer bb, int bi) {
154         return makeShort(bb._get(bi    ),
155                          bb._get(bi + 1));
156     }
157 
getShortB(long a)158     static short getShortB(long a) {
159         return makeShort(_get(a    ),
160                          _get(a + 1));
161     }
162 
getShort(ByteBuffer bb, int bi, boolean bigEndian)163     static short getShort(ByteBuffer bb, int bi, boolean bigEndian) {
164         return bigEndian ? getShortB(bb, bi) : getShortL(bb, bi);
165     }
166 
getShort(long a, boolean bigEndian)167     static short getShort(long a, boolean bigEndian) {
168         return bigEndian ? getShortB(a) : getShortL(a);
169     }
170 
short1(short x)171     private static byte short1(short x) { return (byte)(x >> 8); }
short0(short x)172     private static byte short0(short x) { return (byte)(x     ); }
173 
putShortL(ByteBuffer bb, int bi, short x)174     static void putShortL(ByteBuffer bb, int bi, short x) {
175         bb._put(bi    , short0(x));
176         bb._put(bi + 1, short1(x));
177     }
178 
putShortL(long a, short x)179     static void putShortL(long a, short x) {
180         _put(a    , short0(x));
181         _put(a + 1, short1(x));
182     }
183 
putShortB(ByteBuffer bb, int bi, short x)184     static void putShortB(ByteBuffer bb, int bi, short x) {
185         bb._put(bi    , short1(x));
186         bb._put(bi + 1, short0(x));
187     }
188 
putShortB(long a, short x)189     static void putShortB(long a, short x) {
190         _put(a    , short1(x));
191         _put(a + 1, short0(x));
192     }
193 
putShort(ByteBuffer bb, int bi, short x, boolean bigEndian)194     static void putShort(ByteBuffer bb, int bi, short x, boolean bigEndian) {
195         if (bigEndian)
196             putShortB(bb, bi, x);
197         else
198             putShortL(bb, bi, x);
199     }
200 
putShort(long a, short x, boolean bigEndian)201     static void putShort(long a, short x, boolean bigEndian) {
202         if (bigEndian)
203             putShortB(a, x);
204         else
205             putShortL(a, x);
206     }
207 
208 
209     // -- get/put int --
210 
makeInt(byte b3, byte b2, byte b1, byte b0)211     static private int makeInt(byte b3, byte b2, byte b1, byte b0) {
212         return (((b3       ) << 24) |
213                 ((b2 & 0xff) << 16) |
214                 ((b1 & 0xff) <<  8) |
215                 ((b0 & 0xff)      ));
216     }
217 
getIntL(ByteBuffer bb, int bi)218     static int getIntL(ByteBuffer bb, int bi) {
219         return makeInt(bb._get(bi + 3),
220                        bb._get(bi + 2),
221                        bb._get(bi + 1),
222                        bb._get(bi    ));
223     }
224 
getIntL(long a)225     static int getIntL(long a) {
226         return makeInt(_get(a + 3),
227                        _get(a + 2),
228                        _get(a + 1),
229                        _get(a    ));
230     }
231 
getIntB(ByteBuffer bb, int bi)232     static int getIntB(ByteBuffer bb, int bi) {
233         return makeInt(bb._get(bi    ),
234                        bb._get(bi + 1),
235                        bb._get(bi + 2),
236                        bb._get(bi + 3));
237     }
238 
getIntB(long a)239     static int getIntB(long a) {
240         return makeInt(_get(a    ),
241                        _get(a + 1),
242                        _get(a + 2),
243                        _get(a + 3));
244     }
245 
getInt(ByteBuffer bb, int bi, boolean bigEndian)246     static int getInt(ByteBuffer bb, int bi, boolean bigEndian) {
247         return bigEndian ? getIntB(bb, bi) : getIntL(bb, bi) ;
248     }
249 
getInt(long a, boolean bigEndian)250     static int getInt(long a, boolean bigEndian) {
251         return bigEndian ? getIntB(a) : getIntL(a) ;
252     }
253 
int3(int x)254     private static byte int3(int x) { return (byte)(x >> 24); }
int2(int x)255     private static byte int2(int x) { return (byte)(x >> 16); }
int1(int x)256     private static byte int1(int x) { return (byte)(x >>  8); }
int0(int x)257     private static byte int0(int x) { return (byte)(x      ); }
258 
putIntL(ByteBuffer bb, int bi, int x)259     static void putIntL(ByteBuffer bb, int bi, int x) {
260         bb._put(bi + 3, int3(x));
261         bb._put(bi + 2, int2(x));
262         bb._put(bi + 1, int1(x));
263         bb._put(bi    , int0(x));
264     }
265 
putIntL(long a, int x)266     static void putIntL(long a, int x) {
267         _put(a + 3, int3(x));
268         _put(a + 2, int2(x));
269         _put(a + 1, int1(x));
270         _put(a    , int0(x));
271     }
272 
putIntB(ByteBuffer bb, int bi, int x)273     static void putIntB(ByteBuffer bb, int bi, int x) {
274         bb._put(bi    , int3(x));
275         bb._put(bi + 1, int2(x));
276         bb._put(bi + 2, int1(x));
277         bb._put(bi + 3, int0(x));
278     }
279 
putIntB(long a, int x)280     static void putIntB(long a, int x) {
281         _put(a    , int3(x));
282         _put(a + 1, int2(x));
283         _put(a + 2, int1(x));
284         _put(a + 3, int0(x));
285     }
286 
putInt(ByteBuffer bb, int bi, int x, boolean bigEndian)287     static void putInt(ByteBuffer bb, int bi, int x, boolean bigEndian) {
288         if (bigEndian)
289             putIntB(bb, bi, x);
290         else
291             putIntL(bb, bi, x);
292     }
293 
putInt(long a, int x, boolean bigEndian)294     static void putInt(long a, int x, boolean bigEndian) {
295         if (bigEndian)
296             putIntB(a, x);
297         else
298             putIntL(a, x);
299     }
300 
301 
302     // -- get/put long --
303 
makeLong(byte b7, byte b6, byte b5, byte b4, byte b3, byte b2, byte b1, byte b0)304     static private long makeLong(byte b7, byte b6, byte b5, byte b4,
305                                  byte b3, byte b2, byte b1, byte b0)
306     {
307         return ((((long)b7       ) << 56) |
308                 (((long)b6 & 0xff) << 48) |
309                 (((long)b5 & 0xff) << 40) |
310                 (((long)b4 & 0xff) << 32) |
311                 (((long)b3 & 0xff) << 24) |
312                 (((long)b2 & 0xff) << 16) |
313                 (((long)b1 & 0xff) <<  8) |
314                 (((long)b0 & 0xff)      ));
315     }
316 
getLongL(ByteBuffer bb, int bi)317     static long getLongL(ByteBuffer bb, int bi) {
318         return makeLong(bb._get(bi + 7),
319                         bb._get(bi + 6),
320                         bb._get(bi + 5),
321                         bb._get(bi + 4),
322                         bb._get(bi + 3),
323                         bb._get(bi + 2),
324                         bb._get(bi + 1),
325                         bb._get(bi    ));
326     }
327 
getLongL(long a)328     static long getLongL(long a) {
329         return makeLong(_get(a + 7),
330                         _get(a + 6),
331                         _get(a + 5),
332                         _get(a + 4),
333                         _get(a + 3),
334                         _get(a + 2),
335                         _get(a + 1),
336                         _get(a    ));
337     }
338 
getLongB(ByteBuffer bb, int bi)339     static long getLongB(ByteBuffer bb, int bi) {
340         return makeLong(bb._get(bi    ),
341                         bb._get(bi + 1),
342                         bb._get(bi + 2),
343                         bb._get(bi + 3),
344                         bb._get(bi + 4),
345                         bb._get(bi + 5),
346                         bb._get(bi + 6),
347                         bb._get(bi + 7));
348     }
349 
getLongB(long a)350     static long getLongB(long a) {
351         return makeLong(_get(a    ),
352                         _get(a + 1),
353                         _get(a + 2),
354                         _get(a + 3),
355                         _get(a + 4),
356                         _get(a + 5),
357                         _get(a + 6),
358                         _get(a + 7));
359     }
360 
getLong(ByteBuffer bb, int bi, boolean bigEndian)361     static long getLong(ByteBuffer bb, int bi, boolean bigEndian) {
362         return bigEndian ? getLongB(bb, bi) : getLongL(bb, bi);
363     }
364 
getLong(long a, boolean bigEndian)365     static long getLong(long a, boolean bigEndian) {
366         return bigEndian ? getLongB(a) : getLongL(a);
367     }
368 
long7(long x)369     private static byte long7(long x) { return (byte)(x >> 56); }
long6(long x)370     private static byte long6(long x) { return (byte)(x >> 48); }
long5(long x)371     private static byte long5(long x) { return (byte)(x >> 40); }
long4(long x)372     private static byte long4(long x) { return (byte)(x >> 32); }
long3(long x)373     private static byte long3(long x) { return (byte)(x >> 24); }
long2(long x)374     private static byte long2(long x) { return (byte)(x >> 16); }
long1(long x)375     private static byte long1(long x) { return (byte)(x >>  8); }
long0(long x)376     private static byte long0(long x) { return (byte)(x      ); }
377 
putLongL(ByteBuffer bb, int bi, long x)378     static void putLongL(ByteBuffer bb, int bi, long x) {
379         bb._put(bi + 7, long7(x));
380         bb._put(bi + 6, long6(x));
381         bb._put(bi + 5, long5(x));
382         bb._put(bi + 4, long4(x));
383         bb._put(bi + 3, long3(x));
384         bb._put(bi + 2, long2(x));
385         bb._put(bi + 1, long1(x));
386         bb._put(bi    , long0(x));
387     }
388 
putLongL(long a, long x)389     static void putLongL(long a, long x) {
390         _put(a + 7, long7(x));
391         _put(a + 6, long6(x));
392         _put(a + 5, long5(x));
393         _put(a + 4, long4(x));
394         _put(a + 3, long3(x));
395         _put(a + 2, long2(x));
396         _put(a + 1, long1(x));
397         _put(a    , long0(x));
398     }
399 
putLongB(ByteBuffer bb, int bi, long x)400     static void putLongB(ByteBuffer bb, int bi, long x) {
401         bb._put(bi    , long7(x));
402         bb._put(bi + 1, long6(x));
403         bb._put(bi + 2, long5(x));
404         bb._put(bi + 3, long4(x));
405         bb._put(bi + 4, long3(x));
406         bb._put(bi + 5, long2(x));
407         bb._put(bi + 6, long1(x));
408         bb._put(bi + 7, long0(x));
409     }
410 
putLongB(long a, long x)411     static void putLongB(long a, long x) {
412         _put(a    , long7(x));
413         _put(a + 1, long6(x));
414         _put(a + 2, long5(x));
415         _put(a + 3, long4(x));
416         _put(a + 4, long3(x));
417         _put(a + 5, long2(x));
418         _put(a + 6, long1(x));
419         _put(a + 7, long0(x));
420     }
421 
putLong(ByteBuffer bb, int bi, long x, boolean bigEndian)422     static void putLong(ByteBuffer bb, int bi, long x, boolean bigEndian) {
423         if (bigEndian)
424             putLongB(bb, bi, x);
425         else
426             putLongL(bb, bi, x);
427     }
428 
putLong(long a, long x, boolean bigEndian)429     static void putLong(long a, long x, boolean bigEndian) {
430         if (bigEndian)
431             putLongB(a, x);
432         else
433             putLongL(a, x);
434     }
435 
436 
437     // -- get/put float --
438 
getFloatL(ByteBuffer bb, int bi)439     static float getFloatL(ByteBuffer bb, int bi) {
440         return Float.intBitsToFloat(getIntL(bb, bi));
441     }
442 
getFloatL(long a)443     static float getFloatL(long a) {
444         return Float.intBitsToFloat(getIntL(a));
445     }
446 
getFloatB(ByteBuffer bb, int bi)447     static float getFloatB(ByteBuffer bb, int bi) {
448         return Float.intBitsToFloat(getIntB(bb, bi));
449     }
450 
getFloatB(long a)451     static float getFloatB(long a) {
452         return Float.intBitsToFloat(getIntB(a));
453     }
454 
getFloat(ByteBuffer bb, int bi, boolean bigEndian)455     static float getFloat(ByteBuffer bb, int bi, boolean bigEndian) {
456         return bigEndian ? getFloatB(bb, bi) : getFloatL(bb, bi);
457     }
458 
getFloat(long a, boolean bigEndian)459     static float getFloat(long a, boolean bigEndian) {
460         return bigEndian ? getFloatB(a) : getFloatL(a);
461     }
462 
putFloatL(ByteBuffer bb, int bi, float x)463     static void putFloatL(ByteBuffer bb, int bi, float x) {
464         putIntL(bb, bi, Float.floatToRawIntBits(x));
465     }
466 
putFloatL(long a, float x)467     static void putFloatL(long a, float x) {
468         putIntL(a, Float.floatToRawIntBits(x));
469     }
470 
putFloatB(ByteBuffer bb, int bi, float x)471     static void putFloatB(ByteBuffer bb, int bi, float x) {
472         putIntB(bb, bi, Float.floatToRawIntBits(x));
473     }
474 
putFloatB(long a, float x)475     static void putFloatB(long a, float x) {
476         putIntB(a, Float.floatToRawIntBits(x));
477     }
478 
putFloat(ByteBuffer bb, int bi, float x, boolean bigEndian)479     static void putFloat(ByteBuffer bb, int bi, float x, boolean bigEndian) {
480         if (bigEndian)
481             putFloatB(bb, bi, x);
482         else
483             putFloatL(bb, bi, x);
484     }
485 
putFloat(long a, float x, boolean bigEndian)486     static void putFloat(long a, float x, boolean bigEndian) {
487         if (bigEndian)
488             putFloatB(a, x);
489         else
490             putFloatL(a, x);
491     }
492 
493 
494     // -- get/put double --
495 
getDoubleL(ByteBuffer bb, int bi)496     static double getDoubleL(ByteBuffer bb, int bi) {
497         return Double.longBitsToDouble(getLongL(bb, bi));
498     }
499 
getDoubleL(long a)500     static double getDoubleL(long a) {
501         return Double.longBitsToDouble(getLongL(a));
502     }
503 
getDoubleB(ByteBuffer bb, int bi)504     static double getDoubleB(ByteBuffer bb, int bi) {
505         return Double.longBitsToDouble(getLongB(bb, bi));
506     }
507 
getDoubleB(long a)508     static double getDoubleB(long a) {
509         return Double.longBitsToDouble(getLongB(a));
510     }
511 
getDouble(ByteBuffer bb, int bi, boolean bigEndian)512     static double getDouble(ByteBuffer bb, int bi, boolean bigEndian) {
513         return bigEndian ? getDoubleB(bb, bi) : getDoubleL(bb, bi);
514     }
515 
getDouble(long a, boolean bigEndian)516     static double getDouble(long a, boolean bigEndian) {
517         return bigEndian ? getDoubleB(a) : getDoubleL(a);
518     }
519 
putDoubleL(ByteBuffer bb, int bi, double x)520     static void putDoubleL(ByteBuffer bb, int bi, double x) {
521         putLongL(bb, bi, Double.doubleToRawLongBits(x));
522     }
523 
putDoubleL(long a, double x)524     static void putDoubleL(long a, double x) {
525         putLongL(a, Double.doubleToRawLongBits(x));
526     }
527 
putDoubleB(ByteBuffer bb, int bi, double x)528     static void putDoubleB(ByteBuffer bb, int bi, double x) {
529         putLongB(bb, bi, Double.doubleToRawLongBits(x));
530     }
531 
putDoubleB(long a, double x)532     static void putDoubleB(long a, double x) {
533         putLongB(a, Double.doubleToRawLongBits(x));
534     }
535 
putDouble(ByteBuffer bb, int bi, double x, boolean bigEndian)536     static void putDouble(ByteBuffer bb, int bi, double x, boolean bigEndian) {
537         if (bigEndian)
538             putDoubleB(bb, bi, x);
539         else
540             putDoubleL(bb, bi, x);
541     }
542 
putDouble(long a, double x, boolean bigEndian)543     static void putDouble(long a, double x, boolean bigEndian) {
544         if (bigEndian)
545             putDoubleB(a, x);
546         else
547             putDoubleL(a, x);
548     }
549 
_get(long a)550     private static byte _get(long a) {
551         return UNSAFE.getByte(a);
552     }
553 
_put(long a, byte b)554     private static void _put(long a, byte b) {
555         UNSAFE.putByte(a, b);
556     }
557     // END Android-added: Getter / Setters needed due to unsupported ScopedMemoryAccess.
558 
559     // -- Unsafe access --
560 
561     private static final Unsafe UNSAFE = Unsafe.getUnsafe();
562 
563     // -- Processor and memory-system properties --
564 
565     private static int PAGE_SIZE = -1;
566 
pageSize()567     static int pageSize() {
568         if (PAGE_SIZE == -1)
569             PAGE_SIZE = UNSAFE.pageSize();
570         return PAGE_SIZE;
571     }
572 
pageCount(long size)573     static long pageCount(long size) {
574         return (size + (long)pageSize() - 1L) / pageSize();
575     }
576     // Android-removed: Remove unused methods.
577     /*
578     private static boolean UNALIGNED = UNSAFE.unalignedAccess();
579 
580     static boolean unaligned() {
581         return UNALIGNED;
582     }
583     */
584 
585 
586     // -- Direct memory management --
587 
588     // BEGIN Android-removed: Direct memory management unused on Android.
589     /*
590     // A user-settable upper limit on the maximum amount of allocatable
591     // direct buffer memory.  This value may be changed during VM
592     // initialization if it is launched with "-XX:MaxDirectMemorySize=<size>".
593     private static volatile long MAX_MEMORY = VM.maxDirectMemory();
594     private static final AtomicLong RESERVED_MEMORY = new AtomicLong();
595     private static final AtomicLong TOTAL_CAPACITY = new AtomicLong();
596     private static final AtomicLong COUNT = new AtomicLong();
597     private static volatile boolean MEMORY_LIMIT_SET;
598 
599     // max. number of sleeps during try-reserving with exponentially
600     // increasing delay before throwing OutOfMemoryError:
601     // 1, 2, 4, 8, 16, 32, 64, 128, 256 (total 511 ms ~ 0.5 s)
602     // which means that OOME will be thrown after 0.5 s of trying
603     private static final int MAX_SLEEPS = 9;
604 
605     // These methods should be called whenever direct memory is allocated or
606     // freed.  They allow the user to control the amount of direct memory
607     // which a process may access.  All sizes are specified in bytes.
608     static void reserveMemory(long size, long cap) {
609 
610         if (!MEMORY_LIMIT_SET && VM.initLevel() >= 1) {
611             MAX_MEMORY = VM.maxDirectMemory();
612             MEMORY_LIMIT_SET = true;
613         }
614 
615         // optimist!
616         if (tryReserveMemory(size, cap)) {
617             return;
618         }
619 
620         final JavaLangRefAccess jlra = SharedSecrets.getJavaLangRefAccess();
621         boolean interrupted = false;
622         try {
623 
624             // Retry allocation until success or there are no more
625             // references (including Cleaners that might free direct
626             // buffer memory) to process and allocation still fails.
627             boolean refprocActive;
628             do {
629                 try {
630                     refprocActive = jlra.waitForReferenceProcessing();
631                 } catch (InterruptedException e) {
632                     // Defer interrupts and keep trying.
633                     interrupted = true;
634                     refprocActive = true;
635                 }
636                 if (tryReserveMemory(size, cap)) {
637                     return;
638                 }
639             } while (refprocActive);
640 
641             // trigger VM's Reference processing
642             System.gc();
643 
644             // A retry loop with exponential back-off delays.
645             // Sometimes it would suffice to give up once reference
646             // processing is complete.  But if there are many threads
647             // competing for memory, this gives more opportunities for
648             // any given thread to make progress.  In particular, this
649             // seems to be enough for a stress test like
650             // DirectBufferAllocTest to (usually) succeed, while
651             // without it that test likely fails.  Since failure here
652             // ends in OOME, there's no need to hurry.
653             long sleepTime = 1;
654             int sleeps = 0;
655             while (true) {
656                 if (tryReserveMemory(size, cap)) {
657                     return;
658                 }
659                 if (sleeps >= MAX_SLEEPS) {
660                     break;
661                 }
662                 try {
663                     if (!jlra.waitForReferenceProcessing()) {
664                         Thread.sleep(sleepTime);
665                         sleepTime <<= 1;
666                         sleeps++;
667                     }
668                 } catch (InterruptedException e) {
669                     interrupted = true;
670                 }
671             }
672 
673             // no luck
674             throw new OutOfMemoryError
675                 ("Cannot reserve "
676                  + size + " bytes of direct buffer memory (allocated: "
677                  + RESERVED_MEMORY.get() + ", limit: " + MAX_MEMORY +")");
678 
679         } finally {
680             if (interrupted) {
681                 // don't swallow interrupts
682                 Thread.currentThread().interrupt();
683             }
684         }
685     }
686 
687     private static boolean tryReserveMemory(long size, long cap) {
688 
689         // -XX:MaxDirectMemorySize limits the total capacity rather than the
690         // actual memory usage, which will differ when buffers are page
691         // aligned.
692         long totalCap;
693         while (cap <= MAX_MEMORY - (totalCap = TOTAL_CAPACITY.get())) {
694             if (TOTAL_CAPACITY.compareAndSet(totalCap, totalCap + cap)) {
695                 RESERVED_MEMORY.addAndGet(size);
696                 COUNT.incrementAndGet();
697                 return true;
698             }
699         }
700 
701         return false;
702     }
703 
704 
705     static void unreserveMemory(long size, long cap) {
706         long cnt = COUNT.decrementAndGet();
707         long reservedMem = RESERVED_MEMORY.addAndGet(-size);
708         long totalCap = TOTAL_CAPACITY.addAndGet(-cap);
709         assert cnt >= 0 && reservedMem >= 0 && totalCap >= 0;
710     }
711 
712     static final BufferPool BUFFER_POOL = new BufferPool() {
713         @Override
714         public String getName() {
715             return "direct";
716         }
717         @Override
718         public long getCount() {
719             return Bits.COUNT.get();
720         }
721         @Override
722         public long getTotalCapacity() {
723             return Bits.TOTAL_CAPACITY.get();
724         }
725         @Override
726         public long getMemoryUsed() {
727             return Bits.RESERVED_MEMORY.get();
728         }
729     };
730 
731     // These numbers represent the point at which we have empirically
732     // determined that the average cost of a JNI call exceeds the expense
733     // of an element by element copy.  These numbers may change over time.
734     static final int JNI_COPY_TO_ARRAY_THRESHOLD   = 6;
735     static final int JNI_COPY_FROM_ARRAY_THRESHOLD = 6;
736     */
737     // END Android-removed: Direct memory management unused on Android.
738 }
739