1 /*
   2  * Copyright (c) 2015, 2019, 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, false);
  49         }
  50 
  51         protected FieldInstanceReadOnly(Class<?> receiverType, long fieldOffset{#if[Object]?, Class<?> fieldType},
  52                                         VarForm form, boolean exact) {
  53             super(form, exact);
  54             this.fieldOffset = fieldOffset;
  55             this.receiverType = receiverType;
  56 #if[Object]
  57             this.fieldType = fieldType;
  58 #end[Object]
  59         }
  60 
  61         @Override
  62         public FieldInstanceReadOnly withInvokeExactBehavior() {
  63             return hasInvokeExactBehavior()
  64                 ? this
  65                 : new FieldInstanceReadOnly(receiverType, fieldOffset{#if[Object]?, fieldType}, vform, true);
  66         }
  67 
  68         @Override
  69         public FieldInstanceReadOnly withInvokeBehavior() {
  70             return !hasInvokeExactBehavior()
  71                 ? this
  72                 : new FieldInstanceReadOnly(receiverType, fieldOffset{#if[Object]?, fieldType}, vform, false);
  73         }
  74 
  75         @Override
  76         final MethodType accessModeTypeUncached(AccessType at) {
  77             return at.accessModeType(receiverType, {#if[Object]?fieldType:$type$.class});
  78         }
  79 
  80         @Override
  81         public Optional<VarHandleDesc> describeConstable() {
  82             var receiverTypeRef = receiverType.describeConstable();
  83             var fieldTypeRef = {#if[Object]?fieldType:$type$.class}.describeConstable();
  84             if (!receiverTypeRef.isPresent() || !fieldTypeRef.isPresent())
  85                 return Optional.empty();
  86 
  87             // Reflect on this VarHandle to extract the field name
  88             String name = VarHandles.getFieldFromReceiverAndOffset(
  89                 receiverType, fieldOffset, {#if[Object]?fieldType:$type$.class}).getName();
  90             return Optional.of(VarHandleDesc.ofField(receiverTypeRef.get(), name, fieldTypeRef.get()));
  91         }
  92 
  93         @ForceInline
  94         static $type$ get(VarHandle ob, Object holder) {
  95             FieldInstanceReadOnly handle = (FieldInstanceReadOnly)ob;
  96             return UNSAFE.get$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
  97                                  handle.fieldOffset{#if[Value]?, handle.fieldType});
  98         }
  99 
 100         @ForceInline
 101         static $type$ getVolatile(VarHandle ob, Object holder) {
 102             FieldInstanceReadOnly handle = (FieldInstanceReadOnly)ob;
 103             return UNSAFE.get$Type$Volatile(Objects.requireNonNull(handle.receiverType.cast(holder)),
 104                                  handle.fieldOffset{#if[Value]?, handle.fieldType});
 105         }
 106 
 107         @ForceInline
 108         static $type$ getOpaque(VarHandle ob, Object holder) {
 109             FieldInstanceReadOnly handle = (FieldInstanceReadOnly)ob;
 110             return UNSAFE.get$Type$Opaque(Objects.requireNonNull(handle.receiverType.cast(holder)),
 111                                  handle.fieldOffset{#if[Value]?, handle.fieldType});
 112         }
 113 
 114         @ForceInline
 115         static $type$ getAcquire(VarHandle ob, Object holder) {
 116             FieldInstanceReadOnly handle = (FieldInstanceReadOnly)ob;
 117             return UNSAFE.get$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)),
 118                                  handle.fieldOffset{#if[Value]?, handle.fieldType});
 119         }
 120 
 121         static final VarForm FORM = new VarForm(FieldInstanceReadOnly.class, Object.class, $type$.class);
 122     }
 123 
 124     static final class FieldInstanceReadWrite extends FieldInstanceReadOnly {
 125         FieldInstanceReadWrite(Class<?> receiverType, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
 126             this(receiverType, fieldOffset{#if[Object]?, fieldType}, false);
 127         }
 128 
 129         private FieldInstanceReadWrite(Class<?> receiverType, long fieldOffset{#if[Object]?, Class<?> fieldType},
 130                                        boolean exact) {
 131             super(receiverType, fieldOffset{#if[Object]?, fieldType}, FieldInstanceReadWrite.FORM, exact);
 132         }
 133 
 134         @Override
 135         public FieldInstanceReadWrite withInvokeExactBehavior() {
 136             return hasInvokeExactBehavior()
 137                 ? this
 138                 : new FieldInstanceReadWrite(receiverType, fieldOffset{#if[Object]?, fieldType}, true);
 139         }
 140 
 141         @Override
 142         public FieldInstanceReadWrite withInvokeBehavior() {
 143             return !hasInvokeExactBehavior()
 144                 ? this
 145                 : new FieldInstanceReadWrite(receiverType, fieldOffset{#if[Object]?, fieldType}, false);
 146         }
 147 
 148 #if[Object]
 149         @ForceInline
 150         static Object checkCast(FieldInstanceReadWrite handle, $type$ value) {
 151             if (handle.fieldType.isValueType())
 152                 Objects.requireNonNull(value);
 153             return handle.fieldType.cast(value);
 154         }
 155 #end[Object]
 156 
 157         @ForceInline
 158         static void set(VarHandle ob, Object holder, $type$ value) {
 159             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
 160             UNSAFE.put$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
 161                              handle.fieldOffset{#if[Value]?, handle.fieldType},
 162                              {#if[Object]?checkCast(handle, value):value});
 163         }
 164 
 165         @ForceInline
 166         static void setVolatile(VarHandle ob, Object holder, $type$ value) {
 167             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
 168             UNSAFE.put$Type$Volatile(Objects.requireNonNull(handle.receiverType.cast(holder)),
 169                                      handle.fieldOffset{#if[Value]?, handle.fieldType},
 170                                      {#if[Object]?checkCast(handle, value):value});
 171         }
 172 
 173         @ForceInline
 174         static void setOpaque(VarHandle ob, Object holder, $type$ value) {
 175             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
 176             UNSAFE.put$Type$Opaque(Objects.requireNonNull(handle.receiverType.cast(holder)),
 177                                    handle.fieldOffset{#if[Value]?, handle.fieldType},
 178                                    {#if[Object]?checkCast(handle, value):value});
 179         }
 180 
 181         @ForceInline
 182         static void setRelease(VarHandle ob, Object holder, $type$ value) {
 183             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
 184             UNSAFE.put$Type$Release(Objects.requireNonNull(handle.receiverType.cast(holder)),
 185                                     handle.fieldOffset{#if[Value]?, handle.fieldType},
 186                                     {#if[Object]?checkCast(handle, value):value});
 187         }
 188 #if[CAS]
 189 
 190         @ForceInline
 191         static boolean compareAndSet(VarHandle ob, Object holder, $type$ expected, $type$ value) {
 192             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
 193             return UNSAFE.compareAndSet$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
 194                                                handle.fieldOffset{#if[Object]?, handle.fieldType},
 195                                                {#if[Object]?checkCast(handle, expected):expected},
 196                                                {#if[Object]?checkCast(handle, value):value});
 197         }
 198 
 199         @ForceInline
 200         static $type$ compareAndExchange(VarHandle ob, Object holder, $type$ expected, $type$ value) {
 201             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
 202             return UNSAFE.compareAndExchange$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
 203                                                handle.fieldOffset{#if[Object]?, handle.fieldType},
 204                                                {#if[Object]?checkCast(handle, expected):expected},
 205                                                {#if[Object]?checkCast(handle, value):value});
 206         }
 207 
 208         @ForceInline
 209         static $type$ compareAndExchangeAcquire(VarHandle ob, Object holder, $type$ expected, $type$ value) {
 210             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
 211             return UNSAFE.compareAndExchange$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)),
 212                                                handle.fieldOffset{#if[Object]?, handle.fieldType},
 213                                                {#if[Object]?checkCast(handle, expected):expected},
 214                                                {#if[Object]?checkCast(handle, value):value});
 215         }
 216 
 217         @ForceInline
 218         static $type$ compareAndExchangeRelease(VarHandle ob, Object holder, $type$ expected, $type$ value) {
 219             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
 220             return UNSAFE.compareAndExchange$Type$Release(Objects.requireNonNull(handle.receiverType.cast(holder)),
 221                                                handle.fieldOffset{#if[Object]?, handle.fieldType},
 222                                                {#if[Object]?checkCast(handle, expected):expected},
 223                                                {#if[Object]?checkCast(handle, value):value});
 224         }
 225 
 226         @ForceInline
 227         static boolean weakCompareAndSetPlain(VarHandle ob, Object holder, $type$ expected, $type$ value) {
 228             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
 229             return UNSAFE.weakCompareAndSet$Type$Plain(Objects.requireNonNull(handle.receiverType.cast(holder)),
 230                                                handle.fieldOffset{#if[Object]?, handle.fieldType},
 231                                                {#if[Object]?checkCast(handle, expected):expected},
 232                                                {#if[Object]?checkCast(handle, value):value});
 233         }
 234 
 235         @ForceInline
 236         static boolean weakCompareAndSet(VarHandle ob, Object holder, $type$ expected, $type$ value) {
 237             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
 238             return UNSAFE.weakCompareAndSet$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
 239                                                handle.fieldOffset{#if[Object]?, handle.fieldType},
 240                                                {#if[Object]?checkCast(handle, expected):expected},
 241                                                {#if[Object]?checkCast(handle, value):value});
 242         }
 243 
 244         @ForceInline
 245         static boolean weakCompareAndSetAcquire(VarHandle ob, Object holder, $type$ expected, $type$ value) {
 246             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
 247             return UNSAFE.weakCompareAndSet$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)),
 248                                                handle.fieldOffset{#if[Object]?, handle.fieldType},
 249                                                {#if[Object]?checkCast(handle, expected):expected},
 250                                                {#if[Object]?checkCast(handle, value):value});
 251         }
 252 
 253         @ForceInline
 254         static boolean weakCompareAndSetRelease(VarHandle ob, Object holder, $type$ expected, $type$ value) {
 255             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
 256             return UNSAFE.weakCompareAndSet$Type$Release(Objects.requireNonNull(handle.receiverType.cast(holder)),
 257                                                handle.fieldOffset{#if[Object]?, handle.fieldType},
 258                                                {#if[Object]?checkCast(handle, expected):expected},
 259                                                {#if[Object]?checkCast(handle, value):value});
 260         }
 261 
 262         @ForceInline
 263         static $type$ getAndSet(VarHandle ob, Object holder, $type$ value) {
 264             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
 265             return UNSAFE.getAndSet$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
 266                                           handle.fieldOffset{#if[Value]?, handle.fieldType},
 267                                           {#if[Object]?checkCast(handle, value):value});
 268         }
 269 
 270         @ForceInline
 271         static $type$ getAndSetAcquire(VarHandle ob, Object holder, $type$ value) {
 272             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
 273             return UNSAFE.getAndSet$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)),
 274                                           handle.fieldOffset{#if[Value]?, handle.fieldType},
 275                                           {#if[Object]?checkCast(handle, value):value});
 276         }
 277 
 278         @ForceInline
 279         static $type$ getAndSetRelease(VarHandle ob, Object holder, $type$ value) {
 280             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
 281             return UNSAFE.getAndSet$Type$Release(Objects.requireNonNull(handle.receiverType.cast(holder)),
 282                                           handle.fieldOffset{#if[Value]?, handle.fieldType},
 283                                           {#if[Object]?checkCast(handle, value):value});
 284         }
 285 #end[CAS]
 286 #if[AtomicAdd]
 287 
 288         @ForceInline
 289         static $type$ getAndAdd(VarHandle ob, Object holder, $type$ value) {
 290             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
 291             return UNSAFE.getAndAdd$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
 292                                        handle.fieldOffset,
 293                                        value);
 294         }
 295 
 296         @ForceInline
 297         static $type$ getAndAddAcquire(VarHandle ob, Object holder, $type$ value) {
 298             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
 299             return UNSAFE.getAndAdd$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)),
 300                                        handle.fieldOffset,
 301                                        value);
 302         }
 303 
 304         @ForceInline
 305         static $type$ getAndAddRelease(VarHandle ob, Object holder, $type$ value) {
 306             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
 307             return UNSAFE.getAndAdd$Type$Release(Objects.requireNonNull(handle.receiverType.cast(holder)),
 308                                        handle.fieldOffset,
 309                                        value);
 310         }
 311 
 312 #end[AtomicAdd]
 313 #if[Bitwise]
 314 
 315         @ForceInline
 316         static $type$ getAndBitwiseOr(VarHandle ob, Object holder, $type$ value) {
 317             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
 318             return UNSAFE.getAndBitwiseOr$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
 319                                        handle.fieldOffset,
 320                                        value);
 321         }
 322 
 323         @ForceInline
 324         static $type$ getAndBitwiseOrRelease(VarHandle ob, Object holder, $type$ value) {
 325             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
 326             return UNSAFE.getAndBitwiseOr$Type$Release(Objects.requireNonNull(handle.receiverType.cast(holder)),
 327                                        handle.fieldOffset,
 328                                        value);
 329         }
 330 
 331         @ForceInline
 332         static $type$ getAndBitwiseOrAcquire(VarHandle ob, Object holder, $type$ value) {
 333             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
 334             return UNSAFE.getAndBitwiseOr$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)),
 335                                        handle.fieldOffset,
 336                                        value);
 337         }
 338 
 339         @ForceInline
 340         static $type$ getAndBitwiseAnd(VarHandle ob, Object holder, $type$ value) {
 341             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
 342             return UNSAFE.getAndBitwiseAnd$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
 343                                        handle.fieldOffset,
 344                                        value);
 345         }
 346 
 347         @ForceInline
 348         static $type$ getAndBitwiseAndRelease(VarHandle ob, Object holder, $type$ value) {
 349             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
 350             return UNSAFE.getAndBitwiseAnd$Type$Release(Objects.requireNonNull(handle.receiverType.cast(holder)),
 351                                        handle.fieldOffset,
 352                                        value);
 353         }
 354 
 355         @ForceInline
 356         static $type$ getAndBitwiseAndAcquire(VarHandle ob, Object holder, $type$ value) {
 357             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
 358             return UNSAFE.getAndBitwiseAnd$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)),
 359                                        handle.fieldOffset,
 360                                        value);
 361         }
 362 
 363         @ForceInline
 364         static $type$ getAndBitwiseXor(VarHandle ob, Object holder, $type$ value) {
 365             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
 366             return UNSAFE.getAndBitwiseXor$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
 367                                        handle.fieldOffset,
 368                                        value);
 369         }
 370 
 371         @ForceInline
 372         static $type$ getAndBitwiseXorRelease(VarHandle ob, Object holder, $type$ value) {
 373             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
 374             return UNSAFE.getAndBitwiseXor$Type$Release(Objects.requireNonNull(handle.receiverType.cast(holder)),
 375                                        handle.fieldOffset,
 376                                        value);
 377         }
 378 
 379         @ForceInline
 380         static $type$ getAndBitwiseXorAcquire(VarHandle ob, Object holder, $type$ value) {
 381             FieldInstanceReadWrite handle = (FieldInstanceReadWrite)ob;
 382             return UNSAFE.getAndBitwiseXor$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)),
 383                                        handle.fieldOffset,
 384                                        value);
 385         }
 386 #end[Bitwise]
 387 
 388         static final VarForm FORM = new VarForm(FieldInstanceReadWrite.class, Object.class, $type$.class);
 389     }
 390 
 391 
 392     static class FieldStaticReadOnly extends VarHandle {
 393         final Object base;
 394         final long fieldOffset;
 395 #if[Object]
 396         final Class<?> fieldType;
 397 #end[Object]
 398 
 399         FieldStaticReadOnly(Object base, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
 400             this(base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadOnly.FORM, false);
 401         }
 402 
 403         protected FieldStaticReadOnly(Object base, long fieldOffset{#if[Object]?, Class<?> fieldType},
 404                                       VarForm form, boolean exact) {
 405             super(form, exact);
 406             this.base = base;
 407             this.fieldOffset = fieldOffset;
 408 #if[Object]
 409             this.fieldType = fieldType;
 410 #end[Object]
 411         }
 412 
 413         @Override
 414         public FieldStaticReadOnly withInvokeExactBehavior() {
 415             return hasInvokeExactBehavior()
 416                 ? this
 417                 : new FieldStaticReadOnly(base, fieldOffset{#if[Object]?, fieldType}, vform, true);
 418         }
 419 
 420         @Override
 421         public FieldStaticReadOnly withInvokeBehavior() {
 422             return !hasInvokeExactBehavior()
 423                 ? this
 424                 : new FieldStaticReadOnly(base, fieldOffset{#if[Object]?, fieldType}, vform, false);
 425         }
 426 
 427         @Override
 428         public Optional<VarHandleDesc> describeConstable() {
 429             var fieldTypeRef = {#if[Object]?fieldType:$type$.class}.describeConstable();
 430             if (!fieldTypeRef.isPresent())
 431                 return Optional.empty();
 432 
 433             // Reflect on this VarHandle to extract the field name
 434             var staticField = VarHandles.getStaticFieldFromBaseAndOffset(
 435                 base, fieldOffset, {#if[Object]?fieldType:$type$.class});
 436             var receiverTypeRef = staticField.getDeclaringClass().describeConstable();
 437             if (!receiverTypeRef.isPresent())
 438                 return Optional.empty();
 439             return Optional.of(VarHandleDesc.ofStaticField(receiverTypeRef.get(), staticField.getName(), fieldTypeRef.get()));
 440         }
 441 
 442         @Override
 443         final MethodType accessModeTypeUncached(AccessType at) {
 444             return at.accessModeType(null, {#if[Object]?fieldType:$type$.class});
 445         }
 446 
 447         @ForceInline
 448         static $type$ get(VarHandle ob) {
 449             FieldStaticReadOnly handle = (FieldStaticReadOnly)ob;
 450             return UNSAFE.get$Type$(handle.base,
 451                                  handle.fieldOffset{#if[Value]?, handle.fieldType});
 452         }
 453 
 454         @ForceInline
 455         static $type$ getVolatile(VarHandle ob) {
 456             FieldStaticReadOnly handle = (FieldStaticReadOnly)ob;
 457             return UNSAFE.get$Type$Volatile(handle.base,
 458                                  handle.fieldOffset{#if[Value]?, handle.fieldType});
 459         }
 460 
 461         @ForceInline
 462         static $type$ getOpaque(VarHandle ob) {
 463             FieldStaticReadOnly handle = (FieldStaticReadOnly)ob;
 464             return UNSAFE.get$Type$Opaque(handle.base,
 465                                  handle.fieldOffset{#if[Value]?, handle.fieldType});
 466         }
 467 
 468         @ForceInline
 469         static $type$ getAcquire(VarHandle ob) {
 470             FieldStaticReadOnly handle = (FieldStaticReadOnly)ob;
 471             return UNSAFE.get$Type$Acquire(handle.base,
 472                                  handle.fieldOffset{#if[Value]?, handle.fieldType});
 473         }
 474 
 475         static final VarForm FORM = new VarForm(FieldStaticReadOnly.class, null, $type$.class);
 476     }
 477 
 478     static final class FieldStaticReadWrite extends FieldStaticReadOnly {
 479         FieldStaticReadWrite(Object base, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
 480             this(base, fieldOffset{#if[Object]?, fieldType}, false);
 481         }
 482 
 483         private FieldStaticReadWrite(Object base, long fieldOffset{#if[Object]?, Class<?> fieldType},
 484                                      boolean exact) {
 485             super(base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadWrite.FORM, exact);
 486         }
 487 
 488         @Override
 489         public FieldStaticReadWrite withInvokeExactBehavior() {
 490             return hasInvokeExactBehavior()
 491                 ? this
 492                 : new FieldStaticReadWrite(base, fieldOffset{#if[Object]?, fieldType}, true);
 493         }
 494 
 495         @Override
 496         public FieldStaticReadWrite withInvokeBehavior() {
 497             return !hasInvokeExactBehavior()
 498                 ? this
 499                 : new FieldStaticReadWrite(base, fieldOffset{#if[Object]?, fieldType}, false);
 500         }
 501 
 502 #if[Object]
 503         static Object checkCast(FieldStaticReadWrite handle, $type$ value) {
 504             if (handle.fieldType.isValueType())
 505                 Objects.requireNonNull(value);
 506             return handle.fieldType.cast(value);
 507         }
 508 #end[Object]
 509 
 510         @ForceInline
 511         static void set(VarHandle ob, $type$ value) {
 512             FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
 513             UNSAFE.put$Type$(handle.base,
 514                              handle.fieldOffset{#if[Value]?, handle.fieldType},
 515                              {#if[Object]?checkCast(handle, value):value});
 516         }
 517 
 518         @ForceInline
 519         static void setVolatile(VarHandle ob, $type$ value) {
 520             FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
 521             UNSAFE.put$Type$Volatile(handle.base,
 522                                      handle.fieldOffset{#if[Value]?, handle.fieldType},
 523                                      {#if[Object]?checkCast(handle, value):value});
 524         }
 525 
 526         @ForceInline
 527         static void setOpaque(VarHandle ob, $type$ value) {
 528             FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
 529             UNSAFE.put$Type$Opaque(handle.base,
 530                                    handle.fieldOffset{#if[Value]?, handle.fieldType},
 531                                    {#if[Object]?checkCast(handle, value):value});
 532         }
 533 
 534         @ForceInline
 535         static void setRelease(VarHandle ob, $type$ value) {
 536             FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
 537             UNSAFE.put$Type$Release(handle.base,
 538                                     handle.fieldOffset{#if[Value]?, handle.fieldType},
 539                                     {#if[Object]?checkCast(handle, value):value});
 540         }
 541 #if[CAS]
 542 
 543         @ForceInline
 544         static boolean compareAndSet(VarHandle ob, $type$ expected, $type$ value) {
 545             FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
 546             return UNSAFE.compareAndSet$Type$(handle.base,
 547                                                handle.fieldOffset{#if[Object]?, handle.fieldType},
 548                                                {#if[Object]?checkCast(handle, expected):expected},
 549                                                {#if[Object]?checkCast(handle, value):value});
 550         }
 551 
 552 
 553         @ForceInline
 554         static $type$ compareAndExchange(VarHandle ob, $type$ expected, $type$ value) {
 555             FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
 556             return UNSAFE.compareAndExchange$Type$(handle.base,
 557                                                handle.fieldOffset{#if[Object]?, handle.fieldType},
 558                                                {#if[Object]?checkCast(handle, expected):expected},
 559                                                {#if[Object]?checkCast(handle, value):value});
 560         }
 561 
 562         @ForceInline
 563         static $type$ compareAndExchangeAcquire(VarHandle ob, $type$ expected, $type$ value) {
 564             FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
 565             return UNSAFE.compareAndExchange$Type$Acquire(handle.base,
 566                                                handle.fieldOffset{#if[Object]?, handle.fieldType},
 567                                                {#if[Object]?checkCast(handle, expected):expected},
 568                                                {#if[Object]?checkCast(handle, value):value});
 569         }
 570 
 571         @ForceInline
 572         static $type$ compareAndExchangeRelease(VarHandle ob, $type$ expected, $type$ value) {
 573             FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
 574             return UNSAFE.compareAndExchange$Type$Release(handle.base,
 575                                                handle.fieldOffset{#if[Object]?, handle.fieldType},
 576                                                {#if[Object]?checkCast(handle, expected):expected},
 577                                                {#if[Object]?checkCast(handle, value):value});
 578         }
 579 
 580         @ForceInline
 581         static boolean weakCompareAndSetPlain(VarHandle ob, $type$ expected, $type$ value) {
 582             FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
 583             return UNSAFE.weakCompareAndSet$Type$Plain(handle.base,
 584                                                handle.fieldOffset{#if[Object]?, handle.fieldType},
 585                                                {#if[Object]?checkCast(handle, expected):expected},
 586                                                {#if[Object]?checkCast(handle, value):value});
 587         }
 588 
 589         @ForceInline
 590         static boolean weakCompareAndSet(VarHandle ob, $type$ expected, $type$ value) {
 591             FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
 592             return UNSAFE.weakCompareAndSet$Type$(handle.base,
 593                                                handle.fieldOffset{#if[Object]?, handle.fieldType},
 594                                                {#if[Object]?checkCast(handle, expected):expected},
 595                                                {#if[Object]?checkCast(handle, value):value});
 596         }
 597 
 598         @ForceInline
 599         static boolean weakCompareAndSetAcquire(VarHandle ob, $type$ expected, $type$ value) {
 600             FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
 601             return UNSAFE.weakCompareAndSet$Type$Acquire(handle.base,
 602                                                handle.fieldOffset{#if[Object]?, handle.fieldType},
 603                                                {#if[Object]?checkCast(handle, expected):expected},
 604                                                {#if[Object]?checkCast(handle, value):value});
 605         }
 606 
 607         @ForceInline
 608         static boolean weakCompareAndSetRelease(VarHandle ob, $type$ expected, $type$ value) {
 609             FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
 610             return UNSAFE.weakCompareAndSet$Type$Release(handle.base,
 611                                                handle.fieldOffset{#if[Object]?, handle.fieldType},
 612                                                {#if[Object]?checkCast(handle, expected):expected},
 613                                                {#if[Object]?checkCast(handle, value):value});
 614         }
 615 
 616         @ForceInline
 617         static $type$ getAndSet(VarHandle ob, $type$ value) {
 618             FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
 619             return UNSAFE.getAndSet$Type$(handle.base,
 620                                           handle.fieldOffset{#if[Value]?, handle.fieldType},
 621                                           {#if[Object]?checkCast(handle, value):value});
 622         }
 623 
 624         @ForceInline
 625         static $type$ getAndSetAcquire(VarHandle ob, $type$ value) {
 626             FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
 627             return UNSAFE.getAndSet$Type$Acquire(handle.base,
 628                                           handle.fieldOffset{#if[Value]?, handle.fieldType},
 629                                           {#if[Object]?checkCast(handle, value):value});
 630         }
 631 
 632         @ForceInline
 633         static $type$ getAndSetRelease(VarHandle ob, $type$ value) {
 634             FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
 635             return UNSAFE.getAndSet$Type$Release(handle.base,
 636                                           handle.fieldOffset{#if[Value]?, handle.fieldType},
 637                                           {#if[Object]?checkCast(handle, value):value});
 638         }
 639 #end[CAS]
 640 #if[AtomicAdd]
 641 
 642         @ForceInline
 643         static $type$ getAndAdd(VarHandle ob, $type$ value) {
 644             FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
 645             return UNSAFE.getAndAdd$Type$(handle.base,
 646                                        handle.fieldOffset,
 647                                        value);
 648         }
 649 
 650         @ForceInline
 651         static $type$ getAndAddAcquire(VarHandle ob, $type$ value) {
 652             FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
 653             return UNSAFE.getAndAdd$Type$Acquire(handle.base,
 654                                        handle.fieldOffset,
 655                                        value);
 656         }
 657 
 658         @ForceInline
 659         static $type$ getAndAddRelease(VarHandle ob, $type$ value) {
 660             FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
 661             return UNSAFE.getAndAdd$Type$Release(handle.base,
 662                                        handle.fieldOffset,
 663                                        value);
 664         }
 665 #end[AtomicAdd]
 666 #if[Bitwise]
 667 
 668         @ForceInline
 669         static $type$ getAndBitwiseOr(VarHandle ob, $type$ value) {
 670             FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
 671             return UNSAFE.getAndBitwiseOr$Type$(handle.base,
 672                                        handle.fieldOffset,
 673                                        value);
 674         }
 675 
 676         @ForceInline
 677         static $type$ getAndBitwiseOrRelease(VarHandle ob, $type$ value) {
 678             FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
 679             return UNSAFE.getAndBitwiseOr$Type$Release(handle.base,
 680                                        handle.fieldOffset,
 681                                        value);
 682         }
 683 
 684         @ForceInline
 685         static $type$ getAndBitwiseOrAcquire(VarHandle ob, $type$ value) {
 686             FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
 687             return UNSAFE.getAndBitwiseOr$Type$Acquire(handle.base,
 688                                        handle.fieldOffset,
 689                                        value);
 690         }
 691 
 692         @ForceInline
 693         static $type$ getAndBitwiseAnd(VarHandle ob, $type$ value) {
 694             FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
 695             return UNSAFE.getAndBitwiseAnd$Type$(handle.base,
 696                                        handle.fieldOffset,
 697                                        value);
 698         }
 699 
 700         @ForceInline
 701         static $type$ getAndBitwiseAndRelease(VarHandle ob, $type$ value) {
 702             FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
 703             return UNSAFE.getAndBitwiseAnd$Type$Release(handle.base,
 704                                        handle.fieldOffset,
 705                                        value);
 706         }
 707 
 708         @ForceInline
 709         static $type$ getAndBitwiseAndAcquire(VarHandle ob, $type$ value) {
 710             FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
 711             return UNSAFE.getAndBitwiseAnd$Type$Acquire(handle.base,
 712                                        handle.fieldOffset,
 713                                        value);
 714         }
 715 
 716         @ForceInline
 717         static $type$ getAndBitwiseXor(VarHandle ob, $type$ value) {
 718             FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
 719             return UNSAFE.getAndBitwiseXor$Type$(handle.base,
 720                                        handle.fieldOffset,
 721                                        value);
 722         }
 723 
 724         @ForceInline
 725         static $type$ getAndBitwiseXorRelease(VarHandle ob, $type$ value) {
 726             FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
 727             return UNSAFE.getAndBitwiseXor$Type$Release(handle.base,
 728                                        handle.fieldOffset,
 729                                        value);
 730         }
 731 
 732         @ForceInline
 733         static $type$ getAndBitwiseXorAcquire(VarHandle ob, $type$ value) {
 734             FieldStaticReadWrite handle = (FieldStaticReadWrite)ob;
 735             return UNSAFE.getAndBitwiseXor$Type$Acquire(handle.base,
 736                                        handle.fieldOffset,
 737                                        value);
 738         }
 739 #end[Bitwise]
 740 
 741         static final VarForm FORM = new VarForm(FieldStaticReadWrite.class, null, $type$.class);
 742     }
 743 
 744 #if[Reference]
 745     static VarHandle makeVarHandleValuesArray(Class<?> arrayClass) {
 746         Class<?> componentType = arrayClass.getComponentType();
 747         assert componentType.isValueType() && UNSAFE.isFlattenedArray(arrayClass);
 748         // should cache these VarHandle for performance
 749         return VarHandles.makeArrayElementHandle(arrayClass);
 750     }
 751 #end[Reference]
 752 
 753     static final class Array extends VarHandle {
 754         final int abase;
 755         final int ashift;
 756 #if[Object]
 757         final Class<{#if[Object]??:$type$[]}> arrayType;
 758         final Class<?> componentType;
 759 #end[Object]
 760 
 761         Array(int abase, int ashift{#if[Object]?, Class<?> arrayType}) {
 762             this(abase, ashift{#if[Object]?, arrayType}, false);
 763         }
 764 
 765         private Array(int abase, int ashift{#if[Object]?, Class<?> arrayType}, boolean exact) {
 766             super(Array.FORM, exact);
 767             this.abase = abase;
 768             this.ashift = ashift;
 769 #if[Object]
 770             this.arrayType = {#if[Object]?arrayType:$type$[].class};
 771             this.componentType = arrayType.getComponentType();
 772 #end[Object]
 773         }
 774 
 775         @Override
 776         public Array withInvokeExactBehavior() {
 777             return hasInvokeExactBehavior()
 778                 ? this
 779                 : new Array(abase, ashift{#if[Object]?, arrayType}, true);
 780         }
 781 
 782         @Override
 783         public Array withInvokeBehavior() {
 784             return !hasInvokeExactBehavior()
 785                 ? this
 786                 : new Array(abase, ashift{#if[Object]?, arrayType}, false);
 787         }
 788 
 789         @Override
 790         public Optional<VarHandleDesc> describeConstable() {
 791             var arrayTypeRef = {#if[Object]?arrayType:$type$[].class}.describeConstable();
 792             if (!arrayTypeRef.isPresent())
 793                 return Optional.empty();
 794 
 795             return Optional.of(VarHandleDesc.ofArray(arrayTypeRef.get()));
 796         }
 797 
 798         @Override
 799         final MethodType accessModeTypeUncached(AccessType at) {
 800             return at.accessModeType({#if[Object]?arrayType:$type$[].class}, {#if[Object]?arrayType.getComponentType():$type$.class}, int.class);
 801         }
 802 
 803 #if[Object]
 804         @ForceInline
 805         static Object runtimeTypeCheck(Array handle, Object[] oarray, Object value) {
 806             if (handle.componentType.isValueType())
 807                  Objects.requireNonNull(value);
 808 
 809             if (handle.arrayType == oarray.getClass()) {
 810                 // Fast path: static array type same as argument array type
 811                 return handle.componentType.cast(value);
 812             } else {
 813                 // Slow path: check value against argument array component type
 814                 return reflectiveTypeCheck(oarray, value);
 815             }
 816         }
 817 
 818         @ForceInline
 819         static Object reflectiveTypeCheck(Object[] oarray, Object value) {
 820             try {
 821                 return oarray.getClass().getComponentType().cast(value);
 822             } catch (ClassCastException e) {
 823                 throw new ArrayStoreException();
 824             }
 825         }
 826 #end[Object]
 827 
 828         @ForceInline
 829         static $type$ get(VarHandle ob, Object oarray, int index) {
 830             Array handle = (Array)ob;
 831 #if[Object]
 832             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 833 #else[Object]
 834             $type$[] array = ($type$[]) oarray;
 835 #end[Object]
 836             return array[index];
 837         }
 838 
 839         @ForceInline
 840         static void set(VarHandle ob, Object oarray, int index, $type$ value) {
 841             Array handle = (Array)ob;
 842 #if[Object]
 843             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 844 #else[Object]
 845             $type$[] array = ($type$[]) oarray;
 846 #end[Object]
 847 #if[Reference]
 848             if (UNSAFE.isFlattenedArray(oarray.getClass())) {
 849                 // for flattened array, delegate to VarHandle of the inline type array
 850                 VarHandle vh = makeVarHandleValuesArray(oarray.getClass());
 851                 vh.set(oarray, index, reflectiveTypeCheck(array, value));
 852                 return;
 853             }
 854 #end[Reference]
 855             array[index] = {#if[Object]?runtimeTypeCheck(handle, array, value):value};
 856         }
 857 
 858         @ForceInline
 859         static $type$ getVolatile(VarHandle ob, Object oarray, int index) {
 860             Array handle = (Array)ob;
 861 #if[Object]
 862             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 863 #else[Object]
 864             $type$[] array = ($type$[]) oarray;
 865 #end[Object]
 866 #if[Reference]
 867             if (UNSAFE.isFlattenedArray(oarray.getClass())) {
 868                 // for flattened array, delegate to VarHandle of the inline type array
 869                 VarHandle vh = makeVarHandleValuesArray(oarray.getClass());
 870                 return vh.getVolatile(oarray, index);
 871             }
 872 #end[Reference]
 873             return UNSAFE.get$Type$Volatile(array,
 874                     (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase{#if[Value]?, handle.componentType});
 875         }
 876 
 877         @ForceInline
 878         static void setVolatile(VarHandle ob, Object oarray, int index, $type$ value) {
 879             Array handle = (Array)ob;
 880 #if[Object]
 881             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 882 #else[Object]
 883             $type$[] array = ($type$[]) oarray;
 884 #end[Object]
 885 #if[Reference]
 886             if (UNSAFE.isFlattenedArray(oarray.getClass())) {
 887                 // for flattened array, delegate to VarHandle of the inline type array
 888                 VarHandle vh = makeVarHandleValuesArray(oarray.getClass());
 889                 vh.setVolatile(oarray, index, reflectiveTypeCheck(array, value));
 890                 return;
 891             }
 892 #end[Reference]
 893             UNSAFE.put$Type$Volatile(array,
 894                     (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase{#if[Value]?, handle.componentType},
 895                     {#if[Object]?runtimeTypeCheck(handle, array, value):value});
 896         }
 897 
 898         @ForceInline
 899         static $type$ getOpaque(VarHandle ob, Object oarray, int index) {
 900             Array handle = (Array)ob;
 901 #if[Object]
 902             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 903 #else[Object]
 904             $type$[] array = ($type$[]) oarray;
 905 #end[Object]
 906 #if[Reference]
 907             if (UNSAFE.isFlattenedArray(oarray.getClass())) {
 908                 // for flattened array, delegate to VarHandle of the inline type array
 909                 VarHandle vh = makeVarHandleValuesArray(oarray.getClass());
 910                 return vh.getOpaque(oarray, index);
 911             }
 912 #end[Reference]
 913             return UNSAFE.get$Type$Opaque(array,
 914                     (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase{#if[Value]?, handle.componentType});
 915         }
 916 
 917         @ForceInline
 918         static void setOpaque(VarHandle ob, Object oarray, int index, $type$ value) {
 919             Array handle = (Array)ob;
 920 #if[Object]
 921             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 922 #else[Object]
 923             $type$[] array = ($type$[]) oarray;
 924 #end[Object]
 925 #if[Reference]
 926             if (UNSAFE.isFlattenedArray(oarray.getClass())) {
 927                 // for flattened array, delegate to VarHandle of the inline type array
 928                 VarHandle vh = makeVarHandleValuesArray(oarray.getClass());
 929                 vh.setOpaque(oarray, index, reflectiveTypeCheck(array, value));
 930                 return;
 931             }
 932 #end[Reference]
 933             UNSAFE.put$Type$Opaque(array,
 934                     (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase{#if[Value]?, handle.componentType},
 935                     {#if[Object]?runtimeTypeCheck(handle, array, value):value});
 936         }
 937 
 938         @ForceInline
 939         static $type$ getAcquire(VarHandle ob, Object oarray, int index) {
 940             Array handle = (Array)ob;
 941 #if[Object]
 942             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 943 #else[Object]
 944             $type$[] array = ($type$[]) oarray;
 945 #end[Object]
 946 #if[Reference]
 947             if (UNSAFE.isFlattenedArray(oarray.getClass())) {
 948                 // for flattened array, delegate to VarHandle of the inline type array
 949                 VarHandle vh = makeVarHandleValuesArray(oarray.getClass());
 950                 return vh.getAcquire(oarray, index);
 951             }
 952 #end[Reference]
 953             return UNSAFE.get$Type$Acquire(array,
 954                     (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase{#if[Value]?, handle.componentType});
 955         }
 956 
 957         @ForceInline
 958         static void setRelease(VarHandle ob, Object oarray, int index, $type$ value) {
 959             Array handle = (Array)ob;
 960 #if[Object]
 961             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 962 #else[Object]
 963             $type$[] array = ($type$[]) oarray;
 964 #end[Object]
 965 #if[Reference]
 966             if (UNSAFE.isFlattenedArray(oarray.getClass())) {
 967                 // for flattened array, delegate to VarHandle of the inline type array
 968                 VarHandle vh = makeVarHandleValuesArray(oarray.getClass());
 969                 vh.setRelease(oarray, index, reflectiveTypeCheck(array, value));
 970                 return;
 971             }
 972 #end[Reference]
 973             UNSAFE.put$Type$Release(array,
 974                     (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase{#if[Value]?, handle.componentType},
 975                     {#if[Object]?runtimeTypeCheck(handle, array, value):value});
 976         }
 977 #if[CAS]
 978 
 979         @ForceInline
 980         static boolean compareAndSet(VarHandle ob, Object oarray, int index, $type$ expected, $type$ value) {
 981             Array handle = (Array)ob;
 982 #if[Object]
 983             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 984 #else[Object]
 985             $type$[] array = ($type$[]) oarray;
 986 #end[Object]
 987 #if[Reference]
 988             if (UNSAFE.isFlattenedArray(oarray.getClass())) {
 989                 // for flattened array, delegate to VarHandle of the inline type array
 990                 VarHandle vh = makeVarHandleValuesArray(oarray.getClass());
 991                 return vh.compareAndSet(oarray, index, expected, reflectiveTypeCheck(array, value));
 992             }
 993 #end[Reference]
 994             return UNSAFE.compareAndSet$Type$(array,
 995                     (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase{#if[Object]?, handle.componentType},
 996                     {#if[Object]?handle.componentType.cast(expected):expected},
 997                     {#if[Object]?runtimeTypeCheck(handle, array, value):value});
 998         }
 999 
1000         @ForceInline
1001         static $type$ compareAndExchange(VarHandle ob, Object oarray, int index, $type$ expected, $type$ value) {
1002             Array handle = (Array)ob;
1003 #if[Object]
1004             Object[] array = (Object[]) handle.arrayType.cast(oarray);
1005 #else[Object]
1006             $type$[] array = ($type$[]) oarray;
1007 #end[Object]
1008 #if[Reference]
1009             if (UNSAFE.isFlattenedArray(oarray.getClass())) {
1010                 // for flattened array, delegate to VarHandle of the inline type array
1011                 VarHandle vh = makeVarHandleValuesArray(oarray.getClass());
1012                 return vh.compareAndExchange(oarray, index, expected, reflectiveTypeCheck(array, value));
1013             }
1014 #end[Reference]
1015             return UNSAFE.compareAndExchange$Type$(array,
1016                     (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase{#if[Object]?, handle.componentType},
1017                     {#if[Object]?handle.componentType.cast(expected):expected},
1018                     {#if[Object]?runtimeTypeCheck(handle, array, value):value});
1019         }
1020 
1021         @ForceInline
1022         static $type$ compareAndExchangeAcquire(VarHandle ob, Object oarray, int index, $type$ expected, $type$ value) {
1023             Array handle = (Array)ob;
1024 #if[Object]
1025             Object[] array = (Object[]) handle.arrayType.cast(oarray);
1026 #else[Object]
1027             $type$[] array = ($type$[]) oarray;
1028 #end[Object]
1029 #if[Reference]
1030             if (UNSAFE.isFlattenedArray(oarray.getClass())) {
1031                 // for flattened array, delegate to VarHandle of the inline type array
1032                 VarHandle vh = makeVarHandleValuesArray(oarray.getClass());
1033                 return vh.compareAndExchangeAcquire(oarray, index, expected, reflectiveTypeCheck(array, value));
1034             }
1035 #end[Reference]
1036             return UNSAFE.compareAndExchange$Type$Acquire(array,
1037                     (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase{#if[Object]?, handle.componentType},
1038                     {#if[Object]?handle.componentType.cast(expected):expected},
1039                     {#if[Object]?runtimeTypeCheck(handle, array, value):value});
1040         }
1041 
1042         @ForceInline
1043         static $type$ compareAndExchangeRelease(VarHandle ob, Object oarray, int index, $type$ expected, $type$ value) {
1044             Array handle = (Array)ob;
1045 #if[Object]
1046             Object[] array = (Object[]) handle.arrayType.cast(oarray);
1047 #else[Object]
1048             $type$[] array = ($type$[]) oarray;
1049 #end[Object]
1050 #if[Reference]
1051             if (UNSAFE.isFlattenedArray(oarray.getClass())) {
1052                 // for flattened array, delegate to VarHandle of the inline type array
1053                 VarHandle vh = makeVarHandleValuesArray(oarray.getClass());
1054                 return vh.compareAndExchangeRelease(oarray, index, expected, reflectiveTypeCheck(array, value));
1055             }
1056 #end[Reference]
1057             return UNSAFE.compareAndExchange$Type$Release(array,
1058                     (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase{#if[Object]?, handle.componentType},
1059                     {#if[Object]?handle.componentType.cast(expected):expected},
1060                     {#if[Object]?runtimeTypeCheck(handle, array, value):value});
1061         }
1062 
1063         @ForceInline
1064         static boolean weakCompareAndSetPlain(VarHandle ob, Object oarray, int index, $type$ expected, $type$ value) {
1065             Array handle = (Array)ob;
1066 #if[Object]
1067             Object[] array = (Object[]) handle.arrayType.cast(oarray);
1068 #else[Object]
1069             $type$[] array = ($type$[]) oarray;
1070 #end[Object]
1071 #if[Reference]
1072             if (UNSAFE.isFlattenedArray(oarray.getClass())) {
1073                 // for flattened array, delegate to VarHandle of the inline type array
1074                 VarHandle vh = makeVarHandleValuesArray(oarray.getClass());
1075                 return vh.weakCompareAndSetPlain(oarray, index, expected, reflectiveTypeCheck(array, value));
1076             }
1077 #end[Reference]
1078             return UNSAFE.weakCompareAndSet$Type$Plain(array,
1079                     (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase{#if[Object]?, handle.componentType},
1080                     {#if[Object]?handle.componentType.cast(expected):expected},
1081                     {#if[Object]?runtimeTypeCheck(handle, array, value):value});
1082         }
1083 
1084         @ForceInline
1085         static boolean weakCompareAndSet(VarHandle ob, Object oarray, int index, $type$ expected, $type$ value) {
1086             Array handle = (Array)ob;
1087 #if[Object]
1088             Object[] array = (Object[]) handle.arrayType.cast(oarray);
1089 #else[Object]
1090             $type$[] array = ($type$[]) oarray;
1091 #end[Object]
1092 #if[Reference]
1093             if (UNSAFE.isFlattenedArray(oarray.getClass())) {
1094                 // for flattened array, delegate to VarHandle of the inline type array
1095                 VarHandle vh = makeVarHandleValuesArray(oarray.getClass());
1096                 return vh.weakCompareAndSet(oarray, index, expected, reflectiveTypeCheck(array, value));
1097             }
1098 #end[Reference]
1099             return UNSAFE.weakCompareAndSet$Type$(array,
1100                     (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase{#if[Object]?, handle.componentType},
1101                     {#if[Object]?handle.componentType.cast(expected):expected},
1102                     {#if[Object]?runtimeTypeCheck(handle, array, value):value});
1103         }
1104 
1105         @ForceInline
1106         static boolean weakCompareAndSetAcquire(VarHandle ob, Object oarray, int index, $type$ expected, $type$ value) {
1107             Array handle = (Array)ob;
1108 #if[Object]
1109             Object[] array = (Object[]) handle.arrayType.cast(oarray);
1110 #else[Object]
1111             $type$[] array = ($type$[]) oarray;
1112 #end[Object]
1113 #if[Reference]
1114             if (UNSAFE.isFlattenedArray(oarray.getClass())) {
1115                 // for flattened array, delegate to VarHandle of the inline type array
1116                 VarHandle vh = makeVarHandleValuesArray(oarray.getClass());
1117                 return vh.weakCompareAndSetAcquire(oarray, index, expected, reflectiveTypeCheck(array, value));
1118             }
1119 #end[Reference]
1120             return UNSAFE.weakCompareAndSet$Type$Acquire(array,
1121                     (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase{#if[Object]?, handle.componentType},
1122                     {#if[Object]?handle.componentType.cast(expected):expected},
1123                     {#if[Object]?runtimeTypeCheck(handle, array, value):value});
1124         }
1125 
1126         @ForceInline
1127         static boolean weakCompareAndSetRelease(VarHandle ob, Object oarray, int index, $type$ expected, $type$ value) {
1128             Array handle = (Array)ob;
1129 #if[Object]
1130             Object[] array = (Object[]) handle.arrayType.cast(oarray);
1131 #else[Object]
1132             $type$[] array = ($type$[]) oarray;
1133 #end[Object]
1134 #if[Reference]
1135             if (UNSAFE.isFlattenedArray(oarray.getClass())) {
1136                 // for flattened array, delegate to VarHandle of the inline type array
1137                 VarHandle vh = makeVarHandleValuesArray(oarray.getClass());
1138                 return vh.weakCompareAndSetRelease(oarray, index, expected, reflectiveTypeCheck(array, value));
1139             }
1140 #end[Reference]
1141             return UNSAFE.weakCompareAndSet$Type$Release(array,
1142                     (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase{#if[Object]?, handle.componentType},
1143                     {#if[Object]?handle.componentType.cast(expected):expected},
1144                     {#if[Object]?runtimeTypeCheck(handle, array, value):value});
1145         }
1146 
1147         @ForceInline
1148         static $type$ getAndSet(VarHandle ob, Object oarray, int index, $type$ value) {
1149             Array handle = (Array)ob;
1150 #if[Object]
1151             Object[] array = (Object[]) handle.arrayType.cast(oarray);
1152 #else[Object]
1153             $type$[] array = ($type$[]) oarray;
1154 #end[Object]
1155 #if[Reference]
1156             if (UNSAFE.isFlattenedArray(oarray.getClass())) {
1157                 // for flattened array, delegate to VarHandle of the inline type array
1158                 VarHandle vh = makeVarHandleValuesArray(oarray.getClass());
1159                 return vh.getAndSet(oarray, index, reflectiveTypeCheck(array, value));
1160             }
1161 #end[Reference]
1162             return UNSAFE.getAndSet$Type$(array,
1163                     (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase{#if[Value]?, handle.componentType},
1164                     {#if[Object]?runtimeTypeCheck(handle, array, value):value});
1165         }
1166 
1167         @ForceInline
1168         static $type$ getAndSetAcquire(VarHandle ob, Object oarray, int index, $type$ value) {
1169             Array handle = (Array)ob;
1170 #if[Object]
1171             Object[] array = (Object[]) handle.arrayType.cast(oarray);
1172 #else[Object]
1173             $type$[] array = ($type$[]) oarray;
1174 #end[Object]
1175 #if[Reference]
1176             if (UNSAFE.isFlattenedArray(oarray.getClass())) {
1177                 // for flattened array, delegate to VarHandle of the inline type array
1178                 VarHandle vh = makeVarHandleValuesArray(oarray.getClass());
1179                 return vh.getAndSetAcquire(oarray, index, reflectiveTypeCheck(array, value));
1180             }
1181 #end[Reference]
1182             return UNSAFE.getAndSet$Type$Acquire(array,
1183                     (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase{#if[Value]?, handle.componentType},
1184                     {#if[Object]?runtimeTypeCheck(handle, array, value):value});
1185         }
1186 
1187         @ForceInline
1188         static $type$ getAndSetRelease(VarHandle ob, Object oarray, int index, $type$ value) {
1189             Array handle = (Array)ob;
1190 #if[Object]
1191             Object[] array = (Object[]) handle.arrayType.cast(oarray);
1192 #else[Object]
1193             $type$[] array = ($type$[]) oarray;
1194 #end[Object]
1195 #if[Reference]
1196             if (UNSAFE.isFlattenedArray(oarray.getClass())) {
1197                 // for flattened array, delegate to VarHandle of the inline type array
1198                 VarHandle vh = makeVarHandleValuesArray(oarray.getClass());
1199                 return vh.getAndSetRelease(oarray, index, reflectiveTypeCheck(array, value));
1200             }
1201 #end[Reference]
1202             return UNSAFE.getAndSet$Type$Release(array,
1203                     (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase{#if[Value]?, handle.componentType},
1204                     {#if[Object]?runtimeTypeCheck(handle, array, value):value});
1205         }
1206 #end[CAS]
1207 #if[AtomicAdd]
1208 
1209         @ForceInline
1210         static $type$ getAndAdd(VarHandle ob, Object oarray, int index, $type$ value) {
1211             Array handle = (Array)ob;
1212             $type$[] array = ($type$[]) oarray;
1213             return UNSAFE.getAndAdd$Type$(array,
1214                     (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase,
1215                     value);
1216         }
1217 
1218         @ForceInline
1219         static $type$ getAndAddAcquire(VarHandle ob, Object oarray, int index, $type$ value) {
1220             Array handle = (Array)ob;
1221             $type$[] array = ($type$[]) oarray;
1222             return UNSAFE.getAndAdd$Type$Acquire(array,
1223                     (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase,
1224                     value);
1225         }
1226 
1227         @ForceInline
1228         static $type$ getAndAddRelease(VarHandle ob, Object oarray, int index, $type$ value) {
1229             Array handle = (Array)ob;
1230             $type$[] array = ($type$[]) oarray;
1231             return UNSAFE.getAndAdd$Type$Release(array,
1232                     (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase,
1233                     value);
1234         }
1235 #end[AtomicAdd]
1236 #if[Bitwise]
1237 
1238         @ForceInline
1239         static $type$ getAndBitwiseOr(VarHandle ob, Object oarray, int index, $type$ value) {
1240             Array handle = (Array)ob;
1241             $type$[] array = ($type$[]) oarray;
1242             return UNSAFE.getAndBitwiseOr$Type$(array,
1243                                        (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase,
1244                                        value);
1245         }
1246 
1247         @ForceInline
1248         static $type$ getAndBitwiseOrRelease(VarHandle ob, Object oarray, int index, $type$ value) {
1249             Array handle = (Array)ob;
1250             $type$[] array = ($type$[]) oarray;
1251             return UNSAFE.getAndBitwiseOr$Type$Release(array,
1252                                        (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase,
1253                                        value);
1254         }
1255 
1256         @ForceInline
1257         static $type$ getAndBitwiseOrAcquire(VarHandle ob, Object oarray, int index, $type$ value) {
1258             Array handle = (Array)ob;
1259             $type$[] array = ($type$[]) oarray;
1260             return UNSAFE.getAndBitwiseOr$Type$Acquire(array,
1261                                        (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase,
1262                                        value);
1263         }
1264 
1265         @ForceInline
1266         static $type$ getAndBitwiseAnd(VarHandle ob, Object oarray, int index, $type$ value) {
1267             Array handle = (Array)ob;
1268             $type$[] array = ($type$[]) oarray;
1269             return UNSAFE.getAndBitwiseAnd$Type$(array,
1270                                        (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase,
1271                                        value);
1272         }
1273 
1274         @ForceInline
1275         static $type$ getAndBitwiseAndRelease(VarHandle ob, Object oarray, int index, $type$ value) {
1276             Array handle = (Array)ob;
1277             $type$[] array = ($type$[]) oarray;
1278             return UNSAFE.getAndBitwiseAnd$Type$Release(array,
1279                                        (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase,
1280                                        value);
1281         }
1282 
1283         @ForceInline
1284         static $type$ getAndBitwiseAndAcquire(VarHandle ob, Object oarray, int index, $type$ value) {
1285             Array handle = (Array)ob;
1286             $type$[] array = ($type$[]) oarray;
1287             return UNSAFE.getAndBitwiseAnd$Type$Acquire(array,
1288                                        (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase,
1289                                        value);
1290         }
1291 
1292         @ForceInline
1293         static $type$ getAndBitwiseXor(VarHandle ob, Object oarray, int index, $type$ value) {
1294             Array handle = (Array)ob;
1295             $type$[] array = ($type$[]) oarray;
1296             return UNSAFE.getAndBitwiseXor$Type$(array,
1297                                        (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase,
1298                                        value);
1299         }
1300 
1301         @ForceInline
1302         static $type$ getAndBitwiseXorRelease(VarHandle ob, Object oarray, int index, $type$ value) {
1303             Array handle = (Array)ob;
1304             $type$[] array = ($type$[]) oarray;
1305             return UNSAFE.getAndBitwiseXor$Type$Release(array,
1306                                        (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase,
1307                                        value);
1308         }
1309 
1310         @ForceInline
1311         static $type$ getAndBitwiseXorAcquire(VarHandle ob, Object oarray, int index, $type$ value) {
1312             Array handle = (Array)ob;
1313             $type$[] array = ($type$[]) oarray;
1314             return UNSAFE.getAndBitwiseXor$Type$Acquire(array,
1315                                        (((long) Preconditions.checkIndex(index, array.length, Preconditions.AIOOBE_FORMATTER)) << handle.ashift) + handle.abase,
1316                                        value);
1317         }
1318 #end[Bitwise]
1319 
1320         static final VarForm FORM = new VarForm(Array.class, {#if[Object]?Object[].class:$type$[].class}, {#if[Object]?Object.class:$type$.class}, int.class);
1321     }
1322 }