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