1 /*
   2  * Copyright (c) 2015, 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 package java.lang.invoke;
  26 
  27 import jdk.internal.misc.Unsafe;
  28 import jdk.internal.util.Preconditions;
  29 import jdk.internal.vm.annotation.ForceInline;
  30 
  31 import java.nio.ByteBuffer;
  32 import java.nio.ReadOnlyBufferException;
  33 import java.util.Objects;
  34 
  35 import static java.lang.invoke.MethodHandleStatics.UNSAFE;
  36 
  37 #warn
  38 
  39 final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
  40 
  41     static final int ALIGN = $BoxType$.BYTES - 1;
  42 
  43 #if[floatingPoint]
  44     @ForceInline
  45     static $rawType$ convEndian(boolean big, $type$ v) {
  46         $rawType$ rv = $Type$.$type$ToRaw$RawType$Bits(v);
  47         return big == BE ? rv : $RawBoxType$.reverseBytes(rv);
  48     }
  49 
  50     @ForceInline
  51     static $type$ convEndian(boolean big, $rawType$ rv) {
  52         rv = big == BE ? rv : $RawBoxType$.reverseBytes(rv);
  53         return $Type$.$rawType$BitsTo$Type$(rv);
  54     }
  55 #else[floatingPoint]
  56     @ForceInline
  57     static $type$ convEndian(boolean big, $type$ n) {
  58         return big == BE ? n : $BoxType$.reverseBytes(n);
  59     }
  60 #end[floatingPoint]
  61 
  62 
  63     private static abstract class ByteArrayViewVarHandle extends VarHandle {
  64         final boolean be;
  65 
  66         ByteArrayViewVarHandle(VarForm form, boolean be) {
  67             super(form);
  68             this.be = be;
  69         }
  70 
  71         @Override
  72         final boolean internalEquals(VarHandle vh) {
  73             ByteArrayViewVarHandle that = (ByteArrayViewVarHandle) vh;
  74             return be == that.be;
  75         }
  76 
  77         @Override
  78         final int internalHashCode() {
  79             return Boolean.hashCode(be);
  80         }
  81     }
  82 
  83     static final class ArrayHandle extends ByteArrayViewVarHandle {
  84 
  85         ArrayHandle(boolean be) {
  86             super(ArrayHandle.FORM, be);
  87         }
  88 
  89         @Override
  90         final MethodType accessModeTypeUncached(AccessMode accessMode) {
  91             return accessMode.at.accessModeType(byte[].class, $type$.class, int.class);
  92         }
  93 
  94         @ForceInline
  95         static int index(byte[] ba, int index) {
  96             return Preconditions.checkIndex(index, ba.length - ALIGN, null);
  97         }
  98 
  99         @ForceInline
 100         static long address(byte[] ba, int index) {
 101             long address = ((long) index) + Unsafe.ARRAY_BYTE_BASE_OFFSET;
 102             if ((address & ALIGN) != 0)
 103                 throw newIllegalStateExceptionForMisalignedAccess(index);
 104             return address;
 105         }
 106 
 107         @ForceInline
 108         static $type$ get(ArrayHandle handle, Object oba, int index) {
 109             byte[] ba = (byte[]) oba;
 110 #if[floatingPoint]
 111             $rawType$ rawValue = UNSAFE.get$RawType$Unaligned(
 112                     ba,
 113                     ((long) index(ba, index)) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
 114                     handle.be);
 115             return $Type$.$rawType$BitsTo$Type$(rawValue);
 116 #else[floatingPoint]
 117             return UNSAFE.get$Type$Unaligned(
 118                     ba,
 119                     ((long) index(ba, index)) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
 120                     handle.be);
 121 #end[floatingPoint]
 122         }
 123 
 124         @ForceInline
 125         static void set(ArrayHandle handle, Object oba, int index, $type$ value) {
 126             byte[] ba = (byte[]) oba;
 127 #if[floatingPoint]
 128             UNSAFE.put$RawType$Unaligned(
 129                     ba,
 130                     ((long) index(ba, index)) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
 131                     $Type$.$type$ToRaw$RawType$Bits(value),
 132                     handle.be);
 133 #else[floatingPoint]
 134             UNSAFE.put$RawType$Unaligned(
 135                     ba,
 136                     ((long) index(ba, index)) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
 137                     value,
 138                     handle.be);
 139 #end[floatingPoint]
 140         }
 141 
 142         @ForceInline
 143         static $type$ getVolatile(ArrayHandle handle, Object oba, int index) {
 144             byte[] ba = (byte[]) oba;
 145             return convEndian(handle.be,
 146                               UNSAFE.get$RawType$Volatile(
 147                                       ba,
 148                                       address(ba, index(ba, index))));
 149         }
 150 
 151         @ForceInline
 152         static void setVolatile(ArrayHandle handle, Object oba, int index, $type$ value) {
 153             byte[] ba = (byte[]) oba;
 154             UNSAFE.put$RawType$Volatile(
 155                     ba,
 156                     address(ba, index(ba, index)),
 157                     convEndian(handle.be, value));
 158         }
 159 
 160         @ForceInline
 161         static $type$ getAcquire(ArrayHandle handle, Object oba, int index) {
 162             byte[] ba = (byte[]) oba;
 163             return convEndian(handle.be,
 164                               UNSAFE.get$RawType$Acquire(
 165                                       ba,
 166                                       address(ba, index(ba, index))));
 167         }
 168 
 169         @ForceInline
 170         static void setRelease(ArrayHandle handle, Object oba, int index, $type$ value) {
 171             byte[] ba = (byte[]) oba;
 172             UNSAFE.put$RawType$Release(
 173                     ba,
 174                     address(ba, index(ba, index)),
 175                     convEndian(handle.be, value));
 176         }
 177 
 178         @ForceInline
 179         static $type$ getOpaque(ArrayHandle handle, Object oba, int index) {
 180             byte[] ba = (byte[]) oba;
 181             return convEndian(handle.be,
 182                               UNSAFE.get$RawType$Opaque(
 183                                       ba,
 184                                       address(ba, index(ba, index))));
 185         }
 186 
 187         @ForceInline
 188         static void setOpaque(ArrayHandle handle, Object oba, int index, $type$ value) {
 189             byte[] ba = (byte[]) oba;
 190             UNSAFE.put$RawType$Opaque(
 191                     ba,
 192                     address(ba, index(ba, index)),
 193                     convEndian(handle.be, value));
 194         }
 195 #if[CAS]
 196 
 197         @ForceInline
 198         static boolean compareAndSet(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
 199             byte[] ba = (byte[]) oba;
 200 #if[Object]
 201             return UNSAFE.compareAndSetReference(
 202                     ba,
 203                     address(ba, index(ba, index)),
 204                     convEndian(handle.be, expected), convEndian(handle.be, value));
 205 #else[Object]
 206             return UNSAFE.compareAndSet$RawType$(
 207                     ba,
 208                     address(ba, index(ba, index)),
 209                     convEndian(handle.be, expected), convEndian(handle.be, value));
 210 #end[Object]
 211         }
 212 
 213         @ForceInline
 214         static $type$ compareAndExchange(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
 215             byte[] ba = (byte[]) oba;
 216             return convEndian(handle.be,
 217                               UNSAFE.compareAndExchange$RawType$(
 218                                       ba,
 219                                       address(ba, index(ba, index)),
 220                                       convEndian(handle.be, expected), convEndian(handle.be, value)));
 221         }
 222 
 223         @ForceInline
 224         static $type$ compareAndExchangeAcquire(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
 225             byte[] ba = (byte[]) oba;
 226             return convEndian(handle.be,
 227                               UNSAFE.compareAndExchange$RawType$Acquire(
 228                                       ba,
 229                                       address(ba, index(ba, index)),
 230                                       convEndian(handle.be, expected), convEndian(handle.be, value)));
 231         }
 232 
 233         @ForceInline
 234         static $type$ compareAndExchangeRelease(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
 235             byte[] ba = (byte[]) oba;
 236             return convEndian(handle.be,
 237                               UNSAFE.compareAndExchange$RawType$Release(
 238                                       ba,
 239                                       address(ba, index(ba, index)),
 240                                       convEndian(handle.be, expected), convEndian(handle.be, value)));
 241         }
 242 
 243         @ForceInline
 244         static boolean weakCompareAndSetPlain(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
 245             byte[] ba = (byte[]) oba;
 246             return UNSAFE.weakCompareAndSet$RawType$Plain(
 247                     ba,
 248                     address(ba, index(ba, index)),
 249                     convEndian(handle.be, expected), convEndian(handle.be, value));
 250         }
 251 
 252         @ForceInline
 253         static boolean weakCompareAndSet(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
 254             byte[] ba = (byte[]) oba;
 255             return UNSAFE.weakCompareAndSet$RawType$(
 256                     ba,
 257                     address(ba, index(ba, index)),
 258                     convEndian(handle.be, expected), convEndian(handle.be, value));
 259         }
 260 
 261         @ForceInline
 262         static boolean weakCompareAndSetAcquire(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
 263             byte[] ba = (byte[]) oba;
 264             return UNSAFE.weakCompareAndSet$RawType$Acquire(
 265                     ba,
 266                     address(ba, index(ba, index)),
 267                     convEndian(handle.be, expected), convEndian(handle.be, value));
 268         }
 269 
 270         @ForceInline
 271         static boolean weakCompareAndSetRelease(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
 272             byte[] ba = (byte[]) oba;
 273             return UNSAFE.weakCompareAndSet$RawType$Release(
 274                     ba,
 275                     address(ba, index(ba, index)),
 276                     convEndian(handle.be, expected), convEndian(handle.be, value));
 277         }
 278 
 279         @ForceInline
 280         static $type$ getAndSet(ArrayHandle handle, Object oba, int index, $type$ value) {
 281             byte[] ba = (byte[]) oba;
 282 #if[Object]
 283             return convEndian(handle.be,
 284                               UNSAFE.getAndSetReference(
 285                                       ba,
 286                                       address(ba, index(ba, index)),
 287                                       convEndian(handle.be, value)));
 288 #else[Object]
 289             return convEndian(handle.be,
 290                               UNSAFE.getAndSet$RawType$(
 291                                       ba,
 292                                       address(ba, index(ba, index)),
 293                                       convEndian(handle.be, value)));
 294 #end[Object]
 295         }
 296 
 297         @ForceInline
 298         static $type$ getAndSetAcquire(ArrayHandle handle, Object oba, int index, $type$ value) {
 299             byte[] ba = (byte[]) oba;
 300             return convEndian(handle.be,
 301                               UNSAFE.getAndSet$RawType$Acquire(
 302                                       ba,
 303                                       address(ba, index(ba, index)),
 304                                       convEndian(handle.be, value)));
 305         }
 306 
 307         @ForceInline
 308         static $type$ getAndSetRelease(ArrayHandle handle, Object oba, int index, $type$ value) {
 309             byte[] ba = (byte[]) oba;
 310             return convEndian(handle.be,
 311                               UNSAFE.getAndSet$RawType$Release(
 312                                       ba,
 313                                       address(ba, index(ba, index)),
 314                                       convEndian(handle.be, value)));
 315         }
 316 #end[CAS]
 317 #if[AtomicAdd]
 318 
 319         @ForceInline
 320         static $type$ getAndAdd(ArrayHandle handle, Object oba, int index, $type$ delta) {
 321             byte[] ba = (byte[]) oba;
 322             if (handle.be == BE) {
 323                 return UNSAFE.getAndAdd$RawType$(
 324                         ba,
 325                         address(ba, index(ba, index)),
 326                         delta);
 327             } else {
 328                 return getAndAddConvEndianWithCAS(ba, index, delta);
 329             }
 330         }
 331 
 332         @ForceInline
 333         static $type$ getAndAddAcquire(ArrayHandle handle, Object oba, int index, $type$ delta) {
 334             byte[] ba = (byte[]) oba;
 335             if (handle.be == BE) {
 336                 return UNSAFE.getAndAdd$RawType$Acquire(
 337                         ba,
 338                         address(ba, index(ba, index)),
 339                         delta);
 340             } else {
 341                 return getAndAddConvEndianWithCAS(ba, index, delta);
 342             }
 343         }
 344 
 345         @ForceInline
 346         static $type$ getAndAddRelease(ArrayHandle handle, Object oba, int index, $type$ delta) {
 347             byte[] ba = (byte[]) oba;
 348             if (handle.be == BE) {
 349                 return UNSAFE.getAndAdd$RawType$Release(
 350                         ba,
 351                         address(ba, index(ba, index)),
 352                         delta);
 353             } else {
 354                 return getAndAddConvEndianWithCAS(ba, index, delta);
 355             }
 356         }
 357 
 358         @ForceInline
 359         static $type$ getAndAddConvEndianWithCAS(byte[] ba, int index, $type$ delta) {
 360             $type$ nativeExpectedValue, expectedValue;
 361             long offset = address(ba, index(ba, index));
 362             do {
 363                 nativeExpectedValue = UNSAFE.get$RawType$Volatile(ba, offset);
 364                 expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue);
 365             } while (!UNSAFE.weakCompareAndSet$RawType$(ba, offset,
 366                     nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue + delta)));
 367             return expectedValue;
 368         }
 369 #end[AtomicAdd]
 370 #if[Bitwise]
 371 
 372         @ForceInline
 373         static $type$ getAndBitwiseOr(ArrayHandle handle, Object oba, int index, $type$ value) {
 374             byte[] ba = (byte[]) oba;
 375             if (handle.be == BE) {
 376                 return UNSAFE.getAndBitwiseOr$RawType$(
 377                         ba,
 378                         address(ba, index(ba, index)),
 379                         value);
 380             } else {
 381                 return getAndBitwiseOrConvEndianWithCAS(ba, index, value);
 382             }
 383         }
 384 
 385         @ForceInline
 386         static $type$ getAndBitwiseOrRelease(ArrayHandle handle, Object oba, int index, $type$ value) {
 387             byte[] ba = (byte[]) oba;
 388             if (handle.be == BE) {
 389                 return UNSAFE.getAndBitwiseOr$RawType$Release(
 390                         ba,
 391                         address(ba, index(ba, index)),
 392                         value);
 393             } else {
 394                 return getAndBitwiseOrConvEndianWithCAS(ba, index, value);
 395             }
 396         }
 397 
 398         @ForceInline
 399         static $type$ getAndBitwiseOrAcquire(ArrayHandle handle, Object oba, int index, $type$ value) {
 400             byte[] ba = (byte[]) oba;
 401             if (handle.be == BE) {
 402                 return UNSAFE.getAndBitwiseOr$RawType$Acquire(
 403                         ba,
 404                         address(ba, index(ba, index)),
 405                         value);
 406             } else {
 407                 return getAndBitwiseOrConvEndianWithCAS(ba, index, value);
 408             }
 409         }
 410 
 411         @ForceInline
 412         static $type$ getAndBitwiseOrConvEndianWithCAS(byte[] ba, int index, $type$ value) {
 413             $type$ nativeExpectedValue, expectedValue;
 414             long offset = address(ba, index(ba, index));
 415             do {
 416                 nativeExpectedValue = UNSAFE.get$RawType$Volatile(ba, offset);
 417                 expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue);
 418             } while (!UNSAFE.weakCompareAndSet$RawType$(ba, offset,
 419                     nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue | value)));
 420             return expectedValue;
 421         }
 422 
 423         @ForceInline
 424         static $type$ getAndBitwiseAnd(ArrayHandle handle, Object oba, int index, $type$ value) {
 425             byte[] ba = (byte[]) oba;
 426             if (handle.be == BE) {
 427                 return UNSAFE.getAndBitwiseAnd$RawType$(
 428                         ba,
 429                         address(ba, index(ba, index)),
 430                         value);
 431             } else {
 432                 return getAndBitwiseAndConvEndianWithCAS(ba, index, value);
 433             }
 434         }
 435 
 436         @ForceInline
 437         static $type$ getAndBitwiseAndRelease(ArrayHandle handle, Object oba, int index, $type$ value) {
 438             byte[] ba = (byte[]) oba;
 439             if (handle.be == BE) {
 440                 return UNSAFE.getAndBitwiseAnd$RawType$Release(
 441                         ba,
 442                         address(ba, index(ba, index)),
 443                         value);
 444             } else {
 445                 return getAndBitwiseAndConvEndianWithCAS(ba, index, value);
 446             }
 447         }
 448 
 449         @ForceInline
 450         static $type$ getAndBitwiseAndAcquire(ArrayHandle handle, Object oba, int index, $type$ value) {
 451             byte[] ba = (byte[]) oba;
 452             if (handle.be == BE) {
 453                 return UNSAFE.getAndBitwiseAnd$RawType$Acquire(
 454                         ba,
 455                         address(ba, index(ba, index)),
 456                         value);
 457             } else {
 458                 return getAndBitwiseAndConvEndianWithCAS(ba, index, value);
 459             }
 460         }
 461 
 462         @ForceInline
 463         static $type$ getAndBitwiseAndConvEndianWithCAS(byte[] ba, int index, $type$ value) {
 464             $type$ nativeExpectedValue, expectedValue;
 465             long offset = address(ba, index(ba, index));
 466             do {
 467                 nativeExpectedValue = UNSAFE.get$RawType$Volatile(ba, offset);
 468                 expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue);
 469             } while (!UNSAFE.weakCompareAndSet$RawType$(ba, offset,
 470                     nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue & value)));
 471             return expectedValue;
 472         }
 473 
 474         @ForceInline
 475         static $type$ getAndBitwiseXor(ArrayHandle handle, Object oba, int index, $type$ value) {
 476             byte[] ba = (byte[]) oba;
 477             if (handle.be == BE) {
 478                 return UNSAFE.getAndBitwiseXor$RawType$(
 479                         ba,
 480                         address(ba, index(ba, index)),
 481                         value);
 482             } else {
 483                 return getAndBitwiseXorConvEndianWithCAS(ba, index, value);
 484             }
 485         }
 486 
 487         @ForceInline
 488         static $type$ getAndBitwiseXorRelease(ArrayHandle handle, Object oba, int index, $type$ value) {
 489             byte[] ba = (byte[]) oba;
 490             if (handle.be == BE) {
 491                 return UNSAFE.getAndBitwiseXor$RawType$Release(
 492                         ba,
 493                         address(ba, index(ba, index)),
 494                         value);
 495             } else {
 496                 return getAndBitwiseXorConvEndianWithCAS(ba, index, value);
 497             }
 498         }
 499 
 500         @ForceInline
 501         static $type$ getAndBitwiseXorAcquire(ArrayHandle handle, Object oba, int index, $type$ value) {
 502             byte[] ba = (byte[]) oba;
 503             if (handle.be == BE) {
 504                 return UNSAFE.getAndBitwiseXor$RawType$Acquire(
 505                         ba,
 506                         address(ba, index(ba, index)),
 507                         value);
 508             } else {
 509                 return getAndBitwiseXorConvEndianWithCAS(ba, index, value);
 510             }
 511         }
 512 
 513         @ForceInline
 514         static $type$ getAndBitwiseXorConvEndianWithCAS(byte[] ba, int index, $type$ value) {
 515             $type$ nativeExpectedValue, expectedValue;
 516             long offset = address(ba, index(ba, index));
 517             do {
 518                 nativeExpectedValue = UNSAFE.get$RawType$Volatile(ba, offset);
 519                 expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue);
 520             } while (!UNSAFE.weakCompareAndSet$RawType$(ba, offset,
 521                     nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue ^ value)));
 522             return expectedValue;
 523         }
 524 #end[Bitwise]
 525 
 526         static final VarForm FORM = new VarForm(ArrayHandle.class, byte[].class, $type$.class, int.class);
 527     }
 528 
 529 
 530     static final class ByteBufferHandle extends ByteArrayViewVarHandle {
 531 
 532         ByteBufferHandle(boolean be) {
 533             super(ByteBufferHandle.FORM, be);
 534         }
 535 
 536         @Override
 537         final MethodType accessModeTypeUncached(AccessMode accessMode) {
 538             return accessMode.at.accessModeType(ByteBuffer.class, $type$.class, int.class);
 539         }
 540 
 541         @ForceInline
 542         static int index(ByteBuffer bb, int index) {
 543             return Preconditions.checkIndex(index, UNSAFE.getInt(bb, BUFFER_LIMIT) - ALIGN, null);
 544         }
 545 
 546         @ForceInline
 547         static int indexRO(ByteBuffer bb, int index) {
 548             if (UNSAFE.getBoolean(bb, BYTE_BUFFER_IS_READ_ONLY))
 549                 throw new ReadOnlyBufferException();
 550             return Preconditions.checkIndex(index, UNSAFE.getInt(bb, BUFFER_LIMIT) - ALIGN, null);
 551         }
 552 
 553         @ForceInline
 554         static long address(ByteBuffer bb, int index) {
 555             long address = ((long) index) + UNSAFE.getLong(bb, BUFFER_ADDRESS);
 556             if ((address & ALIGN) != 0)
 557                 throw newIllegalStateExceptionForMisalignedAccess(index);
 558             return address;
 559         }
 560 
 561         @ForceInline
 562         static $type$ get(ByteBufferHandle handle, Object obb, int index) {
 563             ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
 564 #if[floatingPoint]
 565             $rawType$ rawValue = UNSAFE.get$RawType$Unaligned(
 566                     UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 567                     ((long) index(bb, index)) + UNSAFE.getLong(bb, BUFFER_ADDRESS),
 568                     handle.be);
 569             return $Type$.$rawType$BitsTo$Type$(rawValue);
 570 #else[floatingPoint]
 571             return UNSAFE.get$Type$Unaligned(
 572                     UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 573                     ((long) index(bb, index)) + UNSAFE.getLong(bb, BUFFER_ADDRESS),
 574                     handle.be);
 575 #end[floatingPoint]
 576         }
 577 
 578         @ForceInline
 579         static void set(ByteBufferHandle handle, Object obb, int index, $type$ value) {
 580             ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
 581 #if[floatingPoint]
 582             UNSAFE.put$RawType$Unaligned(
 583                     UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 584                     ((long) indexRO(bb, index)) + UNSAFE.getLong(bb, BUFFER_ADDRESS),
 585                     $Type$.$type$ToRaw$RawType$Bits(value),
 586                     handle.be);
 587 #else[floatingPoint]
 588             UNSAFE.put$Type$Unaligned(
 589                     UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 590                     ((long) indexRO(bb, index)) + UNSAFE.getLong(bb, BUFFER_ADDRESS),
 591                     value,
 592                     handle.be);
 593 #end[floatingPoint]
 594         }
 595 
 596         @ForceInline
 597         static $type$ getVolatile(ByteBufferHandle handle, Object obb, int index) {
 598             ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
 599             return convEndian(handle.be,
 600                               UNSAFE.get$RawType$Volatile(
 601                                       UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 602                                       address(bb, index(bb, index))));
 603         }
 604 
 605         @ForceInline
 606         static void setVolatile(ByteBufferHandle handle, Object obb, int index, $type$ value) {
 607             ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
 608             UNSAFE.put$RawType$Volatile(
 609                     UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 610                     address(bb, indexRO(bb, index)),
 611                     convEndian(handle.be, value));
 612         }
 613 
 614         @ForceInline
 615         static $type$ getAcquire(ByteBufferHandle handle, Object obb, int index) {
 616             ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
 617             return convEndian(handle.be,
 618                               UNSAFE.get$RawType$Acquire(
 619                                       UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 620                                       address(bb, index(bb, index))));
 621         }
 622 
 623         @ForceInline
 624         static void setRelease(ByteBufferHandle handle, Object obb, int index, $type$ value) {
 625             ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
 626             UNSAFE.put$RawType$Release(
 627                     UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 628                     address(bb, indexRO(bb, index)),
 629                     convEndian(handle.be, value));
 630         }
 631 
 632         @ForceInline
 633         static $type$ getOpaque(ByteBufferHandle handle, Object obb, int index) {
 634             ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
 635             return convEndian(handle.be,
 636                               UNSAFE.get$RawType$Opaque(
 637                                       UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 638                                       address(bb, index(bb, index))));
 639         }
 640 
 641         @ForceInline
 642         static void setOpaque(ByteBufferHandle handle, Object obb, int index, $type$ value) {
 643             ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
 644             UNSAFE.put$RawType$Opaque(
 645                     UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 646                     address(bb, indexRO(bb, index)),
 647                     convEndian(handle.be, value));
 648         }
 649 #if[CAS]
 650 
 651         @ForceInline
 652         static boolean compareAndSet(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
 653             ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
 654 #if[Object]
 655             return UNSAFE.compareAndSetReference(
 656                     UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 657                     address(bb, indexRO(bb, index)),
 658                     convEndian(handle.be, expected), convEndian(handle.be, value));
 659 #else[Object]
 660             return UNSAFE.compareAndSet$RawType$(
 661                     UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 662                     address(bb, indexRO(bb, index)),
 663                     convEndian(handle.be, expected), convEndian(handle.be, value));
 664 #end[Object]
 665         }
 666 
 667         @ForceInline
 668         static $type$ compareAndExchange(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
 669             ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
 670             return convEndian(handle.be,
 671                               UNSAFE.compareAndExchange$RawType$(
 672                                       UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 673                                       address(bb, indexRO(bb, index)),
 674                                       convEndian(handle.be, expected), convEndian(handle.be, value)));
 675         }
 676 
 677         @ForceInline
 678         static $type$ compareAndExchangeAcquire(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
 679             ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
 680             return convEndian(handle.be,
 681                               UNSAFE.compareAndExchange$RawType$Acquire(
 682                                       UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 683                                       address(bb, indexRO(bb, index)),
 684                                       convEndian(handle.be, expected), convEndian(handle.be, value)));
 685         }
 686 
 687         @ForceInline
 688         static $type$ compareAndExchangeRelease(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
 689             ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
 690             return convEndian(handle.be,
 691                               UNSAFE.compareAndExchange$RawType$Release(
 692                                       UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 693                                       address(bb, indexRO(bb, index)),
 694                                       convEndian(handle.be, expected), convEndian(handle.be, value)));
 695         }
 696 
 697         @ForceInline
 698         static boolean weakCompareAndSetPlain(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
 699             ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
 700             return UNSAFE.weakCompareAndSet$RawType$Plain(
 701                     UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 702                     address(bb, indexRO(bb, index)),
 703                     convEndian(handle.be, expected), convEndian(handle.be, value));
 704         }
 705 
 706         @ForceInline
 707         static boolean weakCompareAndSet(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
 708             ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
 709             return UNSAFE.weakCompareAndSet$RawType$(
 710                     UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 711                     address(bb, indexRO(bb, index)),
 712                     convEndian(handle.be, expected), convEndian(handle.be, value));
 713         }
 714 
 715         @ForceInline
 716         static boolean weakCompareAndSetAcquire(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
 717             ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
 718             return UNSAFE.weakCompareAndSet$RawType$Acquire(
 719                     UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 720                     address(bb, indexRO(bb, index)),
 721                     convEndian(handle.be, expected), convEndian(handle.be, value));
 722         }
 723 
 724         @ForceInline
 725         static boolean weakCompareAndSetRelease(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
 726             ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
 727             return UNSAFE.weakCompareAndSet$RawType$Release(
 728                     UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 729                     address(bb, indexRO(bb, index)),
 730                     convEndian(handle.be, expected), convEndian(handle.be, value));
 731         }
 732 
 733         @ForceInline
 734         static $type$ getAndSet(ByteBufferHandle handle, Object obb, int index, $type$ value) {
 735             ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
 736 #if[Object]
 737             return convEndian(handle.be,
 738                               UNSAFE.getAndSetReference(
 739                                       UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 740                                       address(bb, indexRO(bb, index)),
 741                                       convEndian(handle.be, value)));
 742 #else[Object]
 743             return convEndian(handle.be,
 744                               UNSAFE.getAndSet$RawType$(
 745                                       UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 746                                       address(bb, indexRO(bb, index)),
 747                                       convEndian(handle.be, value)));
 748 #end[Object]
 749         }
 750 
 751         @ForceInline
 752         static $type$ getAndSetAcquire(ByteBufferHandle handle, Object obb, int index, $type$ value) {
 753             ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
 754             return convEndian(handle.be,
 755                               UNSAFE.getAndSet$RawType$Acquire(
 756                                       UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 757                                       address(bb, indexRO(bb, index)),
 758                                       convEndian(handle.be, value)));
 759         }
 760 
 761         @ForceInline
 762         static $type$ getAndSetRelease(ByteBufferHandle handle, Object obb, int index, $type$ value) {
 763             ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
 764             return convEndian(handle.be,
 765                               UNSAFE.getAndSet$RawType$Release(
 766                                       UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 767                                       address(bb, indexRO(bb, index)),
 768                                       convEndian(handle.be, value)));
 769         }
 770 #end[CAS]
 771 #if[AtomicAdd]
 772 
 773         @ForceInline
 774         static $type$ getAndAdd(ByteBufferHandle handle, Object obb, int index, $type$ delta) {
 775             ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
 776             if (handle.be == BE) {
 777                 return UNSAFE.getAndAdd$RawType$(
 778                         UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 779                         address(bb, indexRO(bb, index)),
 780                         delta);
 781             } else {
 782                 return getAndAddConvEndianWithCAS(bb, index, delta);
 783             }
 784         }
 785 
 786         @ForceInline
 787         static $type$ getAndAddAcquire(ByteBufferHandle handle, Object obb, int index, $type$ delta) {
 788             ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
 789             if (handle.be == BE) {
 790                 return UNSAFE.getAndAdd$RawType$Acquire(
 791                         UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 792                         address(bb, indexRO(bb, index)),
 793                         delta);
 794             } else {
 795                 return getAndAddConvEndianWithCAS(bb, index, delta);
 796             }
 797         }
 798 
 799         @ForceInline
 800         static $type$ getAndAddRelease(ByteBufferHandle handle, Object obb, int index, $type$ delta) {
 801             ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
 802             if (handle.be == BE) {
 803                 return UNSAFE.getAndAdd$RawType$Release(
 804                         UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 805                         address(bb, indexRO(bb, index)),
 806                         delta);
 807             } else {
 808                 return getAndAddConvEndianWithCAS(bb, index, delta);
 809             }
 810         }
 811 
 812         @ForceInline
 813         static $type$ getAndAddConvEndianWithCAS(ByteBuffer bb, int index, $type$ delta) {
 814             $type$ nativeExpectedValue, expectedValue;
 815             Object base = UNSAFE.getReference(bb, BYTE_BUFFER_HB);
 816             long offset = address(bb, indexRO(bb, index));
 817             do {
 818                 nativeExpectedValue = UNSAFE.get$RawType$Volatile(base, offset);
 819                 expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue);
 820             } while (!UNSAFE.weakCompareAndSet$RawType$(base, offset,
 821                     nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue + delta)));
 822             return expectedValue;
 823         }
 824 #end[AtomicAdd]
 825 #if[Bitwise]
 826 
 827         @ForceInline
 828         static $type$ getAndBitwiseOr(ByteBufferHandle handle, Object obb, int index, $type$ value) {
 829             ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
 830             if (handle.be == BE) {
 831                 return UNSAFE.getAndBitwiseOr$RawType$(
 832                         UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 833                         address(bb, indexRO(bb, index)),
 834                         value);
 835             } else {
 836                 return getAndBitwiseOrConvEndianWithCAS(bb, index, value);
 837             }
 838         }
 839 
 840         @ForceInline
 841         static $type$ getAndBitwiseOrRelease(ByteBufferHandle handle, Object obb, int index, $type$ value) {
 842             ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
 843             if (handle.be == BE) {
 844                 return UNSAFE.getAndBitwiseOr$RawType$Release(
 845                         UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 846                         address(bb, indexRO(bb, index)),
 847                         value);
 848             } else {
 849                 return getAndBitwiseOrConvEndianWithCAS(bb, index, value);
 850             }
 851         }
 852 
 853         @ForceInline
 854         static $type$ getAndBitwiseOrAcquire(ByteBufferHandle handle, Object obb, int index, $type$ value) {
 855             ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
 856             if (handle.be == BE) {
 857                 return UNSAFE.getAndBitwiseOr$RawType$Acquire(
 858                         UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 859                         address(bb, indexRO(bb, index)),
 860                         value);
 861             } else {
 862                 return getAndBitwiseOrConvEndianWithCAS(bb, index, value);
 863             }
 864         }
 865 
 866         @ForceInline
 867         static $type$ getAndBitwiseOrConvEndianWithCAS(ByteBuffer bb, int index, $type$ value) {
 868             $type$ nativeExpectedValue, expectedValue;
 869             Object base = UNSAFE.getReference(bb, BYTE_BUFFER_HB);
 870             long offset = address(bb, indexRO(bb, index));
 871             do {
 872                 nativeExpectedValue = UNSAFE.get$RawType$Volatile(base, offset);
 873                 expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue);
 874             } while (!UNSAFE.weakCompareAndSet$RawType$(base, offset,
 875                     nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue | value)));
 876             return expectedValue;
 877         }
 878 
 879         @ForceInline
 880         static $type$ getAndBitwiseAnd(ByteBufferHandle handle, Object obb, int index, $type$ value) {
 881             ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
 882             if (handle.be == BE) {
 883                 return UNSAFE.getAndBitwiseAnd$RawType$(
 884                         UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 885                         address(bb, indexRO(bb, index)),
 886                         value);
 887             } else {
 888                 return getAndBitwiseAndConvEndianWithCAS(bb, index, value);
 889             }
 890         }
 891 
 892         @ForceInline
 893         static $type$ getAndBitwiseAndRelease(ByteBufferHandle handle, Object obb, int index, $type$ value) {
 894             ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
 895             if (handle.be == BE) {
 896                 return UNSAFE.getAndBitwiseAnd$RawType$Release(
 897                         UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 898                         address(bb, indexRO(bb, index)),
 899                         value);
 900             } else {
 901                 return getAndBitwiseAndConvEndianWithCAS(bb, index, value);
 902             }
 903         }
 904 
 905         @ForceInline
 906         static $type$ getAndBitwiseAndAcquire(ByteBufferHandle handle, Object obb, int index, $type$ value) {
 907             ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
 908             if (handle.be == BE) {
 909                 return UNSAFE.getAndBitwiseAnd$RawType$Acquire(
 910                         UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 911                         address(bb, indexRO(bb, index)),
 912                         value);
 913             } else {
 914                 return getAndBitwiseAndConvEndianWithCAS(bb, index, value);
 915             }
 916         }
 917 
 918         @ForceInline
 919         static $type$ getAndBitwiseAndConvEndianWithCAS(ByteBuffer bb, int index, $type$ value) {
 920             $type$ nativeExpectedValue, expectedValue;
 921             Object base = UNSAFE.getReference(bb, BYTE_BUFFER_HB);
 922             long offset = address(bb, indexRO(bb, index));
 923             do {
 924                 nativeExpectedValue = UNSAFE.get$RawType$Volatile(base, offset);
 925                 expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue);
 926             } while (!UNSAFE.weakCompareAndSet$RawType$(base, offset,
 927                     nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue & value)));
 928             return expectedValue;
 929         }
 930 
 931 
 932         @ForceInline
 933         static $type$ getAndBitwiseXor(ByteBufferHandle handle, Object obb, int index, $type$ value) {
 934             ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
 935             if (handle.be == BE) {
 936                 return UNSAFE.getAndBitwiseXor$RawType$(
 937                         UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 938                         address(bb, indexRO(bb, index)),
 939                         value);
 940             } else {
 941                 return getAndBitwiseXorConvEndianWithCAS(bb, index, value);
 942             }
 943         }
 944 
 945         @ForceInline
 946         static $type$ getAndBitwiseXorRelease(ByteBufferHandle handle, Object obb, int index, $type$ value) {
 947             ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
 948             if (handle.be == BE) {
 949                 return UNSAFE.getAndBitwiseXor$RawType$Release(
 950                         UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 951                         address(bb, indexRO(bb, index)),
 952                         value);
 953             } else {
 954                 return getAndBitwiseXorConvEndianWithCAS(bb, index, value);
 955             }
 956         }
 957 
 958         @ForceInline
 959         static $type$ getAndBitwiseXorAcquire(ByteBufferHandle handle, Object obb, int index, $type$ value) {
 960             ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
 961             if (handle.be == BE) {
 962                 return UNSAFE.getAndBitwiseXor$RawType$Acquire(
 963                         UNSAFE.getReference(bb, BYTE_BUFFER_HB),
 964                         address(bb, indexRO(bb, index)),
 965                         value);
 966             } else {
 967                 return getAndBitwiseXorConvEndianWithCAS(bb, index, value);
 968             }
 969         }
 970 
 971         @ForceInline
 972         static $type$ getAndBitwiseXorConvEndianWithCAS(ByteBuffer bb, int index, $type$ value) {
 973             $type$ nativeExpectedValue, expectedValue;
 974             Object base = UNSAFE.getReference(bb, BYTE_BUFFER_HB);
 975             long offset = address(bb, indexRO(bb, index));
 976             do {
 977                 nativeExpectedValue = UNSAFE.get$RawType$Volatile(base, offset);
 978                 expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue);
 979             } while (!UNSAFE.weakCompareAndSet$RawType$(base, offset,
 980                     nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue ^ value)));
 981             return expectedValue;
 982         }
 983 #end[Bitwise]
 984 
 985         static final VarForm FORM = new VarForm(ByteBufferHandle.class, ByteBuffer.class, $type$.class, int.class);
 986     }
 987 }