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