1 /*
   2  * Copyright (c) 2000, 2024, 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 
  26 package sun.misc;
  27 
  28 import java.lang.foreign.Arena;
  29 import java.lang.foreign.MemoryLayout;
  30 import java.lang.foreign.MemorySegment;
  31 import java.lang.foreign.ValueLayout;
  32 import java.lang.invoke.VarHandle;
  33 import java.lang.reflect.Field;
  34 import java.net.URL;
  35 import java.security.AccessController;
  36 import java.security.CodeSource;
  37 import java.security.ProtectionDomain;
  38 import java.security.PrivilegedAction;
  39 import java.util.List;
  40 import java.util.Set;
  41 
  42 import jdk.internal.vm.annotation.ForceInline;
  43 import jdk.internal.vm.annotation.Stable;
  44 import jdk.internal.misc.VM;
  45 import jdk.internal.reflect.CallerSensitive;
  46 import jdk.internal.reflect.Reflection;
  47 
  48 /**
  49  * A collection of methods for performing low-level, unsafe operations.
  50  * Although the class and all methods are public, use of this class is
  51  * limited because only trusted code can obtain instances of it.
  52  *
  53  * <em>Note:</em> It is the responsibility of the caller to make sure
  54  * arguments are checked before methods of this class are
  55  * called. While some rudimentary checks are performed on the input,
  56  * the checks are best effort and when performance is an overriding
  57  * priority, as when methods of this class are optimized by the
  58  * runtime compiler, some or all checks (if any) may be elided. Hence,
  59  * the caller must not rely on the checks and corresponding
  60  * exceptions!
  61  *
  62  * @apiNote
  63  * This class pre-dates the introduction of {@link VarHandle}, low-level access to
  64  * memory with {@linkplain java.lang.foreign}, and other standard APIs. New code
  65  * should not use this API.
  66  *
  67  * @author John R. Rose
  68  * @see #getUnsafe
  69  */
  70 
  71 public final class Unsafe {
  72 
  73     static {
  74         Reflection.registerMethodsToFilter(Unsafe.class, Set.of("getUnsafe"));
  75     }
  76 
  77     private Unsafe() {}
  78 
  79     private static final Unsafe theUnsafe = new Unsafe();
  80     private static final jdk.internal.misc.Unsafe theInternalUnsafe = jdk.internal.misc.Unsafe.getUnsafe();
  81 
  82     /**
  83      * Provides the caller with the capability of performing unsafe
  84      * operations.
  85      *
  86      * <p>The returned {@code Unsafe} object should be carefully guarded
  87      * by the caller, since it can be used to read and write data at arbitrary
  88      * memory addresses.  It must never be passed to untrusted code.
  89      *
  90      * <p>Most methods in this class are very low-level, and correspond to a
  91      * small number of hardware instructions (on typical machines).  Compilers
  92      * are encouraged to optimize these methods accordingly.
  93      *
  94      * <p>Here is a suggested idiom for using unsafe operations:
  95      *
  96      * <pre> {@code
  97      * class MyTrustedClass {
  98      *   private static final Unsafe unsafe = Unsafe.getUnsafe();
  99      *   ...
 100      *   private long myCountAddress = ...;
 101      *   public int getCount() { return unsafe.getByte(myCountAddress); }
 102      * }}</pre>
 103      *
 104      * (It may assist compilers to make the local variable {@code final}.)
 105      *
 106      * @throws  SecurityException if the class loader of the caller
 107      *          class is not in the system domain in which all permissions
 108      *          are granted.
 109      */
 110     @CallerSensitive
 111     public static Unsafe getUnsafe() {
 112         Class<?> caller = Reflection.getCallerClass();
 113         if (!VM.isSystemDomainLoader(caller.getClassLoader()))
 114             throw new SecurityException("Unsafe");
 115         return theUnsafe;
 116     }
 117 
 118     //| peek and poke operations
 119     //| (compilers should optimize these to memory ops)
 120 
 121     // These work on object fields in the Java heap.
 122     // They will not work on elements of packed arrays.
 123 
 124     /**
 125      * Fetches a value from a given Java variable.
 126      * More specifically, fetches a field or array element within the given
 127      * object {@code o} at the given offset, or (if {@code o} is null)
 128      * from the memory address whose numerical value is the given offset.
 129      * <p>
 130      * The results are undefined unless one of the following cases is true:
 131      * <ul>
 132      * <li>The offset was obtained from {@link #objectFieldOffset} on
 133      * the {@link java.lang.reflect.Field} of some Java field and the object
 134      * referred to by {@code o} is of a class compatible with that
 135      * field's class.
 136      *
 137      * <li>The offset and object reference {@code o} (either null or
 138      * non-null) were both obtained via {@link #staticFieldOffset}
 139      * and {@link #staticFieldBase} (respectively) from the
 140      * reflective {@link Field} representation of some Java field.
 141      *
 142      * <li>The object referred to by {@code o} is an array, and the offset
 143      * is an integer of the form {@code B+N*S}, where {@code N} is
 144      * a valid index into the array, and {@code B} and {@code S} are
 145      * the values obtained by {@link #arrayBaseOffset} and {@link
 146      * #arrayIndexScale} (respectively) from the array's class.  The value
 147      * referred to is the {@code N}<em>th</em> element of the array.
 148      *
 149      * </ul>
 150      * <p>
 151      * If one of the above cases is true, the call references a specific Java
 152      * variable (field or array element).  However, the results are undefined
 153      * if that variable is not in fact of the type returned by this method.
 154      * <p>
 155      * This method refers to a variable by means of two parameters, and so
 156      * it provides (in effect) a <em>double-register</em> addressing mode
 157      * for Java variables.  When the object reference is null, this method
 158      * uses its offset as an absolute address.  This is similar in operation
 159      * to methods such as {@link #getInt(long)}, which provide (in effect) a
 160      * <em>single-register</em> addressing mode for non-Java variables.
 161      * However, because Java variables may have a different layout in memory
 162      * from non-Java variables, programmers should not assume that these
 163      * two addressing modes are ever equivalent.  Also, programmers should
 164      * remember that offsets from the double-register addressing mode cannot
 165      * be portably confused with longs used in the single-register addressing
 166      * mode.
 167      *
 168      * @deprecated Use {@link VarHandle#get(Object...)} or
 169      * {@link MemorySegment#get(ValueLayout.OfInt, long)} instead.
 170      *
 171      * @param o Java heap object in which the variable resides, if any, else
 172      *        null
 173      * @param offset indication of where the variable resides in a Java heap
 174      *        object, if any, else a memory address locating the variable
 175      *        statically
 176      * @return the value fetched from the indicated Java variable
 177      * @throws RuntimeException No defined exceptions are thrown, not even
 178      *         {@link NullPointerException}
 179      */
 180     @Deprecated(since="23", forRemoval=true)
 181     @ForceInline
 182     public int getInt(Object o, long offset) {
 183         beforeMemoryAccess();
 184         return theInternalUnsafe.getInt(o, offset);
 185     }
 186 
 187     /**
 188      * Stores a value into a given Java variable.
 189      * <p>
 190      * The first two parameters are interpreted exactly as with
 191      * {@link #getInt(Object, long)} to refer to a specific
 192      * Java variable (field or array element).  The given value
 193      * is stored into that variable.
 194      * <p>
 195      * The variable must be of the same type as the method
 196      * parameter {@code x}.
 197      *
 198      * @deprecated Use {@link VarHandle#set(Object...)} or
 199      * {@link MemorySegment#set(ValueLayout.OfInt, long, int)} instead.
 200      *
 201      * @param o Java heap object in which the variable resides, if any, else
 202      *        null
 203      * @param offset indication of where the variable resides in a Java heap
 204      *        object, if any, else a memory address locating the variable
 205      *        statically
 206      * @param x the value to store into the indicated Java variable
 207      * @throws RuntimeException No defined exceptions are thrown, not even
 208      *         {@link NullPointerException}
 209      */
 210     @Deprecated(since="23", forRemoval=true)
 211     @ForceInline
 212     public void putInt(Object o, long offset, int x) {
 213         beforeMemoryAccess();
 214         theInternalUnsafe.putInt(o, offset, x);
 215     }
 216 
 217     /**
 218      * Fetches a reference value from a given Java variable.
 219      *
 220      * @deprecated Use {@link VarHandle#get(Object...)} instead.
 221      */
 222     @Deprecated(since="23", forRemoval=true)
 223     @ForceInline
 224     public Object getObject(Object o, long offset) {
 225         beforeMemoryAccess();
 226         return theInternalUnsafe.getReference(o, offset);
 227     }
 228 
 229     /**
 230      * Stores a reference value into a given Java variable.
 231      * <p>
 232      * Unless the reference {@code x} being stored is either null
 233      * or matches the field type, the results are undefined.
 234      * If the reference {@code o} is non-null, card marks or
 235      * other store barriers for that object (if the VM requires them)
 236      * are updated.
 237      *
 238      * @deprecated Use {@link VarHandle#set(Object...)} instead.
 239      */
 240     @Deprecated(since="23", forRemoval=true)
 241     @ForceInline
 242     public void putObject(Object o, long offset, Object x) {
 243         beforeMemoryAccess();
 244         theInternalUnsafe.putReference(o, offset, x);
 245     }
 246 
 247     /**
 248      * @deprecated Use {@link VarHandle#get(Object...)} or
 249      * {@link MemorySegment#get(ValueLayout.OfBoolean, long)} instead.
 250      *
 251      * @see #getInt(Object, long)
 252      */
 253     @Deprecated(since="23", forRemoval=true)
 254     @ForceInline
 255     public boolean getBoolean(Object o, long offset) {
 256         beforeMemoryAccess();
 257         return theInternalUnsafe.getBoolean(o, offset);
 258     }
 259 
 260     /**
 261      * @deprecated Use {@link VarHandle#set(Object...)} or
 262      * {@link MemorySegment#set(ValueLayout.OfBoolean, long, boolean)} instead.
 263      *
 264      * @see #putInt(Object, long, int)
 265      */
 266     @Deprecated(since="23", forRemoval=true)
 267     @ForceInline
 268     public void putBoolean(Object o, long offset, boolean x) {
 269         beforeMemoryAccess();
 270         theInternalUnsafe.putBoolean(o, offset, x);
 271     }
 272 
 273     /**
 274      * @deprecated Use {@link VarHandle#get(Object...)} or
 275      * {@link MemorySegment#get(ValueLayout.OfByte, long)} instead.
 276      *
 277      * @see #getInt(Object, long)
 278      */
 279     @Deprecated(since="23", forRemoval=true)
 280     @ForceInline
 281     public byte getByte(Object o, long offset) {
 282         beforeMemoryAccess();
 283         return theInternalUnsafe.getByte(o, offset);
 284     }
 285 
 286     /**
 287      * @deprecated Use {@link VarHandle#set(Object...)} or
 288      * {@link MemorySegment#set(ValueLayout.OfByte, long, byte)} instead.
 289      *
 290      * @see #putInt(Object, long, int)
 291      */
 292     @Deprecated(since="23", forRemoval=true)
 293     @ForceInline
 294     public void putByte(Object o, long offset, byte x) {
 295         beforeMemoryAccess();
 296         theInternalUnsafe.putByte(o, offset, x);
 297     }
 298 
 299     /**
 300      * @deprecated Use {@link VarHandle#get(Object...)} or
 301      * {@link MemorySegment#get(ValueLayout.OfShort, long)} instead.
 302      *
 303      * @see #getInt(Object, long)
 304      */
 305     @Deprecated(since="23", forRemoval=true)
 306     @ForceInline
 307     public short getShort(Object o, long offset) {
 308         beforeMemoryAccess();
 309         return theInternalUnsafe.getShort(o, offset);
 310     }
 311 
 312     /**
 313      * @deprecated Use {@link VarHandle#set(Object...)} or
 314      * {@link MemorySegment#set(ValueLayout.OfShort, long, short)} instead.
 315      *
 316      * @see #putInt(Object, long, int)
 317      */
 318     @Deprecated(since="23", forRemoval=true)
 319     @ForceInline
 320     public void putShort(Object o, long offset, short x) {
 321         beforeMemoryAccess();
 322         theInternalUnsafe.putShort(o, offset, x);
 323     }
 324 
 325     /**
 326      * @deprecated Use {@link VarHandle#get(Object...)} or
 327      * {@link MemorySegment#get(ValueLayout.OfChar, long)} instead.
 328      *
 329      * @see #getInt(Object, long)
 330      */
 331     @Deprecated(since="23", forRemoval=true)
 332     @ForceInline
 333     public char getChar(Object o, long offset) {
 334         beforeMemoryAccess();
 335         return theInternalUnsafe.getChar(o, offset);
 336     }
 337 
 338     /**
 339      * @deprecated Use {@link VarHandle#set(Object...)} or
 340      * {@link MemorySegment#set(ValueLayout.OfChar, long, char)} instead.
 341      *
 342      * @see #putInt(Object, long, int)
 343      */
 344     @Deprecated(since="23", forRemoval=true)
 345     @ForceInline
 346     public void putChar(Object o, long offset, char x) {
 347         beforeMemoryAccess();
 348         theInternalUnsafe.putChar(o, offset, x);
 349     }
 350 
 351     /**
 352      * @deprecated Use {@link VarHandle#get(Object...)} or
 353      * {@link MemorySegment#get(ValueLayout.OfLong, long)} instead.
 354      *
 355      * @see #getInt(Object, long)
 356      */
 357     @Deprecated(since="23", forRemoval=true)
 358     @ForceInline
 359     public long getLong(Object o, long offset) {
 360         beforeMemoryAccess();
 361         return theInternalUnsafe.getLong(o, offset);
 362     }
 363 
 364     /**
 365      * @deprecated Use {@link VarHandle#set(Object...)} or
 366      * {@link MemorySegment#set(ValueLayout.OfLong, long, long)} instead.
 367      *
 368      * @see #putInt(Object, long, int)
 369      */
 370     @Deprecated(since="23", forRemoval=true)
 371     @ForceInline
 372     public void putLong(Object o, long offset, long x) {
 373         beforeMemoryAccess();
 374         theInternalUnsafe.putLong(o, offset, x);
 375     }
 376 
 377     /**
 378      * @deprecated Use {@link VarHandle#get(Object...)} or
 379      * {@link MemorySegment#get(ValueLayout.OfFloat, long)} instead.
 380      *
 381      * @see #getInt(Object, long)
 382      */
 383     @Deprecated(since="23", forRemoval=true)
 384     @ForceInline
 385     public float getFloat(Object o, long offset) {
 386         beforeMemoryAccess();
 387         return theInternalUnsafe.getFloat(o, offset);
 388     }
 389 
 390     /**
 391      * @deprecated Use {@link VarHandle#set(Object...)} or
 392      * {@link MemorySegment#set(ValueLayout.OfFloat, long, float)} instead.
 393      *
 394      * @see #putInt(Object, long, int)
 395      */
 396     @Deprecated(since="23", forRemoval=true)
 397     @ForceInline
 398     public void putFloat(Object o, long offset, float x) {
 399         beforeMemoryAccess();
 400         theInternalUnsafe.putFloat(o, offset, x);
 401     }
 402 
 403     /**
 404      * @deprecated Use {@link VarHandle#get(Object...)} or
 405      * {@link MemorySegment#get(ValueLayout.OfDouble, long)} instead.
 406      *
 407      * @see #getInt(Object, long)
 408      */
 409     @Deprecated(since="23", forRemoval=true)
 410     @ForceInline
 411     public double getDouble(Object o, long offset) {
 412         beforeMemoryAccess();
 413         return theInternalUnsafe.getDouble(o, offset);
 414     }
 415 
 416     /**
 417      * @deprecated Use {@link VarHandle#set(Object...)} or
 418      * {@link MemorySegment#set(ValueLayout.OfDouble, long, double)} instead.
 419      *
 420      * @see #putInt(Object, long, int)
 421      */
 422     @Deprecated(since="23", forRemoval=true)
 423     @ForceInline
 424     public void putDouble(Object o, long offset, double x) {
 425         beforeMemoryAccess();
 426         theInternalUnsafe.putDouble(o, offset, x);
 427     }
 428 
 429     // These work on values in the C heap.
 430 
 431     /**
 432      * Fetches a value from a given memory address.  If the address is zero, or
 433      * does not point into a block obtained from {@link #allocateMemory}, the
 434      * results are undefined.
 435      *
 436      * @deprecated Use {@link java.lang.foreign} to access off-heap memory.
 437      *
 438      * @see #allocateMemory
 439      */
 440     @Deprecated(since="23", forRemoval=true)
 441     @ForceInline
 442     public byte getByte(long address) {
 443         beforeMemoryAccess();
 444         return theInternalUnsafe.getByte(address);
 445     }
 446 
 447     /**
 448      * Stores a value into a given memory address.  If the address is zero, or
 449      * does not point into a block obtained from {@link #allocateMemory}, the
 450      * results are undefined.
 451      *
 452      * @deprecated Use {@link java.lang.foreign} to access off-heap memory.
 453      *
 454      * @see #getByte(long)
 455      */
 456     @Deprecated(since="23", forRemoval=true)
 457     @ForceInline
 458     public void putByte(long address, byte x) {
 459         beforeMemoryAccess();
 460         theInternalUnsafe.putByte(address, x);
 461     }
 462 
 463     /**
 464      * @deprecated Use {@link java.lang.foreign} to access off-heap memory.
 465      *
 466      * @see #getByte(long)
 467      */
 468     @Deprecated(since="23", forRemoval=true)
 469     @ForceInline
 470     public short getShort(long address) {
 471         beforeMemoryAccess();
 472         return theInternalUnsafe.getShort(address);
 473     }
 474 
 475     /**
 476      * @deprecated Use {@link java.lang.foreign} to access off-heap memory.
 477      *
 478      * @see #putByte(long, byte)
 479      */
 480     @Deprecated(since="23", forRemoval=true)
 481     @ForceInline
 482     public void putShort(long address, short x) {
 483         beforeMemoryAccess();
 484         theInternalUnsafe.putShort(address, x);
 485     }
 486 
 487     /**
 488      * @deprecated Use {@link java.lang.foreign} to access off-heap memory.
 489      *
 490      * @see #getByte(long)
 491      */
 492     @Deprecated(since="23", forRemoval=true)
 493     @ForceInline
 494     public char getChar(long address) {
 495         beforeMemoryAccess();
 496         return theInternalUnsafe.getChar(address);
 497     }
 498 
 499     /**
 500      * @deprecated Use {@link java.lang.foreign} to access off-heap memory.
 501      *
 502      * @see #putByte(long, byte)
 503      */
 504     @Deprecated(since="23", forRemoval=true)
 505     @ForceInline
 506     public void putChar(long address, char x) {
 507         beforeMemoryAccess();
 508         theInternalUnsafe.putChar(address, x);
 509     }
 510 
 511     /**
 512      * @deprecated Use {@link java.lang.foreign} to access off-heap memory.
 513      *
 514      * @see #getByte(long)
 515      */
 516     @Deprecated(since="23", forRemoval=true)
 517     @ForceInline
 518     public int getInt(long address) {
 519         beforeMemoryAccess();
 520         return theInternalUnsafe.getInt(address);
 521     }
 522 
 523     /**
 524      * @deprecated Use {@link java.lang.foreign} to access off-heap memory.
 525      *
 526      * @see #putByte(long, byte)
 527      */
 528     @Deprecated(since="23", forRemoval=true)
 529     @ForceInline
 530     public void putInt(long address, int x) {
 531         beforeMemoryAccess();
 532         theInternalUnsafe.putInt(address, x);
 533     }
 534 
 535     /**
 536      * @deprecated Use {@link java.lang.foreign} to access off-heap memory.
 537      *
 538      * @see #getByte(long)
 539      */
 540     @Deprecated(since="23", forRemoval=true)
 541     @ForceInline
 542     public long getLong(long address) {
 543         beforeMemoryAccess();
 544         return theInternalUnsafe.getLong(address);
 545     }
 546 
 547     /**
 548      * @deprecated Use {@link java.lang.foreign} to access off-heap memory.
 549      *
 550      * @see #putByte(long, byte)
 551      */
 552     @Deprecated(since="23", forRemoval=true)
 553     @ForceInline
 554     public void putLong(long address, long x) {
 555         beforeMemoryAccess();
 556         theInternalUnsafe.putLong(address, x);
 557     }
 558 
 559     /**
 560      * @deprecated Use {@link java.lang.foreign} to access off-heap memory.
 561      *
 562      * @see #getByte(long)
 563      */
 564     @Deprecated(since="23", forRemoval=true)
 565     @ForceInline
 566     public float getFloat(long address) {
 567         beforeMemoryAccess();
 568         return theInternalUnsafe.getFloat(address);
 569     }
 570 
 571     /**
 572      * @deprecated Use {@link java.lang.foreign} to access off-heap memory.
 573      *
 574      * @see #putByte(long, byte)
 575      */
 576     @Deprecated(since="23", forRemoval=true)
 577     @ForceInline
 578     public void putFloat(long address, float x) {
 579         beforeMemoryAccess();
 580         theInternalUnsafe.putFloat(address, x);
 581     }
 582 
 583     /**
 584      * @deprecated Use {@link java.lang.foreign} to access off-heap memory.
 585      *
 586      * @see #getByte(long)
 587      */
 588     @Deprecated(since="23", forRemoval=true)
 589     @ForceInline
 590     public double getDouble(long address) {
 591         beforeMemoryAccess();
 592         return theInternalUnsafe.getDouble(address);
 593     }
 594 
 595     /**
 596      * @deprecated Use {@link java.lang.foreign} to access off-heap memory.
 597      *
 598      * @see #putByte(long, byte)
 599      */
 600     @Deprecated(since="23", forRemoval=true)
 601     @ForceInline
 602     public void putDouble(long address, double x) {
 603         beforeMemoryAccess();
 604         theInternalUnsafe.putDouble(address, x);
 605     }
 606 
 607 
 608     /**
 609      * Fetches a native pointer from a given memory address.  If the address is
 610      * zero, or does not point into a block obtained from {@link
 611      * #allocateMemory}, the results are undefined.
 612      *
 613      * <p>If the native pointer is less than 64 bits wide, it is extended as
 614      * an unsigned number to a Java long.  The pointer may be indexed by any
 615      * given byte offset, simply by adding that offset (as a simple integer) to
 616      * the long representing the pointer.  The number of bytes actually read
 617      * from the target address may be determined by consulting {@link
 618      * #addressSize}.
 619      *
 620      * @deprecated Use {@link java.lang.foreign} to access off-heap memory.
 621      *
 622      * @see #allocateMemory
 623      */
 624     @Deprecated(since="23", forRemoval=true)
 625     @ForceInline
 626     public long getAddress(long address) {
 627         beforeMemoryAccess();
 628         return theInternalUnsafe.getAddress(address);
 629     }
 630 
 631     /**
 632      * Stores a native pointer into a given memory address.  If the address is
 633      * zero, or does not point into a block obtained from {@link
 634      * #allocateMemory}, the results are undefined.
 635      *
 636      * <p>The number of bytes actually written at the target address may be
 637      * determined by consulting {@link #addressSize}.
 638      *
 639      * @deprecated Use {@link java.lang.foreign} to access off-heap memory.
 640      *
 641      * @see #getAddress(long)
 642      */
 643     @Deprecated(since="23", forRemoval=true)
 644     @ForceInline
 645     public void putAddress(long address, long x) {
 646         beforeMemoryAccess();
 647         theInternalUnsafe.putAddress(address, x);
 648     }
 649 
 650 
 651     //| wrappers for malloc, realloc, free:
 652 
 653     /**
 654      * Allocates a new block of native memory, of the given size in bytes.  The
 655      * contents of the memory are uninitialized; they will generally be
 656      * garbage.  The resulting native pointer will be zero if and only if the
 657      * requested size is zero.  The resulting native pointer will be aligned for
 658      * all value types.   Dispose of this memory by calling {@link #freeMemory}
 659      * or resize it with {@link #reallocateMemory}.
 660      *
 661      * <em>Note:</em> It is the responsibility of the caller to make
 662      * sure arguments are checked before the methods are called. While
 663      * some rudimentary checks are performed on the input, the checks
 664      * are best effort and when performance is an overriding priority,
 665      * as when methods of this class are optimized by the runtime
 666      * compiler, some or all checks (if any) may be elided. Hence, the
 667      * caller must not rely on the checks and corresponding
 668      * exceptions!
 669      *
 670      * @deprecated Use {@link java.lang.foreign} to allocate off-heap memory.
 671      *
 672      * @throws RuntimeException if the size is negative or too large
 673      *         for the native size_t type
 674      *
 675      * @throws OutOfMemoryError if the allocation is refused by the system
 676      *
 677      * @see #getByte(long)
 678      * @see #putByte(long, byte)
 679      */
 680     @Deprecated(since="23", forRemoval=true)
 681     @ForceInline
 682     public long allocateMemory(long bytes) {
 683         beforeMemoryAccess();
 684         return theInternalUnsafe.allocateMemory(bytes);
 685     }
 686 
 687     /**
 688      * Resizes a new block of native memory, to the given size in bytes.  The
 689      * contents of the new block past the size of the old block are
 690      * uninitialized; they will generally be garbage.  The resulting native
 691      * pointer will be zero if and only if the requested size is zero.  The
 692      * resulting native pointer will be aligned for all value types.  Dispose
 693      * of this memory by calling {@link #freeMemory}, or resize it with {@link
 694      * #reallocateMemory}.  The address passed to this method may be null, in
 695      * which case an allocation will be performed.
 696      *
 697      * <em>Note:</em> It is the responsibility of the caller to make
 698      * sure arguments are checked before the methods are called. While
 699      * some rudimentary checks are performed on the input, the checks
 700      * are best effort and when performance is an overriding priority,
 701      * as when methods of this class are optimized by the runtime
 702      * compiler, some or all checks (if any) may be elided. Hence, the
 703      * caller must not rely on the checks and corresponding
 704      * exceptions!
 705      *
 706      * @deprecated Use {@link java.lang.foreign} to allocate off-heap memory.
 707      *
 708      * @throws RuntimeException if the size is negative or too large
 709      *         for the native size_t type
 710      *
 711      * @throws OutOfMemoryError if the allocation is refused by the system
 712      *
 713      * @see #allocateMemory
 714      */
 715     @Deprecated(since="23", forRemoval=true)
 716     @ForceInline
 717     public long reallocateMemory(long address, long bytes) {
 718         beforeMemoryAccess();
 719         return theInternalUnsafe.reallocateMemory(address, bytes);
 720     }
 721 
 722     /**
 723      * Sets all bytes in a given block of memory to a fixed value
 724      * (usually zero).
 725      *
 726      * <p>This method determines a block's base address by means of two parameters,
 727      * and so it provides (in effect) a <em>double-register</em> addressing mode,
 728      * as discussed in {@link #getInt(Object,long)}.  When the object reference is null,
 729      * the offset supplies an absolute base address.
 730      *
 731      * <p>The stores are in coherent (atomic) units of a size determined
 732      * by the address and length parameters.  If the effective address and
 733      * length are all even modulo 8, the stores take place in 'long' units.
 734      * If the effective address and length are (resp.) even modulo 4 or 2,
 735      * the stores take place in units of 'int' or 'short'.
 736      *
 737      * <em>Note:</em> It is the responsibility of the caller to make
 738      * sure arguments are checked before the methods are called. While
 739      * some rudimentary checks are performed on the input, the checks
 740      * are best effort and when performance is an overriding priority,
 741      * as when methods of this class are optimized by the runtime
 742      * compiler, some or all checks (if any) may be elided. Hence, the
 743      * caller must not rely on the checks and corresponding
 744      * exceptions!
 745      *
 746      * @deprecated {@link MemorySegment#fill(byte)} fills the contents of a memory
 747      * segment with a given value.
 748      *
 749      * @throws RuntimeException if any of the arguments is invalid
 750      *
 751      * @since 1.7
 752      */
 753     @Deprecated(since="23", forRemoval=true)
 754     @ForceInline
 755     public void setMemory(Object o, long offset, long bytes, byte value) {
 756         beforeMemoryAccess();
 757         theInternalUnsafe.setMemory(o, offset, bytes, value);
 758     }
 759 
 760     /**
 761      * Sets all bytes in a given block of memory to a fixed value
 762      * (usually zero).  This provides a <em>single-register</em> addressing mode,
 763      * as discussed in {@link #getInt(Object,long)}.
 764      *
 765      * <p>Equivalent to {@code setMemory(null, address, bytes, value)}.
 766      *
 767      * @deprecated {@link MemorySegment#fill(byte)} fills the contents of a memory
 768      * segment with a given value.
 769      *
 770      * Use {@link MemorySegment} and its bulk copy methods instead.
 771      */
 772     @Deprecated(since="23", forRemoval=true)
 773     @ForceInline
 774     public void setMemory(long address, long bytes, byte value) {
 775         beforeMemoryAccess();
 776         theInternalUnsafe.setMemory(address, bytes, value);
 777     }
 778 
 779     /**
 780      * Sets all bytes in a given block of memory to a copy of another
 781      * block.
 782      *
 783      * <p>This method determines each block's base address by means of two parameters,
 784      * and so it provides (in effect) a <em>double-register</em> addressing mode,
 785      * as discussed in {@link #getInt(Object,long)}.  When the object reference is null,
 786      * the offset supplies an absolute base address.
 787      *
 788      * <p>The transfers are in coherent (atomic) units of a size determined
 789      * by the address and length parameters.  If the effective addresses and
 790      * length are all even modulo 8, the transfer takes place in 'long' units.
 791      * If the effective addresses and length are (resp.) even modulo 4 or 2,
 792      * the transfer takes place in units of 'int' or 'short'.
 793      *
 794      * <em>Note:</em> It is the responsibility of the caller to make
 795      * sure arguments are checked before the methods are called. While
 796      * some rudimentary checks are performed on the input, the checks
 797      * are best effort and when performance is an overriding priority,
 798      * as when methods of this class are optimized by the runtime
 799      * compiler, some or all checks (if any) may be elided. Hence, the
 800      * caller must not rely on the checks and corresponding
 801      * exceptions!
 802      *
 803      * @deprecated Use {@link MemorySegment} and its bulk copy methods instead.
 804      *
 805      * @throws RuntimeException if any of the arguments is invalid
 806      *
 807      * @since 1.7
 808      */
 809     @Deprecated(since="23", forRemoval=true)
 810     @ForceInline
 811     public void copyMemory(Object srcBase, long srcOffset,
 812                            Object destBase, long destOffset,
 813                            long bytes) {
 814         beforeMemoryAccess();
 815         theInternalUnsafe.copyMemory(srcBase, srcOffset, destBase, destOffset, bytes);
 816     }
 817 
 818     /**
 819      * Sets all bytes in a given block of memory to a copy of another
 820      * block.  This provides a <em>single-register</em> addressing mode,
 821      * as discussed in {@link #getInt(Object,long)}.
 822      *
 823      * Equivalent to {@code copyMemory(null, srcAddress, null, destAddress, bytes)}.
 824      *
 825      * @deprecated Use {@link MemorySegment} and its bulk copy methods instead.
 826      */
 827     @Deprecated(since="23", forRemoval=true)
 828     @ForceInline
 829     public void copyMemory(long srcAddress, long destAddress, long bytes) {
 830         beforeMemoryAccess();
 831         theInternalUnsafe.copyMemory(srcAddress, destAddress, bytes);
 832     }
 833 
 834     /**
 835      * Disposes of a block of native memory, as obtained from {@link
 836      * #allocateMemory} or {@link #reallocateMemory}.  The address passed to
 837      * this method may be null, in which case no action is taken.
 838      *
 839      * <em>Note:</em> It is the responsibility of the caller to make
 840      * sure arguments are checked before the methods are called. While
 841      * some rudimentary checks are performed on the input, the checks
 842      * are best effort and when performance is an overriding priority,
 843      * as when methods of this class are optimized by the runtime
 844      * compiler, some or all checks (if any) may be elided. Hence, the
 845      * caller must not rely on the checks and corresponding
 846      * exceptions!
 847      *
 848      * @deprecated Use {@link java.lang.foreign} to allocate and free off-heap memory.
 849      *
 850      * @throws RuntimeException if any of the arguments is invalid
 851      *
 852      * @see #allocateMemory
 853      */
 854     @Deprecated(since="23", forRemoval=true)
 855     @ForceInline
 856     public void freeMemory(long address) {
 857         beforeMemoryAccess();
 858         theInternalUnsafe.freeMemory(address);
 859     }
 860 
 861     //| random queries
 862 
 863     /**
 864      * This constant differs from all results that will ever be returned from
 865      * {@link #staticFieldOffset}, {@link #objectFieldOffset},
 866      * or {@link #arrayBaseOffset}.
 867      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
 868      */
 869     @Deprecated(since="23", forRemoval=true)
 870     public static final int INVALID_FIELD_OFFSET = jdk.internal.misc.Unsafe.INVALID_FIELD_OFFSET;
 871 
 872     /**
 873      * Reports the location of a given field in the storage allocation of its
 874      * class.  Do not expect to perform any sort of arithmetic on this offset;
 875      * it is just a cookie which is passed to the unsafe heap memory accessors.
 876      *
 877      * <p>Any given field will always have the same offset and base, and no
 878      * two distinct fields of the same class will ever have the same offset
 879      * and base.
 880      *
 881      * <p>As of 1.4.1, offsets for fields are represented as long values,
 882      * although the Sun JVM does not use the most significant 32 bits.
 883      * However, JVM implementations which store static fields at absolute
 884      * addresses can use long offsets and null base pointers to express
 885      * the field locations in a form usable by {@link #getInt(Object,long)}.
 886      * Therefore, code which will be ported to such JVMs on 64-bit platforms
 887      * must preserve all bits of static field offsets.
 888      *
 889      * @deprecated The guarantee that a field will always have the same offset
 890      * and base may not be true in a future release. The ability to provide an
 891      * offset and object reference to a heap memory accessor will be removed
 892      * in a future release. Use {@link VarHandle} instead.
 893      *
 894      * @see #getInt(Object, long)
 895      */
 896     @Deprecated(since="18", forRemoval=true)
 897     @ForceInline
 898     @SuppressWarnings("preview")
 899     public long objectFieldOffset(Field f) {
 900         if (f == null) {
 901             throw new NullPointerException();
 902         }
 903         Class<?> declaringClass = f.getDeclaringClass();
 904         if (declaringClass.isHidden()) {
 905             throw new UnsupportedOperationException("can't get field offset on a hidden class: " + f);
 906         }
 907         if (declaringClass.isRecord()) {
 908             throw new UnsupportedOperationException("can't get field offset on a record class: " + f);
 909         }
 910         if (declaringClass.isValue()) {
 911             throw new UnsupportedOperationException("can't get field offset on a value class: " + f);
 912         }
 913         beforeMemoryAccess();
 914         return theInternalUnsafe.objectFieldOffset(f);
 915     }
 916 
 917     /**
 918      * Reports the location of a given static field, in conjunction with {@link
 919      * #staticFieldBase}.
 920      * <p>Do not expect to perform any sort of arithmetic on this offset;
 921      * it is just a cookie which is passed to the unsafe heap memory accessors.
 922      *
 923      * <p>Any given field will always have the same offset, and no two distinct
 924      * fields of the same class will ever have the same offset.
 925      *
 926      * <p>As of 1.4.1, offsets for fields are represented as long values,
 927      * although the Sun JVM does not use the most significant 32 bits.
 928      * It is hard to imagine a JVM technology which needs more than
 929      * a few bits to encode an offset within a non-array object,
 930      * However, for consistency with other methods in this class,
 931      * this method reports its result as a long value.
 932      *
 933      * @deprecated The guarantee that a field will always have the same offset
 934      * and base may not be true in a future release. The ability to provide an
 935      * offset and object reference to a heap memory accessor will be removed
 936      * in a future release. Use {@link VarHandle} instead.
 937      *
 938      * @see #getInt(Object, long)
 939      */
 940     @Deprecated(since="18", forRemoval=true)
 941     @ForceInline
 942     @SuppressWarnings("preview")
 943     public long staticFieldOffset(Field f) {
 944         if (f == null) {
 945             throw new NullPointerException();
 946         }
 947         Class<?> declaringClass = f.getDeclaringClass();
 948         if (declaringClass.isHidden()) {
 949             throw new UnsupportedOperationException("can't get field offset on a hidden class: " + f);
 950         }
 951         if (declaringClass.isRecord()) {
 952             throw new UnsupportedOperationException("can't get field offset on a record class: " + f);
 953         }
 954         if (declaringClass.isValue()) {
 955             throw new UnsupportedOperationException("can't get field offset on a value class: " + f);
 956         }
 957         beforeMemoryAccess();
 958         return theInternalUnsafe.staticFieldOffset(f);
 959     }
 960 
 961     /**
 962      * Reports the location of a given static field, in conjunction with {@link
 963      * #staticFieldOffset}.
 964      * <p>Fetch the base "Object", if any, with which static fields of the
 965      * given class can be accessed via methods like {@link #getInt(Object,
 966      * long)}.  This value may be null.  This value may refer to an object
 967      * which is a "cookie", not guaranteed to be a real Object, and it should
 968      * not be used in any way except as argument to the get and put routines in
 969      * this class.
 970      *
 971      * @deprecated The guarantee that a field will always have the same offset
 972      * and base may not be true in a future release. The ability to provide an
 973      * offset and object reference to a heap memory accessor will be removed
 974      * in a future release. Use {@link VarHandle} instead.
 975      */
 976     @Deprecated(since="18", forRemoval=true)
 977     @ForceInline
 978     @SuppressWarnings("preview")
 979     public Object staticFieldBase(Field f) {
 980         if (f == null) {
 981             throw new NullPointerException();
 982         }
 983         Class<?> declaringClass = f.getDeclaringClass();
 984         if (declaringClass.isHidden()) {
 985             throw new UnsupportedOperationException("can't get base address on a hidden class: " + f);
 986         }
 987         if (declaringClass.isRecord()) {
 988             throw new UnsupportedOperationException("can't get base address on a record class: " + f);
 989         }
 990         if (declaringClass.isValue()) {
 991             throw new UnsupportedOperationException("can't get field offset on a value class: " + f);
 992         }
 993         beforeMemoryAccess();
 994         return theInternalUnsafe.staticFieldBase(f);
 995     }
 996 
 997     /**
 998      * Reports the offset of the first element in the storage allocation of a
 999      * given array class.  If {@link #arrayIndexScale} returns a non-zero value
1000      * for the same class, you may use that scale factor, together with this
1001      * base offset, to form new offsets to access elements of arrays of the
1002      * given class.
1003      *
1004      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1005      *
1006      * @see #getInt(Object, long)
1007      * @see #putInt(Object, long, int)
1008      */
1009     @Deprecated(since="23", forRemoval=true)
1010     @ForceInline
1011     public int arrayBaseOffset(Class<?> arrayClass) {
1012         beforeMemoryAccess();
1013         return theInternalUnsafe.arrayBaseOffset(arrayClass);
1014     }
1015 
1016     /** The value of {@code arrayBaseOffset(boolean[].class)}.
1017      *
1018      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1019      */
1020     @Deprecated(since="23", forRemoval=true)
1021     public static final int ARRAY_BOOLEAN_BASE_OFFSET = jdk.internal.misc.Unsafe.ARRAY_BOOLEAN_BASE_OFFSET;
1022 
1023     /** The value of {@code arrayBaseOffset(byte[].class)}.
1024      *
1025      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1026      */
1027     @Deprecated(since="23", forRemoval=true)
1028     public static final int ARRAY_BYTE_BASE_OFFSET = jdk.internal.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET;
1029 
1030     /** The value of {@code arrayBaseOffset(short[].class)}.
1031      *
1032      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1033      */
1034     @Deprecated(since="23", forRemoval=true)
1035     public static final int ARRAY_SHORT_BASE_OFFSET = jdk.internal.misc.Unsafe.ARRAY_SHORT_BASE_OFFSET;
1036 
1037     /** The value of {@code arrayBaseOffset(char[].class)}.
1038      *
1039      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1040      */
1041     @Deprecated(since="23", forRemoval=true)
1042     public static final int ARRAY_CHAR_BASE_OFFSET = jdk.internal.misc.Unsafe.ARRAY_CHAR_BASE_OFFSET;
1043 
1044     /** The value of {@code arrayBaseOffset(int[].class)}.
1045      *
1046      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1047      */
1048     @Deprecated(since="23", forRemoval=true)
1049     public static final int ARRAY_INT_BASE_OFFSET = jdk.internal.misc.Unsafe.ARRAY_INT_BASE_OFFSET;
1050 
1051     /** The value of {@code arrayBaseOffset(long[].class)}.
1052      *
1053      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1054      */
1055     @Deprecated(since="23", forRemoval=true)
1056     public static final int ARRAY_LONG_BASE_OFFSET = jdk.internal.misc.Unsafe.ARRAY_LONG_BASE_OFFSET;
1057 
1058     /** The value of {@code arrayBaseOffset(float[].class)}.
1059      *
1060      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1061      */
1062     @Deprecated(since="23", forRemoval=true)
1063     public static final int ARRAY_FLOAT_BASE_OFFSET = jdk.internal.misc.Unsafe.ARRAY_FLOAT_BASE_OFFSET;
1064 
1065     /** The value of {@code arrayBaseOffset(double[].class)}.
1066      *
1067      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1068      */
1069     @Deprecated(since="23", forRemoval=true)
1070     public static final int ARRAY_DOUBLE_BASE_OFFSET = jdk.internal.misc.Unsafe.ARRAY_DOUBLE_BASE_OFFSET;
1071 
1072     /** The value of {@code arrayBaseOffset(Object[].class)}.
1073      *
1074      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1075      */
1076     @Deprecated(since="23", forRemoval=true)
1077     public static final int ARRAY_OBJECT_BASE_OFFSET = jdk.internal.misc.Unsafe.ARRAY_OBJECT_BASE_OFFSET;
1078 
1079     /**
1080      * Reports the scale factor for addressing elements in the storage
1081      * allocation of a given array class.  However, arrays of "narrow" types
1082      * will generally not work properly with accessors like {@link
1083      * #getByte(Object, long)}, so the scale factor for such classes is reported
1084      * as zero.
1085      *
1086      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1087      *
1088      * @see #arrayBaseOffset
1089      * @see #getInt(Object, long)
1090      * @see #putInt(Object, long, int)
1091      */
1092     @Deprecated(since="23", forRemoval=true)
1093     @ForceInline
1094     public int arrayIndexScale(Class<?> arrayClass) {
1095         return theInternalUnsafe.arrayIndexScale(arrayClass);
1096     }
1097 
1098     /** The value of {@code arrayIndexScale(boolean[].class)}.
1099      *
1100      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1101      */
1102     @Deprecated(since="23", forRemoval=true)
1103     public static final int ARRAY_BOOLEAN_INDEX_SCALE = jdk.internal.misc.Unsafe.ARRAY_BOOLEAN_INDEX_SCALE;
1104 
1105     /** The value of {@code arrayIndexScale(byte[].class)}.
1106      *
1107      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1108      */
1109     @Deprecated(since="23", forRemoval=true)
1110     public static final int ARRAY_BYTE_INDEX_SCALE = jdk.internal.misc.Unsafe.ARRAY_BYTE_INDEX_SCALE;
1111 
1112     /** The value of {@code arrayIndexScale(short[].class)}.
1113      *
1114      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1115      */
1116     @Deprecated(since="23", forRemoval=true)
1117     public static final int ARRAY_SHORT_INDEX_SCALE = jdk.internal.misc.Unsafe.ARRAY_SHORT_INDEX_SCALE;
1118 
1119     /** The value of {@code arrayIndexScale(char[].class)}.
1120      *
1121      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1122      */
1123     @Deprecated(since="23", forRemoval=true)
1124     public static final int ARRAY_CHAR_INDEX_SCALE = jdk.internal.misc.Unsafe.ARRAY_CHAR_INDEX_SCALE;
1125 
1126     /** The value of {@code arrayIndexScale(int[].class)}.
1127      *
1128      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1129      */
1130     @Deprecated(since="23", forRemoval=true)
1131     public static final int ARRAY_INT_INDEX_SCALE = jdk.internal.misc.Unsafe.ARRAY_INT_INDEX_SCALE;
1132 
1133     /** The value of {@code arrayIndexScale(long[].class)}.
1134      *
1135      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1136      */
1137     @Deprecated(since="23", forRemoval=true)
1138     public static final int ARRAY_LONG_INDEX_SCALE = jdk.internal.misc.Unsafe.ARRAY_LONG_INDEX_SCALE;
1139 
1140     /** The value of {@code arrayIndexScale(float[].class)}.
1141      *
1142      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1143      */
1144     @Deprecated(since="23", forRemoval=true)
1145     public static final int ARRAY_FLOAT_INDEX_SCALE = jdk.internal.misc.Unsafe.ARRAY_FLOAT_INDEX_SCALE;
1146 
1147     /** The value of {@code arrayIndexScale(double[].class)}.
1148      *
1149      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1150      */
1151     @Deprecated(since="23", forRemoval=true)
1152     public static final int ARRAY_DOUBLE_INDEX_SCALE = jdk.internal.misc.Unsafe.ARRAY_DOUBLE_INDEX_SCALE;
1153 
1154     /** The value of {@code arrayIndexScale(Object[].class)}.
1155      *
1156      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1157      */
1158     @Deprecated(since="23", forRemoval=true)
1159     public static final int ARRAY_OBJECT_INDEX_SCALE = jdk.internal.misc.Unsafe.ARRAY_OBJECT_INDEX_SCALE;
1160 
1161     /**
1162      * Reports the size in bytes of a native pointer, as stored via {@link
1163      * #putAddress}.  This value will be either 4 or 8.  Note that the sizes of
1164      * other primitive types (as stored in native memory blocks) is determined
1165      * fully by their information content.
1166      *
1167      * @deprecated Use {@link ValueLayout#ADDRESS}.{@link MemoryLayout#byteSize()} instead.
1168      */
1169     @Deprecated(since="23", forRemoval=true)
1170     @ForceInline
1171     public int addressSize() {
1172         return theInternalUnsafe.addressSize();
1173     }
1174 
1175     /** The value of {@code addressSize()}.
1176      *
1177      * @deprecated Use {@link ValueLayout#ADDRESS}.{@link MemoryLayout#byteSize()} instead.
1178      */
1179     @Deprecated(since="23", forRemoval=true)
1180     public static final int ADDRESS_SIZE = theInternalUnsafe.addressSize();
1181 
1182     /**
1183      * Reports the size in bytes of a native memory page (whatever that is).
1184      * This value will always be a power of two.
1185      */
1186     @ForceInline
1187     public int pageSize() {
1188         return theInternalUnsafe.pageSize();
1189     }
1190 
1191 
1192     //| random trusted operations from JNI:
1193 
1194     /**
1195      * Allocates an instance but does not run any constructor.
1196      * Initializes the class if it has not yet been.
1197      */
1198     @ForceInline
1199     public Object allocateInstance(Class<?> cls)
1200         throws InstantiationException {
1201         return theInternalUnsafe.allocateInstance(cls);
1202     }
1203 
1204     /** Throws the exception without telling the verifier. */
1205     @ForceInline
1206     public void throwException(Throwable ee) {
1207         theInternalUnsafe.throwException(ee);
1208     }
1209 
1210     /**
1211      * Atomically updates Java variable to {@code x} if it is currently
1212      * holding {@code expected}.
1213      *
1214      * <p>This operation has memory semantics of a {@code volatile} read
1215      * and write.  Corresponds to C11 atomic_compare_exchange_strong.
1216      *
1217      * @return {@code true} if successful
1218      *
1219      * @deprecated Use {@link VarHandle#compareAndExchange(Object...)} instead.
1220      */
1221     @Deprecated(since="23", forRemoval=true)
1222     @ForceInline
1223     public final boolean compareAndSwapObject(Object o, long offset,
1224                                               Object expected,
1225                                               Object x) {
1226         beforeMemoryAccess();
1227         return theInternalUnsafe.compareAndSetReference(o, offset, expected, x);
1228     }
1229 
1230     /**
1231      * Atomically updates Java variable to {@code x} if it is currently
1232      * holding {@code expected}.
1233      *
1234      * <p>This operation has memory semantics of a {@code volatile} read
1235      * and write.  Corresponds to C11 atomic_compare_exchange_strong.
1236      *
1237      * @return {@code true} if successful
1238      *
1239      * @deprecated Use {@link VarHandle#compareAndExchange(Object...)} instead.
1240      */
1241     @Deprecated(since="23", forRemoval=true)
1242     @ForceInline
1243     public final boolean compareAndSwapInt(Object o, long offset,
1244                                            int expected,
1245                                            int x) {
1246         beforeMemoryAccess();
1247         return theInternalUnsafe.compareAndSetInt(o, offset, expected, x);
1248     }
1249 
1250     /**
1251      * Atomically updates Java variable to {@code x} if it is currently
1252      * holding {@code expected}.
1253      *
1254      * <p>This operation has memory semantics of a {@code volatile} read
1255      * and write.  Corresponds to C11 atomic_compare_exchange_strong.
1256      *
1257      * @return {@code true} if successful
1258      *
1259      * @deprecated Use {@link VarHandle#compareAndExchange(Object...)} instead.
1260      */
1261     @Deprecated(since="23", forRemoval=true)
1262     @ForceInline
1263     public final boolean compareAndSwapLong(Object o, long offset,
1264                                             long expected,
1265                                             long x) {
1266         beforeMemoryAccess();
1267         return theInternalUnsafe.compareAndSetLong(o, offset, expected, x);
1268     }
1269 
1270     /**
1271      * Fetches a reference value from a given Java variable, with volatile
1272      * load semantics. Otherwise identical to {@link #getObject(Object, long)}
1273      *
1274      * @deprecated Use {@link VarHandle#getVolatile(Object...)} instead.
1275      */
1276     @Deprecated(since="23", forRemoval=true)
1277     @ForceInline
1278     public Object getObjectVolatile(Object o, long offset) {
1279         beforeMemoryAccess();
1280         return theInternalUnsafe.getReferenceVolatile(o, offset);
1281     }
1282 
1283     /**
1284      * Stores a reference value into a given Java variable, with
1285      * volatile store semantics. Otherwise identical to {@link #putObject(Object, long, Object)}
1286      *
1287      * @deprecated Use {@link VarHandle#setVolatile(Object...)} instead.
1288      */
1289     @Deprecated(since="23", forRemoval=true)
1290     @ForceInline
1291     public void putObjectVolatile(Object o, long offset, Object x) {
1292         beforeMemoryAccess();
1293         theInternalUnsafe.putReferenceVolatile(o, offset, x);
1294     }
1295 
1296     /** Volatile version of {@link #getInt(Object, long)}.
1297      *
1298      * @deprecated Use {@link VarHandle#getVolatile(Object...)} instead.
1299      */
1300     @Deprecated(since="23", forRemoval=true)
1301     @ForceInline
1302     public int getIntVolatile(Object o, long offset) {
1303         beforeMemoryAccess();
1304         return theInternalUnsafe.getIntVolatile(o, offset);
1305     }
1306 
1307     /** Volatile version of {@link #putInt(Object, long, int)}.
1308      *
1309      * @deprecated Use {@link VarHandle#setVolatile(Object...)} instead.
1310      */
1311     @Deprecated(since="23", forRemoval=true)
1312     @ForceInline
1313     public void putIntVolatile(Object o, long offset, int x) {
1314         beforeMemoryAccess();
1315         theInternalUnsafe.putIntVolatile(o, offset, x);
1316     }
1317 
1318     /** Volatile version of {@link #getBoolean(Object, long)}.
1319      *
1320      * @deprecated Use {@link VarHandle#getVolatile(Object...)} instead.
1321      */
1322     @Deprecated(since="23", forRemoval=true)
1323     @ForceInline
1324     public boolean getBooleanVolatile(Object o, long offset) {
1325         beforeMemoryAccess();
1326         return theInternalUnsafe.getBooleanVolatile(o, offset);
1327     }
1328 
1329     /** Volatile version of {@link #putBoolean(Object, long, boolean)}.
1330      *
1331      * @deprecated Use {@link VarHandle#setVolatile(Object...)} instead.
1332      */
1333     @Deprecated(since="23", forRemoval=true)
1334     @ForceInline
1335     public void putBooleanVolatile(Object o, long offset, boolean x) {
1336         beforeMemoryAccess();
1337         theInternalUnsafe.putBooleanVolatile(o, offset, x);
1338     }
1339 
1340     /** Volatile version of {@link #getByte(Object, long)}.
1341      *
1342      * @deprecated Use {@link VarHandle#getVolatile(Object...)}
1343      * instead.
1344      */
1345     @Deprecated(since="23", forRemoval=true)
1346     @ForceInline
1347     public byte getByteVolatile(Object o, long offset) {
1348         beforeMemoryAccess();
1349         return theInternalUnsafe.getByteVolatile(o, offset);
1350     }
1351 
1352     /** Volatile version of {@link #putByte(Object, long, byte)}.
1353      *
1354      * @deprecated Use {@link VarHandle#setVolatile(Object...)} instead.
1355      */
1356     @Deprecated(since="23", forRemoval=true)
1357     @ForceInline
1358     public void putByteVolatile(Object o, long offset, byte x) {
1359         beforeMemoryAccess();
1360         theInternalUnsafe.putByteVolatile(o, offset, x);
1361     }
1362 
1363     /** Volatile version of {@link #getShort(Object, long)}.
1364      *
1365      * @deprecated Use {@link VarHandle#getVolatile(Object...)} instead.
1366      */
1367     @Deprecated(since="23", forRemoval=true)
1368     @ForceInline
1369     public short getShortVolatile(Object o, long offset) {
1370         beforeMemoryAccess();
1371         return theInternalUnsafe.getShortVolatile(o, offset);
1372     }
1373 
1374     /** Volatile version of {@link #putShort(Object, long, short)}.
1375      *
1376      * @deprecated Use {@link VarHandle#setVolatile(Object...)} instead.
1377      */
1378     @Deprecated(since="23", forRemoval=true)
1379     @ForceInline
1380     public void putShortVolatile(Object o, long offset, short x) {
1381         beforeMemoryAccess();
1382         theInternalUnsafe.putShortVolatile(o, offset, x);
1383     }
1384 
1385     /** Volatile version of {@link #getChar(Object, long)}.
1386      *
1387      * @deprecated Use {@link VarHandle#getVolatile(Object...)} instead.
1388      */
1389     @Deprecated(since="23", forRemoval=true)
1390     @ForceInline
1391     public char getCharVolatile(Object o, long offset) {
1392         beforeMemoryAccess();
1393         return theInternalUnsafe.getCharVolatile(o, offset);
1394     }
1395 
1396     /** Volatile version of {@link #putChar(Object, long, char)}.
1397      *
1398      * @deprecated Use {@link VarHandle#setVolatile(Object...)} instead.
1399      */
1400     @Deprecated(since="23", forRemoval=true)
1401     @ForceInline
1402     public void putCharVolatile(Object o, long offset, char x) {
1403         beforeMemoryAccess();
1404         theInternalUnsafe.putCharVolatile(o, offset, x);
1405     }
1406 
1407     /** Volatile version of {@link #getLong(Object, long)}.
1408      *
1409      * @deprecated Use {@link VarHandle#getVolatile(Object...)} instead.
1410      */
1411     @Deprecated(since="23", forRemoval=true)
1412     @ForceInline
1413     public long getLongVolatile(Object o, long offset) {
1414         beforeMemoryAccess();
1415         return theInternalUnsafe.getLongVolatile(o, offset);
1416     }
1417 
1418     /** Volatile version of {@link #putLong(Object, long, long)}.
1419      *
1420      * @deprecated Use {@link VarHandle#setVolatile(Object...)} instead.
1421      */
1422     @Deprecated(since="23", forRemoval=true)
1423     @ForceInline
1424     public void putLongVolatile(Object o, long offset, long x) {
1425         beforeMemoryAccess();
1426         theInternalUnsafe.putLongVolatile(o, offset, x);
1427     }
1428 
1429     /** Volatile version of {@link #getFloat(Object, long)}.
1430      *
1431      * @deprecated Use {@link VarHandle#getVolatile(Object...)} instead.
1432      */
1433     @Deprecated(since="23", forRemoval=true)
1434     @ForceInline
1435     public float getFloatVolatile(Object o, long offset) {
1436         beforeMemoryAccess();
1437         return theInternalUnsafe.getFloatVolatile(o, offset);
1438     }
1439 
1440     /** Volatile version of {@link #putFloat(Object, long, float)}.
1441      *
1442      * @deprecated Use {@link VarHandle#setVolatile(Object...)} instead.
1443      */
1444     @Deprecated(since="23", forRemoval=true)
1445     @ForceInline
1446     public void putFloatVolatile(Object o, long offset, float x) {
1447         beforeMemoryAccess();
1448         theInternalUnsafe.putFloatVolatile(o, offset, x);
1449     }
1450 
1451     /** Volatile version of {@link #getDouble(Object, long)}.
1452      *
1453      * @deprecated Use {@link VarHandle#getVolatile(Object...)} instead.
1454      */
1455     @Deprecated(since="23", forRemoval=true)
1456     @ForceInline
1457     public double getDoubleVolatile(Object o, long offset) {
1458         beforeMemoryAccess();
1459         return theInternalUnsafe.getDoubleVolatile(o, offset);
1460     }
1461 
1462     /** Volatile version of {@link #putDouble(Object, long, double)}.
1463      *
1464      * @deprecated Use {@link VarHandle#setVolatile(Object...)} instead.
1465      */
1466     @Deprecated(since="23", forRemoval=true)
1467     @ForceInline
1468     public void putDoubleVolatile(Object o, long offset, double x) {
1469         beforeMemoryAccess();
1470         theInternalUnsafe.putDoubleVolatile(o, offset, x);
1471     }
1472 
1473     /**
1474      * Version of {@link #putObjectVolatile(Object, long, Object)}
1475      * that does not guarantee immediate visibility of the store to
1476      * other threads. This method is generally only useful if the
1477      * underlying field is a Java volatile (or if an array cell, one
1478      * that is otherwise only accessed using volatile accesses).
1479      *
1480      * Corresponds to C11 atomic_store_explicit(..., memory_order_release).
1481      *
1482      * @deprecated Use {@link VarHandle#setRelease(Object...)} instead.
1483      */
1484     @Deprecated(since="23", forRemoval=true)
1485     @ForceInline
1486     public void putOrderedObject(Object o, long offset, Object x) {
1487         beforeMemoryAccess();
1488         theInternalUnsafe.putReferenceRelease(o, offset, x);
1489     }
1490 
1491     /** Ordered/Lazy version of {@link #putIntVolatile(Object, long, int)}.
1492      *
1493      * @deprecated Use {@link VarHandle#setRelease(Object...)} instead.
1494      */
1495     @Deprecated(since="23", forRemoval=true)
1496     @ForceInline
1497     public void putOrderedInt(Object o, long offset, int x) {
1498         beforeMemoryAccess();
1499         theInternalUnsafe.putIntRelease(o, offset, x);
1500     }
1501 
1502     /** Ordered/Lazy version of {@link #putLongVolatile(Object, long, long)}.
1503      *
1504      * @deprecated Use {@link VarHandle#setRelease(Object...)} instead.
1505      */
1506     @Deprecated(since="23", forRemoval=true)
1507     @ForceInline
1508     public void putOrderedLong(Object o, long offset, long x) {
1509         beforeMemoryAccess();
1510         theInternalUnsafe.putLongRelease(o, offset, x);
1511     }
1512 
1513     /**
1514      * Unblocks the given thread blocked on {@code park}, or, if it is
1515      * not blocked, causes the subsequent call to {@code park} not to
1516      * block.  Note: this operation is "unsafe" solely because the
1517      * caller must somehow ensure that the thread has not been
1518      * destroyed. Nothing special is usually required to ensure this
1519      * when called from Java (in which there will ordinarily be a live
1520      * reference to the thread) but this is not nearly-automatically
1521      * so when calling from native code.
1522      *
1523      * @param thread the thread to unpark.
1524      *
1525      * @deprecated Use {@link java.util.concurrent.locks.LockSupport#unpark(Thread)} instead.
1526      */
1527     @Deprecated(since="22", forRemoval=true)
1528     @ForceInline
1529     public void unpark(Object thread) {
1530         theInternalUnsafe.unpark(thread);
1531     }
1532 
1533     /**
1534      * Blocks current thread, returning when a balancing
1535      * {@code unpark} occurs, or a balancing {@code unpark} has
1536      * already occurred, or the thread is interrupted, or, if not
1537      * absolute and time is not zero, the given time nanoseconds have
1538      * elapsed, or if absolute, the given deadline in milliseconds
1539      * since Epoch has passed, or spuriously (i.e., returning for no
1540      * "reason"). Note: This operation is in the Unsafe class only
1541      * because {@code unpark} is, so it would be strange to place it
1542      * elsewhere.
1543      *
1544      * @deprecated Use {@link java.util.concurrent.locks.LockSupport#parkNanos(long)} or
1545      * {@link java.util.concurrent.locks.LockSupport#parkUntil(long)} instead.
1546      */
1547     @Deprecated(since="22", forRemoval=true)
1548     @ForceInline
1549     public void park(boolean isAbsolute, long time) {
1550         theInternalUnsafe.park(isAbsolute, time);
1551     }
1552 
1553     /**
1554      * Gets the load average in the system run queue assigned
1555      * to the available processors averaged over various periods of time.
1556      * This method retrieves the given {@code nelem} samples and
1557      * assigns to the elements of the given {@code loadavg} array.
1558      * The system imposes a maximum of 3 samples, representing
1559      * averages over the last 1,  5,  and  15 minutes, respectively.
1560      *
1561      * @param loadavg an array of double of size nelems
1562      * @param nelems the number of samples to be retrieved and
1563      *        must be 1 to 3.
1564      *
1565      * @return the number of samples actually retrieved; or -1
1566      *         if the load average is unobtainable.
1567      *
1568      * @deprecated Use {@link java.management/java.lang.management.OperatingSystemMXBean#getSystemLoadAverage()}
1569      * instead.
1570      */
1571     @SuppressWarnings("doclint:reference") // cross-module links
1572     @Deprecated(since="22", forRemoval=true)
1573     @ForceInline
1574     public int getLoadAverage(double[] loadavg, int nelems) {
1575         return theInternalUnsafe.getLoadAverage(loadavg, nelems);
1576     }
1577 
1578     // The following contain CAS-based Java implementations used on
1579     // platforms not supporting native instructions
1580 
1581     /**
1582      * Atomically adds the given value to the current value of a field
1583      * or array element within the given object {@code o}
1584      * at the given {@code offset}.
1585      *
1586      * @param o object/array to update the field/element in
1587      * @param offset field/element offset
1588      * @param delta the value to add
1589      * @return the previous value
1590      * @since 1.8
1591      *
1592      * @deprecated Use {@link VarHandle#getAndAdd(Object...)} instead.
1593      */
1594     @Deprecated(since="23", forRemoval=true)
1595     @ForceInline
1596     public final int getAndAddInt(Object o, long offset, int delta) {
1597         beforeMemoryAccess();
1598         return theInternalUnsafe.getAndAddInt(o, offset, delta);
1599     }
1600 
1601     /**
1602      * Atomically adds the given value to the current value of a field
1603      * or array element within the given object {@code o}
1604      * at the given {@code offset}.
1605      *
1606      * @param o object/array to update the field/element in
1607      * @param offset field/element offset
1608      * @param delta the value to add
1609      * @return the previous value
1610      * @since 1.8
1611      *
1612      * @deprecated Use {@link VarHandle#getAndAdd(Object...)} instead.
1613      */
1614     @Deprecated(since="23", forRemoval=true)
1615     @ForceInline
1616     public final long getAndAddLong(Object o, long offset, long delta) {
1617         beforeMemoryAccess();
1618         return theInternalUnsafe.getAndAddLong(o, offset, delta);
1619     }
1620 
1621     /**
1622      * Atomically exchanges the given value with the current value of
1623      * a field or array element within the given object {@code o}
1624      * at the given {@code offset}.
1625      *
1626      * @param o object/array to update the field/element in
1627      * @param offset field/element offset
1628      * @param newValue new value
1629      * @return the previous value
1630      * @since 1.8
1631      *
1632      * @deprecated Use {@link VarHandle#getAndAdd(Object...)} instead.
1633      */
1634     @Deprecated(since="23", forRemoval=true)
1635     @ForceInline
1636     public final int getAndSetInt(Object o, long offset, int newValue) {
1637         beforeMemoryAccess();
1638         return theInternalUnsafe.getAndSetInt(o, offset, newValue);
1639     }
1640 
1641     /**
1642      * Atomically exchanges the given value with the current value of
1643      * a field or array element within the given object {@code o}
1644      * at the given {@code offset}.
1645      *
1646      * @param o object/array to update the field/element in
1647      * @param offset field/element offset
1648      * @param newValue new value
1649      * @return the previous value
1650      * @since 1.8
1651      *
1652      * @deprecated Use {@link VarHandle#getAndAdd(Object...)} instead.
1653      */
1654     @Deprecated(since="23", forRemoval=true)
1655     @ForceInline
1656     public final long getAndSetLong(Object o, long offset, long newValue) {
1657         beforeMemoryAccess();
1658         return theInternalUnsafe.getAndSetLong(o, offset, newValue);
1659     }
1660 
1661     /**
1662      * Atomically exchanges the given reference value with the current
1663      * reference value of a field or array element within the given
1664      * object {@code o} at the given {@code offset}.
1665      *
1666      * @param o object/array to update the field/element in
1667      * @param offset field/element offset
1668      * @param newValue new value
1669      * @return the previous value
1670      * @since 1.8
1671      *
1672      * @deprecated Use {@link VarHandle#getAndAdd(Object...)} instead.
1673      */
1674     @Deprecated(since="23", forRemoval=true)
1675     @ForceInline
1676     public final Object getAndSetObject(Object o, long offset, Object newValue) {
1677         beforeMemoryAccess();
1678         return theInternalUnsafe.getAndSetReference(o, offset, newValue);
1679     }
1680 
1681     /**
1682      * Ensures that loads before the fence will not be reordered with loads and
1683      * stores after the fence; a "LoadLoad plus LoadStore barrier".
1684      *
1685      * Corresponds to C11 atomic_thread_fence(memory_order_acquire)
1686      * (an "acquire fence").
1687      *
1688      * A pure LoadLoad fence is not provided, since the addition of LoadStore
1689      * is almost always desired, and most current hardware instructions that
1690      * provide a LoadLoad barrier also provide a LoadStore barrier for free.
1691      *
1692      * @deprecated Use {@link VarHandle#acquireFence()} instead.
1693      * @since 1.8
1694      */
1695     @Deprecated(since="22", forRemoval=true)
1696     @ForceInline
1697     public void loadFence() {
1698         theInternalUnsafe.loadFence();
1699     }
1700 
1701     /**
1702      * Ensures that loads and stores before the fence will not be reordered with
1703      * stores after the fence; a "StoreStore plus LoadStore barrier".
1704      *
1705      * Corresponds to C11 atomic_thread_fence(memory_order_release)
1706      * (a "release fence").
1707      *
1708      * A pure StoreStore fence is not provided, since the addition of LoadStore
1709      * is almost always desired, and most current hardware instructions that
1710      * provide a StoreStore barrier also provide a LoadStore barrier for free.
1711      *
1712      * @deprecated Use {@link VarHandle#releaseFence()} instead.
1713      * @since 1.8
1714      */
1715     @Deprecated(since="22", forRemoval=true)
1716     @ForceInline
1717     public void storeFence() {
1718         theInternalUnsafe.storeFence();
1719     }
1720 
1721     /**
1722      * Ensures that loads and stores before the fence will not be reordered
1723      * with loads and stores after the fence.  Implies the effects of both
1724      * loadFence() and storeFence(), and in addition, the effect of a StoreLoad
1725      * barrier.
1726      *
1727      * Corresponds to C11 atomic_thread_fence(memory_order_seq_cst).
1728      *
1729      * @deprecated Use {@link VarHandle#fullFence()} instead.
1730      * @since 1.8
1731      */
1732     @Deprecated(since="22", forRemoval=true)
1733     @ForceInline
1734     public void fullFence() {
1735         theInternalUnsafe.fullFence();
1736     }
1737 
1738     /**
1739      * Invokes the given direct byte buffer's cleaner, if any.
1740      *
1741      * @param directBuffer a direct byte buffer
1742      * @throws NullPointerException if {@code directBuffer} is null
1743      * @throws IllegalArgumentException if {@code directBuffer} is non-direct,
1744      * or is a {@link java.nio.Buffer#slice slice}, or is a
1745      * {@link java.nio.Buffer#duplicate duplicate}
1746      *
1747      * @deprecated Use a {@link MemorySegment} allocated in an {@link Arena} with the
1748      * appropriate temporal bounds. The {@link MemorySegment#asByteBuffer()} method
1749      * wraps a memory segment as a {@code ByteBuffer} to allow interop with existing
1750      * code.
1751      *
1752      * @since 9
1753      */
1754     @Deprecated(since="23", forRemoval=true)
1755     public void invokeCleaner(java.nio.ByteBuffer directBuffer) {
1756         if (!directBuffer.isDirect())
1757             throw new IllegalArgumentException("Not a direct buffer");
1758         beforeMemoryAccess();
1759         theInternalUnsafe.invokeCleaner(directBuffer);
1760     }
1761 
1762     // Infrastructure for --sun-misc-unsafe-memory-access=<value> command line option.
1763 
1764     private static final Object MEMORY_ACCESS_WARNED_BASE;
1765     private static final long MEMORY_ACCESS_WARNED_OFFSET;
1766     static {
1767         try {
1768             Field field = Unsafe.class.getDeclaredField("memoryAccessWarned");
1769             MEMORY_ACCESS_WARNED_BASE = theInternalUnsafe.staticFieldBase(field);
1770             MEMORY_ACCESS_WARNED_OFFSET = theInternalUnsafe.staticFieldOffset(field);
1771         } catch (Exception e) {
1772             throw new ExceptionInInitializerError(e);
1773         }
1774     }
1775     // set to true by first usage of memory-access method
1776     private static @Stable boolean memoryAccessWarned;
1777 
1778     private static boolean isMemoryAccessWarned() {
1779         return theInternalUnsafe.getBooleanVolatile(MEMORY_ACCESS_WARNED_BASE, MEMORY_ACCESS_WARNED_OFFSET);
1780     }
1781 
1782     private static boolean trySetMemoryAccessWarned() {
1783         return theInternalUnsafe.compareAndSetBoolean(MEMORY_ACCESS_WARNED_BASE, MEMORY_ACCESS_WARNED_OFFSET, false, true);
1784     }
1785 
1786     private static final MemoryAccessOption MEMORY_ACCESS_OPTION = MemoryAccessOption.value();
1787 
1788     /**
1789      * Invoked by all memory-access methods.
1790      */
1791     @ForceInline
1792     private static void beforeMemoryAccess() {
1793         if (MEMORY_ACCESS_OPTION == MemoryAccessOption.ALLOW) {
1794             return;
1795         }
1796 
1797         if (MEMORY_ACCESS_OPTION == MemoryAccessOption.WARN && isMemoryAccessWarned()) {
1798             // nothing to do if this is not the first usage
1799             return;
1800         }
1801 
1802         // warn && first usage, debug, or deny
1803         beforeMemoryAccessSlow();
1804     }
1805 
1806     private static void beforeMemoryAccessSlow() {
1807         assert MEMORY_ACCESS_OPTION != MemoryAccessOption.ALLOW;
1808 
1809         // stack trace without the frames for the beforeMemoryAccess methods
1810         List<StackWalker.StackFrame> stack = StackWalkerHolder.INSTANCE.walk(s ->
1811                 s.dropWhile(f -> (f.getDeclaringClass() == Unsafe.class)
1812                                 && f.getMethodName().startsWith("beforeMemoryAccess"))
1813                     .limit(32)
1814                     .toList()
1815         );
1816 
1817         // callerClass -> Unsafe.methodName
1818         String methodName = stack.get(0).getMethodName();
1819         Class<?> callerClass = stack.get(1).getDeclaringClass();
1820 
1821         switch (MEMORY_ACCESS_OPTION) {
1822             case WARN -> {
1823                 if (trySetMemoryAccessWarned()) {
1824                     log(multiLineWarning(callerClass, methodName));
1825                 }
1826             }
1827             case DEBUG -> {
1828                 String warning = singleLineWarning(callerClass, methodName);
1829                 StringBuilder sb = new StringBuilder(warning);
1830                 stack.stream()
1831                         .skip(1)
1832                         .forEach(f ->
1833                                 sb.append(System.lineSeparator()).append("\tat " + f)
1834                         );
1835                 log(sb.toString());
1836             }
1837             case DENY -> {
1838                 throw new UnsupportedOperationException(methodName);
1839             }
1840         }
1841     }
1842 
1843     /**
1844      * Represents the options for the depreacted method-access methods.
1845      */
1846     private enum MemoryAccessOption {
1847         /**
1848          * Allow use of the memory-access methods with no warnings.
1849          */
1850         ALLOW,
1851         /**
1852          * Warning on the first use of a memory-access method.
1853          */
1854         WARN,
1855         /**
1856          * One-line warning and a stack trace on every use of a memory-access method.
1857          */
1858         DEBUG,
1859         /**
1860          * Deny use of the memory-access methods.
1861          */
1862         DENY;
1863 
1864         private static MemoryAccessOption defaultValue() {
1865             return ALLOW;
1866         }
1867 
1868         /**
1869          * Return the value.
1870          */
1871         static MemoryAccessOption value() {
1872             String value = VM.getSavedProperty("sun.misc.unsafe.memory.access");
1873             if (value != null) {
1874                 return switch (value) {
1875                     case "allow" -> MemoryAccessOption.ALLOW;
1876                     case "warn"  -> MemoryAccessOption.WARN;
1877                     case "debug" -> MemoryAccessOption.DEBUG;
1878                     case "deny"  -> MemoryAccessOption.DENY;
1879                     default -> {
1880                         // should not happen
1881                         log("sun.misc.unsafe.memory.access ignored, value '" + value +
1882                                 "' is not a recognized value");
1883                         yield defaultValue();
1884                     }
1885                 };
1886             } else {
1887                 return defaultValue();
1888             }
1889         }
1890     }
1891 
1892     /**
1893      * Holder for StackWalker that retains class references.
1894      */
1895     private static class StackWalkerHolder {
1896         static final StackWalker INSTANCE;
1897         static {
1898             PrivilegedAction<StackWalker> pa = () ->
1899                     StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
1900             @SuppressWarnings("removal")
1901             StackWalker walker = AccessController.doPrivileged(pa);
1902             INSTANCE = walker;
1903         }
1904     }
1905 
1906     /**
1907      * Return the multi-line warning message for when the given class invokes the
1908      * given the Unsafe method.
1909      */
1910     private static String multiLineWarning(Class<?> callerClass, String methodName) {
1911         return String.format(
1912                 """
1913                 WARNING: A terminally deprecated method in sun.misc.Unsafe has been called
1914                 WARNING: sun.misc.Unsafe::%s has been called by %s
1915                 WARNING: Please consider reporting this to the maintainers of %s
1916                 WARNING: sun.misc.Unsafe::%s will be removed in a future release""",
1917                 methodName, callerAndLocation(callerClass), callerClass, methodName);
1918     }
1919 
1920     /**
1921      * Return the single-line warning message for when the given class invokes the
1922      * given the Unsafe method.
1923      */
1924     private static String singleLineWarning(Class<?> callerClass, String methodName) {
1925         return String.format("WARNING: sun.misc.Unsafe::%s called by %s",
1926                 methodName, callerAndLocation(callerClass));
1927     }
1928 
1929     /**
1930      * Returns a string with the caller class and the location URL from the CodeSource.
1931      */
1932     private static String callerAndLocation(Class<?> callerClass) {
1933         PrivilegedAction<ProtectionDomain> pa = callerClass::getProtectionDomain;
1934         @SuppressWarnings("removal")
1935         CodeSource cs = AccessController.doPrivileged(pa).getCodeSource();
1936         String who = callerClass.getName();
1937         if (cs != null && cs.getLocation() != null) {
1938             who += " (" + cs.getLocation() + ")";
1939         }
1940         return who;
1941     }
1942 
1943     /**
1944      * Prints the given message to the standard error.
1945      */
1946     private static void log(String message) {
1947         VM.initialErr().println(message);
1948     }
1949 }