1 /*
   2  * Copyright (c) 2000, 2018, 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 java.util.concurrent.atomic.AtomicLong;
  30 import java.util.concurrent.atomic.LongAdder;
  31 
  32 import sun.misc.JavaLangRefAccess;
  33 import sun.misc.SharedSecrets;
  34 import sun.misc.Unsafe;
  35 import sun.misc.VM;
  36 
  37 /**
  38  * Access to bits, native and otherwise.
  39  */
  40 
  41 class Bits {                            // package-private
  42 
  43     private Bits() { }
  44 
  45 
  46     // -- Swapping --
  47 
  48     static short swap(short x) {
  49         return Short.reverseBytes(x);
  50     }
  51 
  52     static char swap(char x) {
  53         return Character.reverseBytes(x);
  54     }
  55 
  56     static int swap(int x) {
  57         return Integer.reverseBytes(x);
  58     }
  59 
  60     static long swap(long x) {
  61         return Long.reverseBytes(x);
  62     }
  63 
  64 
  65     // -- get/put char --
  66 
  67     static private char makeChar(byte b1, byte b0) {
  68         return (char)((b1 << 8) | (b0 & 0xff));
  69     }
  70 
  71     static char getCharL(ByteBuffer bb, int bi) {
  72         return makeChar(bb._get(bi + 1),
  73                         bb._get(bi    ));
  74     }
  75 
  76     static char getCharL(long a) {
  77         return makeChar(_get(a + 1),
  78                         _get(a    ));
  79     }
  80 
  81     static char getCharB(ByteBuffer bb, int bi) {
  82         return makeChar(bb._get(bi    ),
  83                         bb._get(bi + 1));
  84     }
  85 
  86     static char getCharB(long a) {
  87         return makeChar(_get(a    ),
  88                         _get(a + 1));
  89     }
  90 
  91     static char getChar(ByteBuffer bb, int bi, boolean bigEndian) {
  92         return bigEndian ? getCharB(bb, bi) : getCharL(bb, bi);
  93     }
  94 
  95     static char getChar(long a, boolean bigEndian) {
  96         return bigEndian ? getCharB(a) : getCharL(a);
  97     }
  98 
  99     private static byte char1(char x) { return (byte)(x >> 8); }
 100     private static byte char0(char x) { return (byte)(x     ); }
 101 
 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 
 107     static void putCharL(long a, char x) {
 108         _put(a    , char0(x));
 109         _put(a + 1, char1(x));
 110     }
 111 
 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 
 117     static void putCharB(long a, char x) {
 118         _put(a    , char1(x));
 119         _put(a + 1, char0(x));
 120     }
 121 
 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 
 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 
 139     static private short makeShort(byte b1, byte b0) {
 140         return (short)((b1 << 8) | (b0 & 0xff));
 141     }
 142 
 143     static short getShortL(ByteBuffer bb, int bi) {
 144         return makeShort(bb._get(bi + 1),
 145                          bb._get(bi    ));
 146     }
 147 
 148     static short getShortL(long a) {
 149         return makeShort(_get(a + 1),
 150                          _get(a    ));
 151     }
 152 
 153     static short getShortB(ByteBuffer bb, int bi) {
 154         return makeShort(bb._get(bi    ),
 155                          bb._get(bi + 1));
 156     }
 157 
 158     static short getShortB(long a) {
 159         return makeShort(_get(a    ),
 160                          _get(a + 1));
 161     }
 162 
 163     static short getShort(ByteBuffer bb, int bi, boolean bigEndian) {
 164         return bigEndian ? getShortB(bb, bi) : getShortL(bb, bi);
 165     }
 166 
 167     static short getShort(long a, boolean bigEndian) {
 168         return bigEndian ? getShortB(a) : getShortL(a);
 169     }
 170 
 171     private static byte short1(short x) { return (byte)(x >> 8); }
 172     private static byte short0(short x) { return (byte)(x     ); }
 173 
 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 
 179     static void putShortL(long a, short x) {
 180         _put(a    , short0(x));
 181         _put(a + 1, short1(x));
 182     }
 183 
 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 
 189     static void putShortB(long a, short x) {
 190         _put(a    , short1(x));
 191         _put(a + 1, short0(x));
 192     }
 193 
 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 
 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 
 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 
 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 
 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 
 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 
 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 
 246     static int getInt(ByteBuffer bb, int bi, boolean bigEndian) {
 247         return bigEndian ? getIntB(bb, bi) : getIntL(bb, bi) ;
 248     }
 249 
 250     static int getInt(long a, boolean bigEndian) {
 251         return bigEndian ? getIntB(a) : getIntL(a) ;
 252     }
 253 
 254     private static byte int3(int x) { return (byte)(x >> 24); }
 255     private static byte int2(int x) { return (byte)(x >> 16); }
 256     private static byte int1(int x) { return (byte)(x >>  8); }
 257     private static byte int0(int x) { return (byte)(x      ); }
 258 
 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 
 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 
 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 
 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 
 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 
 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 
 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 
 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 
 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 
 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 
 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 
 361     static long getLong(ByteBuffer bb, int bi, boolean bigEndian) {
 362         return bigEndian ? getLongB(bb, bi) : getLongL(bb, bi);
 363     }
 364 
 365     static long getLong(long a, boolean bigEndian) {
 366         return bigEndian ? getLongB(a) : getLongL(a);
 367     }
 368 
 369     private static byte long7(long x) { return (byte)(x >> 56); }
 370     private static byte long6(long x) { return (byte)(x >> 48); }
 371     private static byte long5(long x) { return (byte)(x >> 40); }
 372     private static byte long4(long x) { return (byte)(x >> 32); }
 373     private static byte long3(long x) { return (byte)(x >> 24); }
 374     private static byte long2(long x) { return (byte)(x >> 16); }
 375     private static byte long1(long x) { return (byte)(x >>  8); }
 376     private static byte long0(long x) { return (byte)(x      ); }
 377 
 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 
 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 
 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 
 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 
 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 
 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 
 439     static float getFloatL(ByteBuffer bb, int bi) {
 440         return Float.intBitsToFloat(getIntL(bb, bi));
 441     }
 442 
 443     static float getFloatL(long a) {
 444         return Float.intBitsToFloat(getIntL(a));
 445     }
 446 
 447     static float getFloatB(ByteBuffer bb, int bi) {
 448         return Float.intBitsToFloat(getIntB(bb, bi));
 449     }
 450 
 451     static float getFloatB(long a) {
 452         return Float.intBitsToFloat(getIntB(a));
 453     }
 454 
 455     static float getFloat(ByteBuffer bb, int bi, boolean bigEndian) {
 456         return bigEndian ? getFloatB(bb, bi) : getFloatL(bb, bi);
 457     }
 458 
 459     static float getFloat(long a, boolean bigEndian) {
 460         return bigEndian ? getFloatB(a) : getFloatL(a);
 461     }
 462 
 463     static void putFloatL(ByteBuffer bb, int bi, float x) {
 464         putIntL(bb, bi, Float.floatToRawIntBits(x));
 465     }
 466 
 467     static void putFloatL(long a, float x) {
 468         putIntL(a, Float.floatToRawIntBits(x));
 469     }
 470 
 471     static void putFloatB(ByteBuffer bb, int bi, float x) {
 472         putIntB(bb, bi, Float.floatToRawIntBits(x));
 473     }
 474 
 475     static void putFloatB(long a, float x) {
 476         putIntB(a, Float.floatToRawIntBits(x));
 477     }
 478 
 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 
 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 
 496     static double getDoubleL(ByteBuffer bb, int bi) {
 497         return Double.longBitsToDouble(getLongL(bb, bi));
 498     }
 499 
 500     static double getDoubleL(long a) {
 501         return Double.longBitsToDouble(getLongL(a));
 502     }
 503 
 504     static double getDoubleB(ByteBuffer bb, int bi) {
 505         return Double.longBitsToDouble(getLongB(bb, bi));
 506     }
 507 
 508     static double getDoubleB(long a) {
 509         return Double.longBitsToDouble(getLongB(a));
 510     }
 511 
 512     static double getDouble(ByteBuffer bb, int bi, boolean bigEndian) {
 513         return bigEndian ? getDoubleB(bb, bi) : getDoubleL(bb, bi);
 514     }
 515 
 516     static double getDouble(long a, boolean bigEndian) {
 517         return bigEndian ? getDoubleB(a) : getDoubleL(a);
 518     }
 519 
 520     static void putDoubleL(ByteBuffer bb, int bi, double x) {
 521         putLongL(bb, bi, Double.doubleToRawLongBits(x));
 522     }
 523 
 524     static void putDoubleL(long a, double x) {
 525         putLongL(a, Double.doubleToRawLongBits(x));
 526     }
 527 
 528     static void putDoubleB(ByteBuffer bb, int bi, double x) {
 529         putLongB(bb, bi, Double.doubleToRawLongBits(x));
 530     }
 531 
 532     static void putDoubleB(long a, double x) {
 533         putLongB(a, Double.doubleToRawLongBits(x));
 534     }
 535 
 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 
 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 
 550 
 551     // -- Unsafe access --
 552 
 553     private static final Unsafe unsafe = Unsafe.getUnsafe();
 554 
 555     private static byte _get(long a) {
 556         return unsafe.getByte(a);
 557     }
 558 
 559     private static void _put(long a, byte b) {
 560         unsafe.putByte(a, b);
 561     }
 562 
 563     static Unsafe unsafe() {
 564         return unsafe;
 565     }
 566 
 567 
 568     // -- Processor and memory-system properties --
 569 
 570     private static final ByteOrder byteOrder;
 571 
 572     static ByteOrder byteOrder() {
 573         if (byteOrder == null)
 574             throw new Error("Unknown byte order");
 575         return byteOrder;
 576     }
 577 
 578     static {
 579         long a = unsafe.allocateMemory(8);
 580         try {
 581             unsafe.putLong(a, 0x0102030405060708L);
 582             byte b = unsafe.getByte(a);
 583             switch (b) {
 584             case 0x01: byteOrder = ByteOrder.BIG_ENDIAN;     break;
 585             case 0x08: byteOrder = ByteOrder.LITTLE_ENDIAN;  break;
 586             default:
 587                 assert false;
 588                 byteOrder = null;
 589             }
 590         } finally {
 591             unsafe.freeMemory(a);
 592         }
 593     }
 594 
 595 
 596     private static int pageSize = -1;
 597 
 598     static int pageSize() {
 599         if (pageSize == -1)
 600             pageSize = unsafe().pageSize();
 601         return pageSize;
 602     }
 603 
 604     static int pageCount(long size) {
 605         return (int)(size + (long)pageSize() - 1L) / pageSize();
 606     }
 607 
 608     private static boolean unaligned;
 609     private static boolean unalignedKnown = false;
 610 
 611     static boolean unaligned() {
 612         if (unalignedKnown)
 613             return unaligned;
 614         String arch = AccessController.doPrivileged(
 615             new sun.security.action.GetPropertyAction("os.arch"));
 616         unaligned = arch.equals("i386") || arch.equals("x86")
 617             || arch.equals("amd64") || arch.equals("x86_64")
 618             || arch.equals("ppc64") || arch.equals("ppc64le");
 619         unalignedKnown = true;
 620         return unaligned;
 621     }
 622 
 623 
 624     // -- Direct memory management --
 625 
 626     // A user-settable upper limit on the maximum amount of allocatable
 627     // direct buffer memory.  This value may be changed during VM
 628     // initialization if it is launched with "-XX:MaxDirectMemorySize=<size>".
 629     private static volatile long maxMemory = VM.maxDirectMemory();
 630     private static final AtomicLong reservedMemory = new AtomicLong();
 631     private static final AtomicLong totalCapacity = new AtomicLong();
 632     private static final AtomicLong count = new AtomicLong();
 633     private static volatile boolean memoryLimitSet = false;
 634     // max. number of sleeps during try-reserving with exponentially
 635     // increasing delay before throwing OutOfMemoryError:
 636     // 1, 2, 4, 8, 16, 32, 64, 128, 256 (total 511 ms ~ 0.5 s)
 637     // which means that OOME will be thrown after 0.5 s of trying
 638     private static final int MAX_SLEEPS = 9;
 639 
 640     // These methods should be called whenever direct memory is allocated or
 641     // freed.  They allow the user to control the amount of direct memory
 642     // which a process may access.  All sizes are specified in bytes.
 643     static void reserveMemory(long size, int cap) {
 644 
 645         if (!memoryLimitSet && VM.isBooted()) {
 646             maxMemory = VM.maxDirectMemory();
 647             memoryLimitSet = true;
 648         }
 649 
 650         // optimist!
 651         if (tryReserveMemory(size, cap)) {
 652             return;
 653         }
 654 
 655         final JavaLangRefAccess jlra = SharedSecrets.getJavaLangRefAccess();
 656 
 657         // retry while helping enqueue pending Reference objects
 658         // which includes executing pending Cleaner(s) which includes
 659         // Cleaner(s) that free direct buffer memory
 660         while (jlra.tryHandlePendingReference()) {
 661             if (tryReserveMemory(size, cap)) {
 662                 return;
 663             }
 664         }
 665 
 666         // trigger VM's Reference processing
 667         System.gc();
 668 
 669         // a retry loop with exponential back-off delays
 670         // (this gives VM some time to do it's job)
 671         boolean interrupted = false;
 672         try {
 673             long sleepTime = 1;
 674             int sleeps = 0;
 675             while (true) {
 676                 if (tryReserveMemory(size, cap)) {
 677                     return;
 678                 }
 679                 if (sleeps >= MAX_SLEEPS) {
 680                     break;
 681                 }
 682                 if (!jlra.tryHandlePendingReference()) {
 683                     try {
 684                         Thread.sleep(sleepTime);
 685                         sleepTime <<= 1;
 686                         sleeps++;
 687                     } catch (InterruptedException e) {
 688                         interrupted = true;
 689                     }
 690                 }
 691             }
 692 
 693             // no luck
 694             throw new OutOfMemoryError("Direct buffer memory");
 695 
 696         } finally {
 697             if (interrupted) {
 698                 // don't swallow interrupts
 699                 Thread.currentThread().interrupt();
 700             }
 701         }
 702     }
 703 
 704     private static boolean tryReserveMemory(long size, int cap) {
 705 
 706         // -XX:MaxDirectMemorySize limits the total capacity rather than the
 707         // actual memory usage, which will differ when buffers are page
 708         // aligned.
 709         long totalCap;
 710         while (cap <= maxMemory - (totalCap = totalCapacity.get())) {
 711             if (totalCapacity.compareAndSet(totalCap, totalCap + cap)) {
 712                 reservedMemory.addAndGet(size);
 713                 count.incrementAndGet();
 714                 return true;
 715             }
 716         }
 717 
 718         return false;
 719     }
 720 
 721 
 722     static void unreserveMemory(long size, int cap) {
 723         long cnt = count.decrementAndGet();
 724         long reservedMem = reservedMemory.addAndGet(-size);
 725         long totalCap = totalCapacity.addAndGet(-cap);
 726         assert cnt >= 0 && reservedMem >= 0 && totalCap >= 0;
 727     }
 728 
 729     // -- Monitoring of direct buffer usage --
 730 
 731     static {
 732         // setup access to this package in SharedSecrets
 733         sun.misc.SharedSecrets.setJavaNioAccess(
 734             new sun.misc.JavaNioAccess() {
 735                 @Override
 736                 public sun.misc.JavaNioAccess.BufferPool getDirectBufferPool() {
 737                     return new sun.misc.JavaNioAccess.BufferPool() {
 738                         @Override
 739                         public String getName() {
 740                             return "direct";
 741                         }
 742                         @Override
 743                         public long getCount() {
 744                             return Bits.count.get();
 745                         }
 746                         @Override
 747                         public long getTotalCapacity() {
 748                             return Bits.totalCapacity.get();
 749                         }
 750                         @Override
 751                         public long getMemoryUsed() {
 752                             return Bits.reservedMemory.get();
 753                         }
 754                     };
 755                 }
 756                 @Override
 757                 public ByteBuffer newDirectByteBuffer(long addr, int cap, Object ob) {
 758                     return new DirectByteBuffer(addr, cap, ob);
 759                 }
 760                 @Override
 761                 public void truncate(Buffer buf) {
 762                     buf.truncate();
 763                 }
 764         });
 765     }
 766 
 767     // -- Bulk get/put acceleration --
 768 
 769     // These numbers represent the point at which we have empirically
 770     // determined that the average cost of a JNI call exceeds the expense
 771     // of an element by element copy.  These numbers may change over time.
 772     static final int JNI_COPY_TO_ARRAY_THRESHOLD   = 6;
 773     static final int JNI_COPY_FROM_ARRAY_THRESHOLD = 6;
 774 
 775     // This number limits the number of bytes to copy per call to Unsafe's
 776     // copyMemory method. A limit is imposed to allow for safepoint polling
 777     // during a large copy
 778     static final long UNSAFE_COPY_THRESHOLD = 1024L * 1024L;
 779 
 780     // These methods do no bounds checking.  Verification that the copy will not
 781     // result in memory corruption should be done prior to invocation.
 782     // All positions and lengths are specified in bytes.
 783 
 784     /**
 785      * Copy from given source array to destination address.
 786      *
 787      * @param   src
 788      *          source array
 789      * @param   srcBaseOffset
 790      *          offset of first element of storage in source array
 791      * @param   srcPos
 792      *          offset within source array of the first element to read
 793      * @param   dstAddr
 794      *          destination address
 795      * @param   length
 796      *          number of bytes to copy
 797      */
 798     static void copyFromArray(Object src, long srcBaseOffset, long srcPos,
 799                               long dstAddr, long length)
 800     {
 801         long offset = srcBaseOffset + srcPos;
 802         while (length > 0) {
 803             long size = (length > UNSAFE_COPY_THRESHOLD) ? UNSAFE_COPY_THRESHOLD : length;
 804             unsafe.copyMemory(src, offset, null, dstAddr, size);
 805             length -= size;
 806             offset += size;
 807             dstAddr += size;
 808         }
 809     }
 810 
 811     /**
 812      * Copy from source address into given destination array.
 813      *
 814      * @param   srcAddr
 815      *          source address
 816      * @param   dst
 817      *          destination array
 818      * @param   dstBaseOffset
 819      *          offset of first element of storage in destination array
 820      * @param   dstPos
 821      *          offset within destination array of the first element to write
 822      * @param   length
 823      *          number of bytes to copy
 824      */
 825     static void copyToArray(long srcAddr, Object dst, long dstBaseOffset, long dstPos,
 826                             long length)
 827     {
 828         long offset = dstBaseOffset + dstPos;
 829         while (length > 0) {
 830             long size = (length > UNSAFE_COPY_THRESHOLD) ? UNSAFE_COPY_THRESHOLD : length;
 831             unsafe.copyMemory(null, srcAddr, dst, offset, size);
 832             length -= size;
 833             srcAddr += size;
 834             offset += size;
 835         }
 836     }
 837 
 838     /**
 839      * Copy and unconditionally byte swap 16 bit elements from a heap array to off-heap memory
 840      *
 841      * @param src
 842      *        the source array, must be a 16-bit primitive array type
 843      * @param srcPos
 844      *        byte offset within source array of the first element to read
 845      * @param dstAddr
 846      *        destination address
 847      * @param length
 848      *        number of bytes to copy
 849      */
 850     static void copyFromCharArray(Object src, long srcPos, long dstAddr, long length) {
 851         copySwapMemory(src, unsafe.arrayBaseOffset(src.getClass()) + srcPos, null, dstAddr, length, 2);
 852     }
 853 
 854     /**
 855      * Copy and unconditionally byte swap 16 bit elements from off-heap memory to a heap array
 856      *
 857      * @param srcAddr
 858      *        source address
 859      * @param dst
 860      *        destination array, must be a 16-bit primitive array type
 861      * @param dstPos
 862      *        byte offset within the destination array of the first element to write
 863      * @param length
 864      *        number of bytes to copy
 865      */
 866     static void copyToCharArray(long srcAddr, Object dst, long dstPos, long length) {
 867         copySwapMemory(null, srcAddr, dst, unsafe.arrayBaseOffset(dst.getClass()) + dstPos, length, 2);
 868     }
 869 
 870     /**
 871      * Copy and unconditionally byte swap 16 bit elements from a heap array to off-heap memory
 872      *
 873      * @param src
 874      *        the source array, must be a 16-bit primitive array type
 875      * @param srcPos
 876      *        byte offset within source array of the first element to read
 877      * @param dstAddr
 878      *        destination address
 879      * @param length
 880      *        number of bytes to copy
 881      */
 882     static void copyFromShortArray(Object src, long srcPos, long dstAddr, long length) {
 883         copySwapMemory(src, unsafe.arrayBaseOffset(src.getClass()) + srcPos, null, dstAddr, length, 2);
 884     }
 885 
 886     /**
 887      * Copy and unconditionally byte swap 16 bit elements from off-heap memory to a heap array
 888      *
 889      * @param srcAddr
 890      *        source address
 891      * @param dst
 892      *        destination array, must be a 16-bit primitive array type
 893      * @param dstPos
 894      *        byte offset within the destination array of the first element to write
 895      * @param length
 896      *        number of bytes to copy
 897      */
 898     static void copyToShortArray(long srcAddr, Object dst, long dstPos, long length) {
 899         copySwapMemory(null, srcAddr, dst, unsafe.arrayBaseOffset(dst.getClass()) + dstPos, length, 2);
 900     }
 901 
 902     /**
 903      * Copy and unconditionally byte swap 32 bit elements from a heap array to off-heap memory
 904      *
 905      * @param src
 906      *        the source array, must be a 32-bit primitive array type
 907      * @param srcPos
 908      *        byte offset within source array of the first element to read
 909      * @param dstAddr
 910      *        destination address
 911      * @param length
 912      *        number of bytes to copy
 913      */
 914     static void copyFromIntArray(Object src, long srcPos, long dstAddr, long length) {
 915         copySwapMemory(src, unsafe.arrayBaseOffset(src.getClass()) + srcPos, null, dstAddr, length, 4);
 916     }
 917 
 918     /**
 919      * Copy and unconditionally byte swap 32 bit elements from off-heap memory to a heap array
 920      *
 921      * @param srcAddr
 922      *        source address
 923      * @param dst
 924      *        destination array, must be a 32-bit primitive array type
 925      * @param dstPos
 926      *        byte offset within the destination array of the first element to write
 927      * @param length
 928      *        number of bytes to copy
 929      */
 930     static void copyToIntArray(long srcAddr, Object dst, long dstPos, long length) {
 931         copySwapMemory(null, srcAddr, dst, unsafe.arrayBaseOffset(dst.getClass()) + dstPos, length, 4);
 932     }
 933 
 934     /**
 935      * Copy and unconditionally byte swap 64 bit elements from a heap array to off-heap memory
 936      *
 937      * @param src
 938      *        the source array, must be a 64-bit primitive array type
 939      * @param srcPos
 940      *        byte offset within source array of the first element to read
 941      * @param dstAddr
 942      *        destination address
 943      * @param length
 944      *        number of bytes to copy
 945      */
 946     static void copyFromLongArray(Object src, long srcPos, long dstAddr, long length) {
 947         copySwapMemory(src, unsafe.arrayBaseOffset(src.getClass()) + srcPos, null, dstAddr, length, 8);
 948     }
 949 
 950     /**
 951      * Copy and unconditionally byte swap 64 bit elements from off-heap memory to a heap array
 952      *
 953      * @param srcAddr
 954      *        source address
 955      * @param dst
 956      *        destination array, must be a 64-bit primitive array type
 957      * @param dstPos
 958      *        byte offset within the destination array of the first element to write
 959      * @param length
 960      *        number of bytes to copy
 961      */
 962     static void copyToLongArray(long srcAddr, Object dst, long dstPos, long length) {
 963         copySwapMemory(null, srcAddr, dst, unsafe.arrayBaseOffset(dst.getClass()) + dstPos, length, 8);
 964     }
 965 
 966     private static boolean isPrimitiveArray(Class<?> c) {
 967         Class<?> componentType = c.getComponentType();
 968         return componentType != null && componentType.isPrimitive();
 969     }
 970 
 971     private native static void copySwapMemory0(Object srcBase, long srcOffset,
 972                                         Object destBase, long destOffset,
 973                                         long bytes, long elemSize);
 974 
 975     /**
 976      * Copies all elements from one block of memory to another block,
 977      * *unconditionally* byte swapping the elements on the fly.
 978      *
 979      * <p>This method determines each block's base address by means of two parameters,
 980      * and so it provides (in effect) a <em>double-register</em> addressing mode,
 981      * as discussed in {@link sun.misc.Unsafe#getInt(Object,long)}.  When the
 982      * object reference is null, the offset supplies an absolute base address.
 983      *
 984      * @since 8u201
 985      */
 986     private static void copySwapMemory(Object srcBase, long srcOffset,
 987                                Object destBase, long destOffset,
 988                                long bytes, long elemSize) {
 989         if (bytes < 0) {
 990             throw new IllegalArgumentException();
 991         }
 992         if (elemSize != 2 && elemSize != 4 && elemSize != 8) {
 993             throw new IllegalArgumentException();
 994         }
 995         if (bytes % elemSize != 0) {
 996             throw new IllegalArgumentException();
 997         }
 998         if ((srcBase == null && srcOffset == 0) ||
 999             (destBase == null && destOffset == 0)) {
1000             throw new NullPointerException();
1001         }
1002 
1003         // Must be off-heap, or primitive heap arrays
1004         if (srcBase != null && (srcOffset < 0 || !isPrimitiveArray(srcBase.getClass()))) {
1005             throw new IllegalArgumentException();
1006         }
1007         if (destBase != null && (destOffset < 0 || !isPrimitiveArray(destBase.getClass()))) {
1008             throw new IllegalArgumentException();
1009         }
1010 
1011         // Sanity check size and offsets on 32-bit platforms. Most
1012         // significant 32 bits must be zero.
1013         if (unsafe.addressSize() == 4 &&
1014             (bytes >>> 32 != 0 || srcOffset >>> 32 != 0 || destOffset >>> 32 != 0)) {
1015             throw new IllegalArgumentException();
1016         }
1017 
1018         if (bytes == 0) {
1019             return;
1020         }
1021 
1022         copySwapMemory0(srcBase, srcOffset, destBase, destOffset, bytes, elemSize);
1023     }
1024 
1025 }