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