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