1 /*
   2  * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package java.lang.invoke;
  26 
  27 import jdk.internal.foreign.MemoryAddressImpl;
  28 import jdk.internal.misc.Unsafe;
  29 import jdk.internal.util.Preconditions;
  30 import jdk.internal.vm.annotation.ForceInline;
  31 
  32 import java.foreign.layout.Layout;
  33 import java.foreign.layout.Value;
  34 import java.foreign.layout.Value.Endianness;
  35 import java.foreign.memory.MemoryAddress;
  36 import java.foreign.memory.MemoryScope;
  37 import java.nio.ByteBuffer;
  38 import java.nio.ReadOnlyBufferException;
  39 import java.util.Objects;
  40 
  41 import static java.lang.invoke.MethodHandleStatics.UNSAFE;
  42 
  43 #warn
  44 
  45 final class VarHandleMemoryAddressAs$Type$s extends VarHandleByteArrayBase {
  46 
  47     static final int ALIGN = $BoxType$.BYTES - 1;
  48 
  49 #if[floatingPoint]
  50     @ForceInline
  51     static $rawType$ convEndian(boolean big, $type$ v) {
  52         $rawType$ rv = $Type$.$type$ToRaw$RawType$Bits(v);
  53         return big == BE ? rv : $RawBoxType$.reverseBytes(rv);
  54     }
  55 
  56     @ForceInline
  57     static $type$ convEndian(boolean big, $rawType$ rv) {
  58         rv = big == BE ? rv : $RawBoxType$.reverseBytes(rv);
  59         return $Type$.$rawType$BitsTo$Type$(rv);
  60     }
  61 #else[floatingPoint]
  62     @ForceInline
  63     static $type$ convEndian(boolean big, $type$ n) {
  64         return big == BE ? n : swap(n);
  65     }
  66 
  67     @ForceInline
  68     static $type$ swap($type$ rv) {
  69 #if[byte]
  70         return (byte) (Integer.reverse(rv) >>> (Integer.SIZE - Byte.SIZE));
  71 #else[byte]
  72         return $BoxType$.reverseBytes(rv);
  73 #end[byte]
  74     }
  75 #end[floatingPoint]
  76 
  77     @ForceInline
  78     static MemoryAddressImpl checkAddress(Object obb, long offset, long length) {
  79         MemoryAddressImpl oo = (MemoryAddressImpl)Objects.requireNonNull(obb);
  80         oo.checkAccess(offset, length);
  81         return oo;
  82     }
  83     
  84     @ForceInline
  85     static long offset(MemoryAddressImpl bb, long offset) {
  86         return bb.unsafeGetOffset() + offset;
  87     }
  88     
  89     @ForceInline
  90     static $type$ get0(MemoryAddressHandleBase handle, Object obb, long base) {
  91         MemoryAddressImpl bb = checkAddress(obb, base, handle.length);
  92 #if[floatingPoint]
  93         $rawType$ rawValue = UNSAFE.get$RawType$Unaligned(
  94                 bb.unsafeGetBase(),
  95                 offset(bb, base),
  96                 handle.be);
  97         return $Type$.$rawType$BitsTo$Type$(rawValue);
  98 #else[floatingPoint]
  99 #if[byte]
 100         return convEndian(handle.be, UNSAFE.get$Type$(
 101                             bb.unsafeGetBase(),
 102                             offset(bb, base)));
 103 #else[byte]
 104         return UNSAFE.get$Type$Unaligned(
 105                 bb.unsafeGetBase(),
 106                 offset(bb, base),
 107                 handle.be);
 108 #end[byte]
 109 #end[floatingPoint]
 110     }
 111 
 112     @ForceInline
 113     static void set0(MemoryAddressHandleBase handle, Object obb, long base, $type$ value) {
 114         MemoryAddressImpl bb = checkAddress(obb, base, handle.length);
 115 #if[floatingPoint]
 116         UNSAFE.put$RawType$Unaligned(
 117                 bb.unsafeGetBase(),
 118                 offset(bb, base),
 119                 $Type$.$type$ToRaw$RawType$Bits(value),
 120                 handle.be);
 121 #else[floatingPoint]
 122 #if[byte]
 123         UNSAFE.put$Type$(
 124                          bb.unsafeGetBase(),
 125                          offset(bb, base),
 126                          convEndian(handle.be, value));
 127 #else[byte]
 128         UNSAFE.put$Type$Unaligned(
 129                 bb.unsafeGetBase(),
 130                 offset(bb, base),
 131                 value,
 132                 handle.be);
 133 #end[byte]
 134 #end[floatingPoint]
 135     }
 136 
 137     @ForceInline
 138     static $type$ getVolatile0(MemoryAddressHandleBase handle, Object obb, long base) {
 139         MemoryAddressImpl bb = checkAddress(obb, base, handle.length);
 140         return convEndian(handle.be,
 141                           UNSAFE.get$RawType$Volatile(
 142                                   bb.unsafeGetBase(),
 143                                   offset(bb, base)));
 144     }
 145 
 146     @ForceInline
 147     static void setVolatile0(MemoryAddressHandleBase handle, Object obb, long base, $type$ value) {
 148         MemoryAddressImpl bb = checkAddress(obb, base, handle.length);
 149         UNSAFE.put$RawType$Volatile(
 150                 bb.unsafeGetBase(),
 151                 offset(bb, base),
 152                 convEndian(handle.be, value));
 153     }
 154 
 155     @ForceInline
 156     static $type$ getAcquire0(MemoryAddressHandleBase handle, Object obb, long base) {
 157         MemoryAddressImpl bb = checkAddress(obb, base, handle.length);
 158         return convEndian(handle.be,
 159                           UNSAFE.get$RawType$Acquire(
 160                                   bb.unsafeGetBase(),
 161                                   offset(bb, base)));
 162     }
 163 
 164     @ForceInline
 165     static void setRelease0(MemoryAddressHandleBase handle, Object obb, long base, $type$ value) {
 166         MemoryAddressImpl bb = checkAddress(obb, base, handle.length);
 167         UNSAFE.put$RawType$Release(
 168                 bb.unsafeGetBase(),
 169                 offset(bb, base),
 170                 convEndian(handle.be, value));
 171     }
 172 
 173     @ForceInline
 174     static $type$ getOpaque0(MemoryAddressHandleBase handle, Object obb, long base) {
 175         MemoryAddressImpl bb = checkAddress(obb, base, handle.length);
 176         return convEndian(handle.be,
 177                           UNSAFE.get$RawType$Opaque(
 178                                   bb.unsafeGetBase(),
 179                                   offset(bb, base)));
 180     }
 181 
 182     @ForceInline
 183     static void setOpaque0(MemoryAddressHandleBase handle, Object obb, long base, $type$ value) {
 184         MemoryAddressImpl bb = checkAddress(obb, base, handle.length);
 185         UNSAFE.put$RawType$Opaque(
 186                 bb.unsafeGetBase(),
 187                 offset(bb, base),
 188                 convEndian(handle.be, value));
 189     }
 190 #if[CAS]
 191 
 192     @ForceInline
 193     static boolean compareAndSet0(MemoryAddressHandleBase handle, Object obb, long base, $type$ expected, $type$ value) {
 194         MemoryAddressImpl bb = checkAddress(obb, base, handle.length);
 195 #if[Object]
 196         return UNSAFE.compareAndSetReference(
 197                 bb.unsafeGetBase(),
 198                 offset(bb, base),
 199                 convEndian(handle.be, expected), convEndian(handle.be, value));
 200 #else[Object]
 201         return UNSAFE.compareAndSet$RawType$(
 202                 bb.unsafeGetBase(),
 203                 offset(bb, base),
 204                 convEndian(handle.be, expected), convEndian(handle.be, value));
 205 #end[Object]
 206     }
 207 
 208     @ForceInline
 209     static $type$ compareAndExchange0(MemoryAddressHandleBase handle, Object obb, long base, $type$ expected, $type$ value) {
 210         MemoryAddressImpl bb = checkAddress(obb, base, handle.length);
 211         return convEndian(handle.be,
 212                           UNSAFE.compareAndExchange$RawType$(
 213                                   bb.unsafeGetBase(),
 214                                   offset(bb, base),
 215                                   convEndian(handle.be, expected), convEndian(handle.be, value)));
 216     }
 217 
 218     @ForceInline
 219     static $type$ compareAndExchangeAcquire0(MemoryAddressHandleBase handle, Object obb, long base, $type$ expected, $type$ value) {
 220         MemoryAddressImpl bb = checkAddress(obb, base, handle.length);
 221         return convEndian(handle.be,
 222                           UNSAFE.compareAndExchange$RawType$Acquire(
 223                                   bb.unsafeGetBase(),
 224                                   offset(bb, base),
 225                                   convEndian(handle.be, expected), convEndian(handle.be, value)));
 226     }
 227 
 228     @ForceInline
 229     static $type$ compareAndExchangeRelease0(MemoryAddressHandleBase handle, Object obb, long base, $type$ expected, $type$ value) {
 230         MemoryAddressImpl bb = checkAddress(obb, base, handle.length);
 231         return convEndian(handle.be,
 232                           UNSAFE.compareAndExchange$RawType$Release(
 233                                   bb.unsafeGetBase(),
 234                                   offset(bb, base),
 235                                   convEndian(handle.be, expected), convEndian(handle.be, value)));
 236     }
 237 
 238     @ForceInline
 239     static boolean weakCompareAndSetPlain0(MemoryAddressHandleBase handle, Object obb, long base, $type$ expected, $type$ value) {
 240         MemoryAddressImpl bb = checkAddress(obb, base, handle.length);
 241         return UNSAFE.weakCompareAndSet$RawType$Plain(
 242                 bb.unsafeGetBase(),
 243                 offset(bb, base),
 244                 convEndian(handle.be, expected), convEndian(handle.be, value));
 245     }
 246 
 247     @ForceInline
 248     static boolean weakCompareAndSet0(MemoryAddressHandleBase handle, Object obb, long base, $type$ expected, $type$ value) {
 249         MemoryAddressImpl bb = checkAddress(obb, base, handle.length);
 250         return UNSAFE.weakCompareAndSet$RawType$(
 251                 bb.unsafeGetBase(),
 252                 offset(bb, base),
 253                 convEndian(handle.be, expected), convEndian(handle.be, value));
 254     }
 255 
 256     @ForceInline
 257     static boolean weakCompareAndSetAcquire0(MemoryAddressHandleBase handle, Object obb, long base, $type$ expected, $type$ value) {
 258         MemoryAddressImpl bb = checkAddress(obb, base, handle.length);
 259         return UNSAFE.weakCompareAndSet$RawType$Acquire(
 260                 bb.unsafeGetBase(),
 261                 offset(bb, base),
 262                 convEndian(handle.be, expected), convEndian(handle.be, value));
 263     }
 264 
 265     @ForceInline
 266     static boolean weakCompareAndSetRelease0(MemoryAddressHandleBase handle, Object obb, long base, $type$ expected, $type$ value) {
 267         MemoryAddressImpl bb = checkAddress(obb, base, handle.length);
 268         return UNSAFE.weakCompareAndSet$RawType$Release(
 269                 bb.unsafeGetBase(),
 270                 offset(bb, base),
 271                 convEndian(handle.be, expected), convEndian(handle.be, value));
 272     }
 273 
 274     @ForceInline
 275     static $type$ getAndSet0(MemoryAddressHandleBase handle, Object obb, long base, $type$ value) {
 276         MemoryAddressImpl bb = checkAddress(obb, base, handle.length);
 277 #if[Object]
 278         return convEndian(handle.be,
 279                           UNSAFE.getAndSetReference(
 280                                   bb.unsafeGetBase(),
 281                                   offset(bb, base),
 282                                   convEndian(handle.be, value)));
 283 #else[Object]
 284         return convEndian(handle.be,
 285                           UNSAFE.getAndSet$RawType$(
 286                                   bb.unsafeGetBase(),
 287                                   offset(bb, base),
 288                                   convEndian(handle.be, value)));
 289 #end[Object]
 290     }
 291 
 292     @ForceInline
 293     static $type$ getAndSetAcquire0(MemoryAddressHandleBase handle, Object obb, long base, $type$ value) {
 294         MemoryAddressImpl bb = checkAddress(obb, base, handle.length);
 295         return convEndian(handle.be,
 296                           UNSAFE.getAndSet$RawType$Acquire(
 297                                   bb.unsafeGetBase(),
 298                                   offset(bb, base),
 299                                   convEndian(handle.be, value)));
 300     }
 301 
 302     @ForceInline
 303     static $type$ getAndSetRelease0(MemoryAddressHandleBase handle, Object obb, long base, $type$ value) {
 304         MemoryAddressImpl bb = checkAddress(obb, base, handle.length);
 305         return convEndian(handle.be,
 306                           UNSAFE.getAndSet$RawType$Release(
 307                                   bb.unsafeGetBase(),
 308                                   offset(bb, base),
 309                                   convEndian(handle.be, value)));
 310     }
 311 #end[CAS]
 312 #if[AtomicAdd]
 313 
 314     @ForceInline
 315     static $type$ getAndAdd0(MemoryAddressHandleBase handle, Object obb, long base, $type$ delta) {
 316         MemoryAddressImpl bb = checkAddress(obb, base, handle.length);
 317         if (handle.be == BE) {
 318             return UNSAFE.getAndAdd$RawType$(
 319                     bb.unsafeGetBase(),
 320                     offset(bb, base),
 321                     delta);
 322         } else {
 323             return getAndAddConvEndianWithCAS(bb, offset(bb, base), delta);
 324         }
 325     }
 326 
 327     @ForceInline
 328     static $type$ getAndAddAcquire0(MemoryAddressHandleBase handle, Object obb, long base, $type$ delta) {
 329         MemoryAddressImpl bb = checkAddress(obb, base, handle.length);
 330         if (handle.be == BE) {
 331             return UNSAFE.getAndAdd$RawType$Acquire(
 332                     bb.unsafeGetBase(),
 333                     offset(bb, base),
 334                     delta);
 335         } else {
 336             return getAndAddConvEndianWithCAS(bb, offset(bb, base), delta);
 337         }
 338     }
 339 
 340     @ForceInline
 341     static $type$ getAndAddRelease0(MemoryAddressHandleBase handle, Object obb, long base, $type$ delta) {
 342         MemoryAddressImpl bb = checkAddress(obb, base, handle.length);
 343         if (handle.be == BE) {
 344             return UNSAFE.getAndAdd$RawType$Release(
 345                     bb.unsafeGetBase(),
 346                     offset(bb, base),
 347                     delta);
 348         } else {
 349             return getAndAddConvEndianWithCAS(bb, offset(bb, base), delta);
 350         }
 351     }
 352 
 353     @ForceInline
 354     static $type$ getAndAddConvEndianWithCAS(MemoryAddressImpl bb, long offset, $type$ delta) {
 355         $type$ nativeExpectedValue, expectedValue;
 356         Object base = bb.unsafeGetBase();
 357         do {
 358             nativeExpectedValue = UNSAFE.get$RawType$Volatile(base, offset);
 359             expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue);
 360         } while (!UNSAFE.weakCompareAndSet$RawType$(base, offset,
 361                 nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue + delta)));
 362         return expectedValue;
 363     }
 364 #end[AtomicAdd]
 365 #if[Bitwise]
 366 
 367     @ForceInline
 368     static $type$ getAndBitwiseOr0(MemoryAddressHandleBase handle, Object obb, long base, $type$ value) {
 369         MemoryAddressImpl bb = checkAddress(obb, base, handle.length);
 370         if (handle.be == BE) {
 371             return UNSAFE.getAndBitwiseOr$RawType$(
 372                     bb.unsafeGetBase(),
 373                     offset(bb, base),
 374                     value);
 375         } else {
 376             return getAndBitwiseOrConvEndianWithCAS(bb, offset(bb, base), value);
 377         }
 378     }
 379 
 380     @ForceInline
 381     static $type$ getAndBitwiseOrRelease0(MemoryAddressHandleBase handle, Object obb, long base, $type$ value) {
 382         MemoryAddressImpl bb = checkAddress(obb, base, handle.length);
 383         if (handle.be == BE) {
 384             return UNSAFE.getAndBitwiseOr$RawType$Release(
 385                     bb.unsafeGetBase(),
 386                     offset(bb, base),
 387                     value);
 388         } else {
 389             return getAndBitwiseOrConvEndianWithCAS(bb, offset(bb, base), value);
 390         }
 391     }
 392 
 393     @ForceInline
 394     static $type$ getAndBitwiseOrAcquire0(MemoryAddressHandleBase handle, Object obb, long base, $type$ value) {
 395         MemoryAddressImpl bb = checkAddress(obb, base, handle.length);
 396         if (handle.be == BE) {
 397             return UNSAFE.getAndBitwiseOr$RawType$Acquire(
 398                     bb.unsafeGetBase(),
 399                     offset(bb, base),
 400                     value);
 401         } else {
 402             return getAndBitwiseOrConvEndianWithCAS(bb, offset(bb, base), value);
 403         }
 404     }
 405 
 406     @ForceInline
 407     static $type$ getAndBitwiseOrConvEndianWithCAS(MemoryAddressImpl bb, long offset, $type$ value) {
 408         $type$ nativeExpectedValue, expectedValue;
 409         Object base = bb.unsafeGetBase();
 410         do {
 411             nativeExpectedValue = UNSAFE.get$RawType$Volatile(base, offset);
 412             expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue);
 413         } while (!UNSAFE.weakCompareAndSet$RawType$(base, offset,
 414                 nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue | value)));
 415         return expectedValue;
 416     }
 417 
 418     @ForceInline
 419     static $type$ getAndBitwiseAnd0(MemoryAddressHandleBase handle, Object obb, long base, $type$ value) {
 420         MemoryAddressImpl bb = checkAddress(obb, base, handle.length);
 421         if (handle.be == BE) {
 422             return UNSAFE.getAndBitwiseAnd$RawType$(
 423                     bb.unsafeGetBase(),
 424                     offset(bb, base),
 425                     value);
 426         } else {
 427             return getAndBitwiseAndConvEndianWithCAS(bb, offset(bb, base), value);
 428         }
 429     }
 430 
 431     @ForceInline
 432     static $type$ getAndBitwiseAndRelease0(MemoryAddressHandleBase handle, Object obb, long base, $type$ value) {
 433         MemoryAddressImpl bb = checkAddress(obb, base, handle.length);
 434         if (handle.be == BE) {
 435             return UNSAFE.getAndBitwiseAnd$RawType$Release(
 436                     bb.unsafeGetBase(),
 437                     offset(bb, base),
 438                     value);
 439         } else {
 440             return getAndBitwiseAndConvEndianWithCAS(bb, offset(bb, base), value);
 441         }
 442     }
 443 
 444     @ForceInline
 445     static $type$ getAndBitwiseAndAcquire0(MemoryAddressHandleBase handle, Object obb, long base, $type$ value) {
 446         MemoryAddressImpl bb = checkAddress(obb, base, handle.length);
 447         if (handle.be == BE) {
 448             return UNSAFE.getAndBitwiseAnd$RawType$Acquire(
 449                     bb.unsafeGetBase(),
 450                     offset(bb, base),
 451                     value);
 452         } else {
 453             return getAndBitwiseAndConvEndianWithCAS(bb, offset(bb, base), value);
 454         }
 455     }
 456 
 457     @ForceInline
 458     static $type$ getAndBitwiseAndConvEndianWithCAS(MemoryAddressImpl bb, long offset, $type$ value) {
 459         $type$ nativeExpectedValue, expectedValue;
 460         Object base = bb.unsafeGetBase();
 461         do {
 462             nativeExpectedValue = UNSAFE.get$RawType$Volatile(base, offset);
 463             expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue);
 464         } while (!UNSAFE.weakCompareAndSet$RawType$(base, offset,
 465                 nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue & value)));
 466         return expectedValue;
 467     }
 468 
 469 
 470     @ForceInline
 471     static $type$ getAndBitwiseXor0(MemoryAddressHandleBase handle, Object obb, long base, $type$ value) {
 472         MemoryAddressImpl bb = checkAddress(obb, base, handle.length);
 473         if (handle.be == BE) {
 474             return UNSAFE.getAndBitwiseXor$RawType$(
 475                     bb.unsafeGetBase(),
 476                     offset(bb, base),
 477                     value);
 478         } else {
 479             return getAndBitwiseXorConvEndianWithCAS(bb, offset(bb, base), value);
 480         }
 481     }
 482 
 483     @ForceInline
 484     static $type$ getAndBitwiseXorRelease0(MemoryAddressHandleBase handle, Object obb, long base, $type$ value) {
 485         MemoryAddressImpl bb = checkAddress(obb, base, handle.length);
 486         if (handle.be == BE) {
 487             return UNSAFE.getAndBitwiseXor$RawType$Release(
 488                     bb.unsafeGetBase(),
 489                     offset(bb, base),
 490                     value);
 491         } else {
 492             return getAndBitwiseXorConvEndianWithCAS(bb, offset(bb, base), value);
 493         }
 494     }
 495 
 496     @ForceInline
 497     static $type$ getAndBitwiseXorAcquire0(MemoryAddressHandleBase handle, Object obb, long base, $type$ value) {
 498         MemoryAddressImpl bb = checkAddress(obb, base, handle.length);
 499         if (handle.be == BE) {
 500             return UNSAFE.getAndBitwiseXor$RawType$Acquire(
 501                     bb.unsafeGetBase(),
 502                     offset(bb, base),
 503                     value);
 504         } else {
 505             return getAndBitwiseXorConvEndianWithCAS(bb, offset(bb, base), value);
 506         }
 507     }
 508 
 509     @ForceInline
 510     static $type$ getAndBitwiseXorConvEndianWithCAS(MemoryAddressImpl bb, long offset, $type$ value) {
 511         $type$ nativeExpectedValue, expectedValue;
 512         Object base = bb.unsafeGetBase();
 513         do {
 514             nativeExpectedValue = UNSAFE.get$RawType$Volatile(base, offset);
 515             expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue);
 516         } while (!UNSAFE.weakCompareAndSet$RawType$(base, offset,
 517                 nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue ^ value)));
 518         return expectedValue;
 519     }
 520 #end[Bitwise]
 521     
 522     static abstract class MemoryAddressHandleBase extends VarHandle {
 523         final boolean be;
 524         final long length;
 525         final long offset;
 526             
 527         MemoryAddressHandleBase(VarForm form, boolean be, long length, long offset) {
 528             super(form);
 529             this.be = be;
 530             this.length = length;
 531             this.offset = offset;
 532         }   
 533     }
 534 }