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