1 /*
   2  * Copyright (c) 2015, 2016, 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.util.Objects;
  31 
  32 import static java.lang.invoke.MethodHandleStatics.UNSAFE;
  33 
  34 #warn
  35 
  36 final class VarHandle$Type$s {
  37 
  38     static class FieldInstanceReadOnly extends VarHandle {
  39         final long fieldOffset;
  40         final Class<?> receiverType;
  41 #if[Object]
  42         final Class<?> fieldType;
  43 #end[Object]
  44 
  45         FieldInstanceReadOnly(Class<?> receiverType, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
  46             this(receiverType, fieldOffset{#if[Object]?, fieldType}, FieldInstanceReadOnly.FORM);
  47         }
  48 
  49         protected FieldInstanceReadOnly(Class<?> receiverType, long fieldOffset{#if[Object]?, Class<?> fieldType},
  50                                         VarForm form) {
  51             super(form);
  52             this.fieldOffset = fieldOffset;
  53             this.receiverType = receiverType;
  54 #if[Object]
  55             this.fieldType = fieldType;
  56 #end[Object]
  57         }
  58 
  59         @Override
  60         final MethodType accessModeTypeUncached(AccessMode accessMode) {
  61             return accessMode.at.accessModeType(receiverType, {#if[Object]?fieldType:$type$.class});
  62         }
  63 
  64         @ForceInline
  65         static $type$ get(FieldInstanceReadOnly handle, Object holder) {
  66             return UNSAFE.get$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
  67                                  handle.fieldOffset);
  68         }
  69 
  70         @ForceInline
  71         static $type$ getVolatile(FieldInstanceReadOnly handle, Object holder) {
  72             return UNSAFE.get$Type$Volatile(Objects.requireNonNull(handle.receiverType.cast(holder)),
  73                                  handle.fieldOffset);
  74         }
  75 
  76         @ForceInline
  77         static $type$ getOpaque(FieldInstanceReadOnly handle, Object holder) {
  78             return UNSAFE.get$Type$Opaque(Objects.requireNonNull(handle.receiverType.cast(holder)),
  79                                  handle.fieldOffset);
  80         }
  81 
  82         @ForceInline
  83         static $type$ getAcquire(FieldInstanceReadOnly handle, Object holder) {
  84             return UNSAFE.get$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)),
  85                                  handle.fieldOffset);
  86         }
  87 
  88         static final VarForm FORM = new VarForm(FieldInstanceReadOnly.class, Object.class, $type$.class);
  89     }
  90 
  91     static final class FieldInstanceReadWrite extends FieldInstanceReadOnly {
  92 
  93         FieldInstanceReadWrite(Class<?> receiverType, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
  94             super(receiverType, fieldOffset{#if[Object]?, fieldType}, FieldInstanceReadWrite.FORM);
  95         }
  96 
  97         @ForceInline
  98         static void set(FieldInstanceReadWrite handle, Object holder, $type$ value) {
  99             UNSAFE.put$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
 100                              handle.fieldOffset,
 101                              {#if[Object]?handle.fieldType.cast(value):value});
 102         }
 103 
 104         @ForceInline
 105         static void setVolatile(FieldInstanceReadWrite handle, Object holder, $type$ value) {
 106             UNSAFE.put$Type$Volatile(Objects.requireNonNull(handle.receiverType.cast(holder)),
 107                                      handle.fieldOffset,
 108                                      {#if[Object]?handle.fieldType.cast(value):value});
 109         }
 110 
 111         @ForceInline
 112         static void setOpaque(FieldInstanceReadWrite handle, Object holder, $type$ value) {
 113             UNSAFE.put$Type$Opaque(Objects.requireNonNull(handle.receiverType.cast(holder)),
 114                                    handle.fieldOffset,
 115                                    {#if[Object]?handle.fieldType.cast(value):value});
 116         }
 117 
 118         @ForceInline
 119         static void setRelease(FieldInstanceReadWrite handle, Object holder, $type$ value) {
 120             UNSAFE.put$Type$Release(Objects.requireNonNull(handle.receiverType.cast(holder)),
 121                                     handle.fieldOffset,
 122                                     {#if[Object]?handle.fieldType.cast(value):value});
 123         }
 124 #if[CAS]
 125 
 126         @ForceInline
 127         static boolean compareAndSet(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
 128             return UNSAFE.compareAndSwap$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
 129                                                handle.fieldOffset,
 130                                                {#if[Object]?handle.fieldType.cast(expected):expected},
 131                                                {#if[Object]?handle.fieldType.cast(value):value});
 132         }
 133 
 134         @ForceInline
 135         static $type$ compareAndExchangeVolatile(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
 136             return UNSAFE.compareAndExchange$Type$Volatile(Objects.requireNonNull(handle.receiverType.cast(holder)),
 137                                                handle.fieldOffset,
 138                                                {#if[Object]?handle.fieldType.cast(expected):expected},
 139                                                {#if[Object]?handle.fieldType.cast(value):value});
 140         }
 141 
 142         @ForceInline
 143         static void compareAndExchangeVolatile_V(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
 144             UNSAFE.compareAndExchange$Type$Volatile(Objects.requireNonNull(handle.receiverType.cast(holder)),
 145                                                handle.fieldOffset,
 146                                                {#if[Object]?handle.fieldType.cast(expected):expected},
 147                                                {#if[Object]?handle.fieldType.cast(value):value});
 148         }
 149 
 150         @ForceInline
 151         static $type$ compareAndExchangeAcquire(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
 152             return UNSAFE.compareAndExchange$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)),
 153                                                handle.fieldOffset,
 154                                                {#if[Object]?handle.fieldType.cast(expected):expected},
 155                                                {#if[Object]?handle.fieldType.cast(value):value});
 156         }
 157 
 158         @ForceInline
 159         static $type$ compareAndExchangeRelease(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
 160             return UNSAFE.compareAndExchange$Type$Release(Objects.requireNonNull(handle.receiverType.cast(holder)),
 161                                                handle.fieldOffset,
 162                                                {#if[Object]?handle.fieldType.cast(expected):expected},
 163                                                {#if[Object]?handle.fieldType.cast(value):value});
 164         }
 165 
 166         @ForceInline
 167         static boolean weakCompareAndSet(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
 168             return UNSAFE.weakCompareAndSwap$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
 169                                                handle.fieldOffset,
 170                                                {#if[Object]?handle.fieldType.cast(expected):expected},
 171                                                {#if[Object]?handle.fieldType.cast(value):value});
 172         }
 173 
 174         @ForceInline
 175         static boolean weakCompareAndSetVolatile(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
 176             // TODO defer to strong form until new Unsafe method is added
 177             return UNSAFE.compareAndSwap$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
 178                                                handle.fieldOffset,
 179                                                {#if[Object]?handle.fieldType.cast(expected):expected},
 180                                                {#if[Object]?handle.fieldType.cast(value):value});
 181         }
 182 
 183         @ForceInline
 184         static boolean weakCompareAndSetAcquire(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
 185             return UNSAFE.weakCompareAndSwap$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)),
 186                                                handle.fieldOffset,
 187                                                {#if[Object]?handle.fieldType.cast(expected):expected},
 188                                                {#if[Object]?handle.fieldType.cast(value):value});
 189         }
 190 
 191         @ForceInline
 192         static boolean weakCompareAndSetRelease(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
 193             return UNSAFE.weakCompareAndSwap$Type$Release(Objects.requireNonNull(handle.receiverType.cast(holder)),
 194                                                handle.fieldOffset,
 195                                                {#if[Object]?handle.fieldType.cast(expected):expected},
 196                                                {#if[Object]?handle.fieldType.cast(value):value});
 197         }
 198 
 199         @ForceInline
 200         static $type$ getAndSet(FieldInstanceReadWrite handle, Object holder, $type$ value) {
 201             return UNSAFE.getAndSet$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
 202                                           handle.fieldOffset,
 203                                           {#if[Object]?handle.fieldType.cast(value):value});
 204         }
 205 #end[CAS]
 206 #if[AtomicAdd]
 207 
 208         @ForceInline
 209         static $type$ getAndAdd(FieldInstanceReadWrite handle, Object holder, $type$ value) {
 210             return UNSAFE.getAndAdd$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
 211                                        handle.fieldOffset,
 212                                        value);
 213         }
 214 
 215         @ForceInline
 216         static $type$ addAndGet(FieldInstanceReadWrite handle, Object holder, $type$ value) {
 217             return UNSAFE.getAndAdd$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
 218                                        handle.fieldOffset,
 219                                        value) + value;
 220         }
 221 #end[AtomicAdd]
 222 
 223         static final VarForm FORM = new VarForm(FieldInstanceReadWrite.class, Object.class, $type$.class);
 224     }
 225 
 226 
 227     static class FieldStaticReadOnly extends VarHandle {
 228         final Object base;
 229         final long fieldOffset;
 230 #if[Object]
 231         final Class<?> fieldType;
 232 #end[Object]
 233 
 234         FieldStaticReadOnly(Object base, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
 235             this(base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadOnly.FORM);
 236         }
 237 
 238         protected FieldStaticReadOnly(Object base, long fieldOffset{#if[Object]?, Class<?> fieldType},
 239                                       VarForm form) {
 240             super(form);
 241             this.base = base;
 242             this.fieldOffset = fieldOffset;
 243 #if[Object]
 244             this.fieldType = fieldType;
 245 #end[Object]
 246         }
 247 
 248         @Override
 249         final MethodType accessModeTypeUncached(AccessMode accessMode) {
 250             return accessMode.at.accessModeType(null, {#if[Object]?fieldType:$type$.class});
 251         }
 252 
 253         @ForceInline
 254         static $type$ get(FieldStaticReadOnly handle) {
 255             return UNSAFE.get$Type$(handle.base,
 256                                  handle.fieldOffset);
 257         }
 258 
 259         @ForceInline
 260         static $type$ getVolatile(FieldStaticReadOnly handle) {
 261             return UNSAFE.get$Type$Volatile(handle.base,
 262                                  handle.fieldOffset);
 263         }
 264 
 265         @ForceInline
 266         static $type$ getOpaque(FieldStaticReadOnly handle) {
 267             return UNSAFE.get$Type$Opaque(handle.base,
 268                                  handle.fieldOffset);
 269         }
 270 
 271         @ForceInline
 272         static $type$ getAcquire(FieldStaticReadOnly handle) {
 273             return UNSAFE.get$Type$Acquire(handle.base,
 274                                  handle.fieldOffset);
 275         }
 276 
 277         static final VarForm FORM = new VarForm(FieldStaticReadOnly.class, null, $type$.class);
 278     }
 279 
 280     static final class FieldStaticReadWrite extends FieldStaticReadOnly {
 281 
 282         FieldStaticReadWrite(Object base, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
 283             super(base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadWrite.FORM);
 284         }
 285 
 286         @ForceInline
 287         static void set(FieldStaticReadWrite handle, $type$ value) {
 288             UNSAFE.put$Type$(handle.base,
 289                              handle.fieldOffset,
 290                              {#if[Object]?handle.fieldType.cast(value):value});
 291         }
 292 
 293         @ForceInline
 294         static void setVolatile(FieldStaticReadWrite handle, $type$ value) {
 295             UNSAFE.put$Type$Volatile(handle.base,
 296                                      handle.fieldOffset,
 297                                      {#if[Object]?handle.fieldType.cast(value):value});
 298         }
 299 
 300         @ForceInline
 301         static void setOpaque(FieldStaticReadWrite handle, $type$ value) {
 302             UNSAFE.put$Type$Opaque(handle.base,
 303                                    handle.fieldOffset,
 304                                    {#if[Object]?handle.fieldType.cast(value):value});
 305         }
 306 
 307         @ForceInline
 308         static void setRelease(FieldStaticReadWrite handle, $type$ value) {
 309             UNSAFE.put$Type$Release(handle.base,
 310                                     handle.fieldOffset,
 311                                     {#if[Object]?handle.fieldType.cast(value):value});
 312         }
 313 #if[CAS]
 314 
 315         @ForceInline
 316         static boolean compareAndSet(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
 317             return UNSAFE.compareAndSwap$Type$(handle.base,
 318                                                handle.fieldOffset,
 319                                                {#if[Object]?handle.fieldType.cast(expected):expected},
 320                                                {#if[Object]?handle.fieldType.cast(value):value});
 321         }
 322 
 323 
 324         @ForceInline
 325         static $type$ compareAndExchangeVolatile(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
 326             return UNSAFE.compareAndExchange$Type$Volatile(handle.base,
 327                                                handle.fieldOffset,
 328                                                {#if[Object]?handle.fieldType.cast(expected):expected},
 329                                                {#if[Object]?handle.fieldType.cast(value):value});
 330         }
 331 
 332         @ForceInline
 333         static $type$ compareAndExchangeAcquire(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
 334             return UNSAFE.compareAndExchange$Type$Acquire(handle.base,
 335                                                handle.fieldOffset,
 336                                                {#if[Object]?handle.fieldType.cast(expected):expected},
 337                                                {#if[Object]?handle.fieldType.cast(value):value});
 338         }
 339 
 340         @ForceInline
 341         static $type$ compareAndExchangeRelease(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
 342             return UNSAFE.compareAndExchange$Type$Release(handle.base,
 343                                                handle.fieldOffset,
 344                                                {#if[Object]?handle.fieldType.cast(expected):expected},
 345                                                {#if[Object]?handle.fieldType.cast(value):value});
 346         }
 347 
 348         @ForceInline
 349         static boolean weakCompareAndSet(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
 350             return UNSAFE.weakCompareAndSwap$Type$(handle.base,
 351                                                handle.fieldOffset,
 352                                                {#if[Object]?handle.fieldType.cast(expected):expected},
 353                                                {#if[Object]?handle.fieldType.cast(value):value});
 354         }
 355 
 356         @ForceInline
 357         static boolean weakCompareAndSetVolatile(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
 358             // TODO defer to strong form until new Unsafe method is added
 359             return UNSAFE.compareAndSwap$Type$(handle.base,
 360                                                handle.fieldOffset,
 361                                                {#if[Object]?handle.fieldType.cast(expected):expected},
 362                                                {#if[Object]?handle.fieldType.cast(value):value});
 363         }
 364 
 365         @ForceInline
 366         static boolean weakCompareAndSetAcquire(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
 367             return UNSAFE.weakCompareAndSwap$Type$Acquire(handle.base,
 368                                                handle.fieldOffset,
 369                                                {#if[Object]?handle.fieldType.cast(expected):expected},
 370                                                {#if[Object]?handle.fieldType.cast(value):value});
 371         }
 372 
 373         @ForceInline
 374         static boolean weakCompareAndSetRelease(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
 375             return UNSAFE.weakCompareAndSwap$Type$Release(handle.base,
 376                                                handle.fieldOffset,
 377                                                {#if[Object]?handle.fieldType.cast(expected):expected},
 378                                                {#if[Object]?handle.fieldType.cast(value):value});
 379         }
 380 
 381         @ForceInline
 382         static $type$ getAndSet(FieldStaticReadWrite handle, $type$ value) {
 383             return UNSAFE.getAndSet$Type$(handle.base,
 384                                           handle.fieldOffset,
 385                                           {#if[Object]?handle.fieldType.cast(value):value});
 386         }
 387 #end[CAS]
 388 #if[AtomicAdd]
 389 
 390         @ForceInline
 391         static $type$ getAndAdd(FieldStaticReadWrite handle, $type$ value) {
 392             return UNSAFE.getAndAdd$Type$(handle.base,
 393                                        handle.fieldOffset,
 394                                        value);
 395         }
 396 
 397         @ForceInline
 398         static $type$ addAndGet(FieldStaticReadWrite handle, $type$ value) {
 399             return UNSAFE.getAndAdd$Type$(handle.base,
 400                                        handle.fieldOffset,
 401                                        value) + value;
 402         }
 403 #end[AtomicAdd]
 404 
 405         static final VarForm FORM = new VarForm(FieldStaticReadWrite.class, null, $type$.class);
 406     }
 407 
 408 
 409     static final class Array extends VarHandle {
 410         final int abase;
 411         final int ashift;
 412 #if[Object]
 413         final Class<{#if[Object]??:$type$[]}> arrayType;
 414         final Class<?> componentType;
 415 #end[Object]
 416 
 417         Array(int abase, int ashift{#if[Object]?, Class<?> arrayType}) {
 418             super(Array.FORM);
 419             this.abase = abase;
 420             this.ashift = ashift;
 421 #if[Object]
 422             this.arrayType = {#if[Object]?arrayType:$type$[].class};
 423             this.componentType = arrayType.getComponentType();
 424 #end[Object]
 425         }
 426 
 427         @Override
 428         final MethodType accessModeTypeUncached(AccessMode accessMode) {
 429             return accessMode.at.accessModeType({#if[Object]?arrayType:$type$[].class}, {#if[Object]?arrayType.getComponentType():$type$.class}, int.class);
 430         }
 431 
 432         @ForceInline
 433         static $type$ get(Array handle, Object oarray, int index) {
 434 #if[Object]
 435             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 436 #else[Object]
 437             $type$[] array = ($type$[]) oarray;
 438 #end[Object]
 439             return array[index];
 440         }
 441 
 442         @ForceInline
 443         static void set(Array handle, Object oarray, int index, $type$ value) {
 444 #if[Object]
 445             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 446 #else[Object]
 447             $type$[] array = ($type$[]) oarray;
 448 #end[Object]
 449             array[index] = {#if[Object]?handle.componentType.cast(value):value};
 450         }
 451 
 452         @ForceInline
 453         static $type$ getVolatile(Array handle, Object oarray, int index) {
 454 #if[Object]
 455             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 456 #else[Object]
 457             $type$[] array = ($type$[]) oarray;
 458 #end[Object]
 459             return UNSAFE.get$Type$Volatile(array,
 460                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase);
 461         }
 462 
 463         @ForceInline
 464         static void setVolatile(Array handle, Object oarray, int index, $type$ value) {
 465 #if[Object]
 466             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 467 #else[Object]
 468             $type$[] array = ($type$[]) oarray;
 469 #end[Object]
 470             UNSAFE.put$Type$Volatile(array,
 471                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
 472                     {#if[Object]?handle.componentType.cast(value):value});
 473         }
 474 
 475         @ForceInline
 476         static $type$ getOpaque(Array handle, Object oarray, int index) {
 477 #if[Object]
 478             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 479 #else[Object]
 480             $type$[] array = ($type$[]) oarray;
 481 #end[Object]
 482             return UNSAFE.get$Type$Opaque(array,
 483                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase);
 484         }
 485 
 486         @ForceInline
 487         static void setOpaque(Array handle, Object oarray, int index, $type$ value) {
 488 #if[Object]
 489             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 490 #else[Object]
 491             $type$[] array = ($type$[]) oarray;
 492 #end[Object]
 493             UNSAFE.put$Type$Opaque(array,
 494                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
 495                     {#if[Object]?handle.componentType.cast(value):value});
 496         }
 497 
 498         @ForceInline
 499         static $type$ getAcquire(Array handle, Object oarray, int index) {
 500 #if[Object]
 501             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 502 #else[Object]
 503             $type$[] array = ($type$[]) oarray;
 504 #end[Object]
 505             return UNSAFE.get$Type$Acquire(array,
 506                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase);
 507         }
 508 
 509         @ForceInline
 510         static void setRelease(Array handle, Object oarray, int index, $type$ value) {
 511 #if[Object]
 512             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 513 #else[Object]
 514             $type$[] array = ($type$[]) oarray;
 515 #end[Object]
 516             UNSAFE.put$Type$Release(array,
 517                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
 518                     {#if[Object]?handle.componentType.cast(value):value});
 519         }
 520 #if[CAS]
 521 
 522         @ForceInline
 523         static boolean compareAndSet(Array handle, Object oarray, int index, $type$ expected, $type$ value) {
 524 #if[Object]
 525             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 526 #else[Object]
 527             $type$[] array = ($type$[]) oarray;
 528 #end[Object]
 529             return UNSAFE.compareAndSwap$Type$(array,
 530                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
 531                     {#if[Object]?handle.componentType.cast(expected):expected},
 532                     {#if[Object]?handle.componentType.cast(value):value});
 533         }
 534 
 535         @ForceInline
 536         static $type$ compareAndExchangeVolatile(Array handle, Object oarray, int index, $type$ expected, $type$ value) {
 537 #if[Object]
 538             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 539 #else[Object]
 540             $type$[] array = ($type$[]) oarray;
 541 #end[Object]
 542             return UNSAFE.compareAndExchange$Type$Volatile(array,
 543                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
 544                     {#if[Object]?handle.componentType.cast(expected):expected},
 545                     {#if[Object]?handle.componentType.cast(value):value});
 546         }
 547 
 548         @ForceInline
 549         static $type$ compareAndExchangeAcquire(Array handle, Object oarray, int index, $type$ expected, $type$ value) {
 550 #if[Object]
 551             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 552 #else[Object]
 553             $type$[] array = ($type$[]) oarray;
 554 #end[Object]
 555             return UNSAFE.compareAndExchange$Type$Acquire(array,
 556                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
 557                     {#if[Object]?handle.componentType.cast(expected):expected},
 558                     {#if[Object]?handle.componentType.cast(value):value});
 559         }
 560 
 561         @ForceInline
 562         static $type$ compareAndExchangeRelease(Array handle, Object oarray, int index, $type$ expected, $type$ value) {
 563 #if[Object]
 564             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 565 #else[Object]
 566             $type$[] array = ($type$[]) oarray;
 567 #end[Object]
 568             return UNSAFE.compareAndExchange$Type$Release(array,
 569                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
 570                     {#if[Object]?handle.componentType.cast(expected):expected},
 571                     {#if[Object]?handle.componentType.cast(value):value});
 572         }
 573 
 574         @ForceInline
 575         static boolean weakCompareAndSet(Array handle, Object oarray, int index, $type$ expected, $type$ value) {
 576 #if[Object]
 577             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 578 #else[Object]
 579             $type$[] array = ($type$[]) oarray;
 580 #end[Object]
 581             return UNSAFE.weakCompareAndSwap$Type$(array,
 582                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
 583                     {#if[Object]?handle.componentType.cast(expected):expected},
 584                     {#if[Object]?handle.componentType.cast(value):value});
 585         }
 586 
 587         @ForceInline
 588         static boolean weakCompareAndSetVolatile(Array handle, Object oarray, int index, $type$ expected, $type$ value) {
 589 #if[Object]
 590             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 591 #else[Object]
 592             $type$[] array = ($type$[]) oarray;
 593 #end[Object]
 594             // TODO defer to strong form until new Unsafe method is added
 595             return UNSAFE.compareAndSwap$Type$(array,
 596                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
 597                     {#if[Object]?handle.componentType.cast(expected):expected},
 598                     {#if[Object]?handle.componentType.cast(value):value});
 599         }
 600 
 601         @ForceInline
 602         static boolean weakCompareAndSetAcquire(Array handle, Object oarray, int index, $type$ expected, $type$ value) {
 603 #if[Object]
 604             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 605 #else[Object]
 606             $type$[] array = ($type$[]) oarray;
 607 #end[Object]
 608             return UNSAFE.weakCompareAndSwap$Type$Acquire(array,
 609                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
 610                     {#if[Object]?handle.componentType.cast(expected):expected},
 611                     {#if[Object]?handle.componentType.cast(value):value});
 612         }
 613 
 614         @ForceInline
 615         static boolean weakCompareAndSetRelease(Array handle, Object oarray, int index, $type$ expected, $type$ value) {
 616 #if[Object]
 617             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 618 #else[Object]
 619             $type$[] array = ($type$[]) oarray;
 620 #end[Object]
 621             return UNSAFE.weakCompareAndSwap$Type$Release(array,
 622                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
 623                     {#if[Object]?handle.componentType.cast(expected):expected},
 624                     {#if[Object]?handle.componentType.cast(value):value});
 625         }
 626 
 627         @ForceInline
 628         static $type$ getAndSet(Array handle, Object oarray, int index, $type$ value) {
 629 #if[Object]
 630             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 631 #else[Object]
 632             $type$[] array = ($type$[]) oarray;
 633 #end[Object]
 634             return UNSAFE.getAndSet$Type$(array,
 635                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
 636                     {#if[Object]?handle.componentType.cast(value):value});
 637         }
 638 #end[CAS]
 639 #if[AtomicAdd]
 640 
 641         @ForceInline
 642         static $type$ getAndAdd(Array handle, Object oarray, int index, $type$ value) {
 643 #if[Object]
 644             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 645 #else[Object]
 646             $type$[] array = ($type$[]) oarray;
 647 #end[Object]
 648             return UNSAFE.getAndAdd$Type$(array,
 649                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
 650                     value);
 651         }
 652 
 653         @ForceInline
 654         static $type$ addAndGet(Array handle, Object oarray, int index, $type$ value) {
 655 #if[Object]
 656             Object[] array = (Object[]) handle.arrayType.cast(oarray);
 657 #else[Object]
 658             $type$[] array = ($type$[]) oarray;
 659 #end[Object]
 660             return UNSAFE.getAndAdd$Type$(array,
 661                     (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
 662                     value) + value;
 663         }
 664 #end[AtomicAdd]
 665 
 666         static final VarForm FORM = new VarForm(Array.class, {#if[Object]?Object[].class:$type$[].class}, {#if[Object]?Object.class:$type$.class}, int.class);
 667     }
 668 }