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