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     public long objectFieldOffset(Field f) {
 899         if (f == null) {
 900             throw new NullPointerException();
 901         }
 902         Class<?> declaringClass = f.getDeclaringClass();
 903         if (declaringClass.isHidden()) {
 904             throw new UnsupportedOperationException("can't get field offset on a hidden class: " + f);
 905         }
 906         if (declaringClass.isRecord()) {
 907             throw new UnsupportedOperationException("can't get field offset on a record class: " + f);
 908         }
 909         beforeMemoryAccess();
 910         return theInternalUnsafe.objectFieldOffset(f);
 911     }
 912 
 913     /**
 914      * Reports the location of a given static field, in conjunction with {@link
 915      * #staticFieldBase}.
 916      * <p>Do not expect to perform any sort of arithmetic on this offset;
 917      * it is just a cookie which is passed to the unsafe heap memory accessors.
 918      *
 919      * <p>Any given field will always have the same offset, and no two distinct
 920      * fields of the same class will ever have the same offset.
 921      *
 922      * <p>As of 1.4.1, offsets for fields are represented as long values,
 923      * although the Sun JVM does not use the most significant 32 bits.
 924      * It is hard to imagine a JVM technology which needs more than
 925      * a few bits to encode an offset within a non-array object,
 926      * However, for consistency with other methods in this class,
 927      * this method reports its result as a long value.
 928      *
 929      * @deprecated The guarantee that a field will always have the same offset
 930      * and base may not be true in a future release. The ability to provide an
 931      * offset and object reference to a heap memory accessor will be removed
 932      * in a future release. Use {@link VarHandle} instead.
 933      *
 934      * @see #getInt(Object, long)
 935      */
 936     @Deprecated(since="18", forRemoval=true)
 937     @ForceInline
 938     public long staticFieldOffset(Field f) {
 939         if (f == null) {
 940             throw new NullPointerException();
 941         }
 942         Class<?> declaringClass = f.getDeclaringClass();
 943         if (declaringClass.isHidden()) {
 944             throw new UnsupportedOperationException("can't get field offset on a hidden class: " + f);
 945         }
 946         if (declaringClass.isRecord()) {
 947             throw new UnsupportedOperationException("can't get field offset on a record class: " + f);
 948         }
 949         beforeMemoryAccess();
 950         return theInternalUnsafe.staticFieldOffset(f);
 951     }
 952 
 953     /**
 954      * Reports the location of a given static field, in conjunction with {@link
 955      * #staticFieldOffset}.
 956      * <p>Fetch the base "Object", if any, with which static fields of the
 957      * given class can be accessed via methods like {@link #getInt(Object,
 958      * long)}.  This value may be null.  This value may refer to an object
 959      * which is a "cookie", not guaranteed to be a real Object, and it should
 960      * not be used in any way except as argument to the get and put routines in
 961      * this class.
 962      *
 963      * @deprecated The guarantee that a field will always have the same offset
 964      * and base may not be true in a future release. The ability to provide an
 965      * offset and object reference to a heap memory accessor will be removed
 966      * in a future release. Use {@link VarHandle} instead.
 967      */
 968     @Deprecated(since="18", forRemoval=true)
 969     @ForceInline
 970     public Object staticFieldBase(Field f) {
 971         if (f == null) {
 972             throw new NullPointerException();
 973         }
 974         Class<?> declaringClass = f.getDeclaringClass();
 975         if (declaringClass.isHidden()) {
 976             throw new UnsupportedOperationException("can't get base address on a hidden class: " + f);
 977         }
 978         if (declaringClass.isRecord()) {
 979             throw new UnsupportedOperationException("can't get base address on a record class: " + f);
 980         }
 981         beforeMemoryAccess();
 982         return theInternalUnsafe.staticFieldBase(f);
 983     }
 984 
 985     /**
 986      * Reports the offset of the first element in the storage allocation of a
 987      * given array class.  If {@link #arrayIndexScale} returns a non-zero value
 988      * for the same class, you may use that scale factor, together with this
 989      * base offset, to form new offsets to access elements of arrays of the
 990      * given class.
 991      *
 992      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
 993      *
 994      * @see #getInt(Object, long)
 995      * @see #putInt(Object, long, int)
 996      */
 997     @Deprecated(since="23", forRemoval=true)
 998     @ForceInline
 999     public int arrayBaseOffset(Class<?> arrayClass) {
1000         beforeMemoryAccess();
1001         return theInternalUnsafe.arrayBaseOffset(arrayClass);
1002     }
1003 
1004     /** The value of {@code arrayBaseOffset(boolean[].class)}.
1005      *
1006      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1007      */
1008     @Deprecated(since="23", forRemoval=true)
1009     public static final int ARRAY_BOOLEAN_BASE_OFFSET = jdk.internal.misc.Unsafe.ARRAY_BOOLEAN_BASE_OFFSET;
1010 
1011     /** The value of {@code arrayBaseOffset(byte[].class)}.
1012      *
1013      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1014      */
1015     @Deprecated(since="23", forRemoval=true)
1016     public static final int ARRAY_BYTE_BASE_OFFSET = jdk.internal.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET;
1017 
1018     /** The value of {@code arrayBaseOffset(short[].class)}.
1019      *
1020      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1021      */
1022     @Deprecated(since="23", forRemoval=true)
1023     public static final int ARRAY_SHORT_BASE_OFFSET = jdk.internal.misc.Unsafe.ARRAY_SHORT_BASE_OFFSET;
1024 
1025     /** The value of {@code arrayBaseOffset(char[].class)}.
1026      *
1027      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1028      */
1029     @Deprecated(since="23", forRemoval=true)
1030     public static final int ARRAY_CHAR_BASE_OFFSET = jdk.internal.misc.Unsafe.ARRAY_CHAR_BASE_OFFSET;
1031 
1032     /** The value of {@code arrayBaseOffset(int[].class)}.
1033      *
1034      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1035      */
1036     @Deprecated(since="23", forRemoval=true)
1037     public static final int ARRAY_INT_BASE_OFFSET = jdk.internal.misc.Unsafe.ARRAY_INT_BASE_OFFSET;
1038 
1039     /** The value of {@code arrayBaseOffset(long[].class)}.
1040      *
1041      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1042      */
1043     @Deprecated(since="23", forRemoval=true)
1044     public static final int ARRAY_LONG_BASE_OFFSET = jdk.internal.misc.Unsafe.ARRAY_LONG_BASE_OFFSET;
1045 
1046     /** The value of {@code arrayBaseOffset(float[].class)}.
1047      *
1048      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1049      */
1050     @Deprecated(since="23", forRemoval=true)
1051     public static final int ARRAY_FLOAT_BASE_OFFSET = jdk.internal.misc.Unsafe.ARRAY_FLOAT_BASE_OFFSET;
1052 
1053     /** The value of {@code arrayBaseOffset(double[].class)}.
1054      *
1055      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1056      */
1057     @Deprecated(since="23", forRemoval=true)
1058     public static final int ARRAY_DOUBLE_BASE_OFFSET = jdk.internal.misc.Unsafe.ARRAY_DOUBLE_BASE_OFFSET;
1059 
1060     /** The value of {@code arrayBaseOffset(Object[].class)}.
1061      *
1062      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1063      */
1064     @Deprecated(since="23", forRemoval=true)
1065     public static final int ARRAY_OBJECT_BASE_OFFSET = jdk.internal.misc.Unsafe.ARRAY_OBJECT_BASE_OFFSET;
1066 
1067     /**
1068      * Reports the scale factor for addressing elements in the storage
1069      * allocation of a given array class.  However, arrays of "narrow" types
1070      * will generally not work properly with accessors like {@link
1071      * #getByte(Object, long)}, so the scale factor for such classes is reported
1072      * as zero.
1073      *
1074      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1075      *
1076      * @see #arrayBaseOffset
1077      * @see #getInt(Object, long)
1078      * @see #putInt(Object, long, int)
1079      */
1080     @Deprecated(since="23", forRemoval=true)
1081     @ForceInline
1082     public int arrayIndexScale(Class<?> arrayClass) {
1083         return theInternalUnsafe.arrayIndexScale(arrayClass);
1084     }
1085 
1086     /** The value of {@code arrayIndexScale(boolean[].class)}.
1087      *
1088      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1089      */
1090     @Deprecated(since="23", forRemoval=true)
1091     public static final int ARRAY_BOOLEAN_INDEX_SCALE = jdk.internal.misc.Unsafe.ARRAY_BOOLEAN_INDEX_SCALE;
1092 
1093     /** The value of {@code arrayIndexScale(byte[].class)}.
1094      *
1095      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1096      */
1097     @Deprecated(since="23", forRemoval=true)
1098     public static final int ARRAY_BYTE_INDEX_SCALE = jdk.internal.misc.Unsafe.ARRAY_BYTE_INDEX_SCALE;
1099 
1100     /** The value of {@code arrayIndexScale(short[].class)}.
1101      *
1102      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1103      */
1104     @Deprecated(since="23", forRemoval=true)
1105     public static final int ARRAY_SHORT_INDEX_SCALE = jdk.internal.misc.Unsafe.ARRAY_SHORT_INDEX_SCALE;
1106 
1107     /** The value of {@code arrayIndexScale(char[].class)}.
1108      *
1109      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1110      */
1111     @Deprecated(since="23", forRemoval=true)
1112     public static final int ARRAY_CHAR_INDEX_SCALE = jdk.internal.misc.Unsafe.ARRAY_CHAR_INDEX_SCALE;
1113 
1114     /** The value of {@code arrayIndexScale(int[].class)}.
1115      *
1116      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1117      */
1118     @Deprecated(since="23", forRemoval=true)
1119     public static final int ARRAY_INT_INDEX_SCALE = jdk.internal.misc.Unsafe.ARRAY_INT_INDEX_SCALE;
1120 
1121     /** The value of {@code arrayIndexScale(long[].class)}.
1122      *
1123      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1124      */
1125     @Deprecated(since="23", forRemoval=true)
1126     public static final int ARRAY_LONG_INDEX_SCALE = jdk.internal.misc.Unsafe.ARRAY_LONG_INDEX_SCALE;
1127 
1128     /** The value of {@code arrayIndexScale(float[].class)}.
1129      *
1130      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1131      */
1132     @Deprecated(since="23", forRemoval=true)
1133     public static final int ARRAY_FLOAT_INDEX_SCALE = jdk.internal.misc.Unsafe.ARRAY_FLOAT_INDEX_SCALE;
1134 
1135     /** The value of {@code arrayIndexScale(double[].class)}.
1136      *
1137      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1138      */
1139     @Deprecated(since="23", forRemoval=true)
1140     public static final int ARRAY_DOUBLE_INDEX_SCALE = jdk.internal.misc.Unsafe.ARRAY_DOUBLE_INDEX_SCALE;
1141 
1142     /** The value of {@code arrayIndexScale(Object[].class)}.
1143      *
1144      * @deprecated Not needed when using {@link VarHandle} or {@link java.lang.foreign}.
1145      */
1146     @Deprecated(since="23", forRemoval=true)
1147     public static final int ARRAY_OBJECT_INDEX_SCALE = jdk.internal.misc.Unsafe.ARRAY_OBJECT_INDEX_SCALE;
1148 
1149     /**
1150      * Reports the size in bytes of a native pointer, as stored via {@link
1151      * #putAddress}.  This value will be either 4 or 8.  Note that the sizes of
1152      * other primitive types (as stored in native memory blocks) is determined
1153      * fully by their information content.
1154      *
1155      * @deprecated Use {@link ValueLayout#ADDRESS}.{@link MemoryLayout#byteSize()} instead.
1156      */
1157     @Deprecated(since="23", forRemoval=true)
1158     @ForceInline
1159     public int addressSize() {
1160         return theInternalUnsafe.addressSize();
1161     }
1162 
1163     /** The value of {@code addressSize()}.
1164      *
1165      * @deprecated Use {@link ValueLayout#ADDRESS}.{@link MemoryLayout#byteSize()} instead.
1166      */
1167     @Deprecated(since="23", forRemoval=true)
1168     public static final int ADDRESS_SIZE = theInternalUnsafe.addressSize();
1169 
1170     /**
1171      * Reports the size in bytes of a native memory page (whatever that is).
1172      * This value will always be a power of two.
1173      */
1174     @ForceInline
1175     public int pageSize() {
1176         return theInternalUnsafe.pageSize();
1177     }
1178 
1179 
1180     //| random trusted operations from JNI:
1181 
1182     /**
1183      * Allocates an instance but does not run any constructor.
1184      * Initializes the class if it has not yet been.
1185      */
1186     @ForceInline
1187     public Object allocateInstance(Class<?> cls)
1188         throws InstantiationException {
1189         return theInternalUnsafe.allocateInstance(cls);
1190     }
1191 
1192     /** Throws the exception without telling the verifier. */
1193     @ForceInline
1194     public void throwException(Throwable ee) {
1195         theInternalUnsafe.throwException(ee);
1196     }
1197 
1198     /**
1199      * Atomically updates Java variable to {@code x} if it is currently
1200      * holding {@code expected}.
1201      *
1202      * <p>This operation has memory semantics of a {@code volatile} read
1203      * and write.  Corresponds to C11 atomic_compare_exchange_strong.
1204      *
1205      * @return {@code true} if successful
1206      *
1207      * @deprecated Use {@link VarHandle#compareAndExchange(Object...)} instead.
1208      */
1209     @Deprecated(since="23", forRemoval=true)
1210     @ForceInline
1211     public final boolean compareAndSwapObject(Object o, long offset,
1212                                               Object expected,
1213                                               Object x) {
1214         beforeMemoryAccess();
1215         return theInternalUnsafe.compareAndSetReference(o, offset, expected, x);
1216     }
1217 
1218     /**
1219      * Atomically updates Java variable to {@code x} if it is currently
1220      * holding {@code expected}.
1221      *
1222      * <p>This operation has memory semantics of a {@code volatile} read
1223      * and write.  Corresponds to C11 atomic_compare_exchange_strong.
1224      *
1225      * @return {@code true} if successful
1226      *
1227      * @deprecated Use {@link VarHandle#compareAndExchange(Object...)} instead.
1228      */
1229     @Deprecated(since="23", forRemoval=true)
1230     @ForceInline
1231     public final boolean compareAndSwapInt(Object o, long offset,
1232                                            int expected,
1233                                            int x) {
1234         beforeMemoryAccess();
1235         return theInternalUnsafe.compareAndSetInt(o, offset, expected, x);
1236     }
1237 
1238     /**
1239      * Atomically updates Java variable to {@code x} if it is currently
1240      * holding {@code expected}.
1241      *
1242      * <p>This operation has memory semantics of a {@code volatile} read
1243      * and write.  Corresponds to C11 atomic_compare_exchange_strong.
1244      *
1245      * @return {@code true} if successful
1246      *
1247      * @deprecated Use {@link VarHandle#compareAndExchange(Object...)} instead.
1248      */
1249     @Deprecated(since="23", forRemoval=true)
1250     @ForceInline
1251     public final boolean compareAndSwapLong(Object o, long offset,
1252                                             long expected,
1253                                             long x) {
1254         beforeMemoryAccess();
1255         return theInternalUnsafe.compareAndSetLong(o, offset, expected, x);
1256     }
1257 
1258     /**
1259      * Fetches a reference value from a given Java variable, with volatile
1260      * load semantics. Otherwise identical to {@link #getObject(Object, long)}
1261      *
1262      * @deprecated Use {@link VarHandle#getVolatile(Object...)} instead.
1263      */
1264     @Deprecated(since="23", forRemoval=true)
1265     @ForceInline
1266     public Object getObjectVolatile(Object o, long offset) {
1267         beforeMemoryAccess();
1268         return theInternalUnsafe.getReferenceVolatile(o, offset);
1269     }
1270 
1271     /**
1272      * Stores a reference value into a given Java variable, with
1273      * volatile store semantics. Otherwise identical to {@link #putObject(Object, long, Object)}
1274      *
1275      * @deprecated Use {@link VarHandle#setVolatile(Object...)} instead.
1276      */
1277     @Deprecated(since="23", forRemoval=true)
1278     @ForceInline
1279     public void putObjectVolatile(Object o, long offset, Object x) {
1280         beforeMemoryAccess();
1281         theInternalUnsafe.putReferenceVolatile(o, offset, x);
1282     }
1283 
1284     /** Volatile version of {@link #getInt(Object, long)}.
1285      *
1286      * @deprecated Use {@link VarHandle#getVolatile(Object...)} instead.
1287      */
1288     @Deprecated(since="23", forRemoval=true)
1289     @ForceInline
1290     public int getIntVolatile(Object o, long offset) {
1291         beforeMemoryAccess();
1292         return theInternalUnsafe.getIntVolatile(o, offset);
1293     }
1294 
1295     /** Volatile version of {@link #putInt(Object, long, int)}.
1296      *
1297      * @deprecated Use {@link VarHandle#setVolatile(Object...)} instead.
1298      */
1299     @Deprecated(since="23", forRemoval=true)
1300     @ForceInline
1301     public void putIntVolatile(Object o, long offset, int x) {
1302         beforeMemoryAccess();
1303         theInternalUnsafe.putIntVolatile(o, offset, x);
1304     }
1305 
1306     /** Volatile version of {@link #getBoolean(Object, long)}.
1307      *
1308      * @deprecated Use {@link VarHandle#getVolatile(Object...)} instead.
1309      */
1310     @Deprecated(since="23", forRemoval=true)
1311     @ForceInline
1312     public boolean getBooleanVolatile(Object o, long offset) {
1313         beforeMemoryAccess();
1314         return theInternalUnsafe.getBooleanVolatile(o, offset);
1315     }
1316 
1317     /** Volatile version of {@link #putBoolean(Object, long, boolean)}.
1318      *
1319      * @deprecated Use {@link VarHandle#setVolatile(Object...)} instead.
1320      */
1321     @Deprecated(since="23", forRemoval=true)
1322     @ForceInline
1323     public void putBooleanVolatile(Object o, long offset, boolean x) {
1324         beforeMemoryAccess();
1325         theInternalUnsafe.putBooleanVolatile(o, offset, x);
1326     }
1327 
1328     /** Volatile version of {@link #getByte(Object, long)}.
1329      *
1330      * @deprecated Use {@link VarHandle#getVolatile(Object...)}
1331      * instead.
1332      */
1333     @Deprecated(since="23", forRemoval=true)
1334     @ForceInline
1335     public byte getByteVolatile(Object o, long offset) {
1336         beforeMemoryAccess();
1337         return theInternalUnsafe.getByteVolatile(o, offset);
1338     }
1339 
1340     /** Volatile version of {@link #putByte(Object, long, byte)}.
1341      *
1342      * @deprecated Use {@link VarHandle#setVolatile(Object...)} instead.
1343      */
1344     @Deprecated(since="23", forRemoval=true)
1345     @ForceInline
1346     public void putByteVolatile(Object o, long offset, byte x) {
1347         beforeMemoryAccess();
1348         theInternalUnsafe.putByteVolatile(o, offset, x);
1349     }
1350 
1351     /** Volatile version of {@link #getShort(Object, long)}.
1352      *
1353      * @deprecated Use {@link VarHandle#getVolatile(Object...)} instead.
1354      */
1355     @Deprecated(since="23", forRemoval=true)
1356     @ForceInline
1357     public short getShortVolatile(Object o, long offset) {
1358         beforeMemoryAccess();
1359         return theInternalUnsafe.getShortVolatile(o, offset);
1360     }
1361 
1362     /** Volatile version of {@link #putShort(Object, long, short)}.
1363      *
1364      * @deprecated Use {@link VarHandle#setVolatile(Object...)} instead.
1365      */
1366     @Deprecated(since="23", forRemoval=true)
1367     @ForceInline
1368     public void putShortVolatile(Object o, long offset, short x) {
1369         beforeMemoryAccess();
1370         theInternalUnsafe.putShortVolatile(o, offset, x);
1371     }
1372 
1373     /** Volatile version of {@link #getChar(Object, long)}.
1374      *
1375      * @deprecated Use {@link VarHandle#getVolatile(Object...)} instead.
1376      */
1377     @Deprecated(since="23", forRemoval=true)
1378     @ForceInline
1379     public char getCharVolatile(Object o, long offset) {
1380         beforeMemoryAccess();
1381         return theInternalUnsafe.getCharVolatile(o, offset);
1382     }
1383 
1384     /** Volatile version of {@link #putChar(Object, long, char)}.
1385      *
1386      * @deprecated Use {@link VarHandle#setVolatile(Object...)} instead.
1387      */
1388     @Deprecated(since="23", forRemoval=true)
1389     @ForceInline
1390     public void putCharVolatile(Object o, long offset, char x) {
1391         beforeMemoryAccess();
1392         theInternalUnsafe.putCharVolatile(o, offset, x);
1393     }
1394 
1395     /** Volatile version of {@link #getLong(Object, long)}.
1396      *
1397      * @deprecated Use {@link VarHandle#getVolatile(Object...)} instead.
1398      */
1399     @Deprecated(since="23", forRemoval=true)
1400     @ForceInline
1401     public long getLongVolatile(Object o, long offset) {
1402         beforeMemoryAccess();
1403         return theInternalUnsafe.getLongVolatile(o, offset);
1404     }
1405 
1406     /** Volatile version of {@link #putLong(Object, long, long)}.
1407      *
1408      * @deprecated Use {@link VarHandle#setVolatile(Object...)} instead.
1409      */
1410     @Deprecated(since="23", forRemoval=true)
1411     @ForceInline
1412     public void putLongVolatile(Object o, long offset, long x) {
1413         beforeMemoryAccess();
1414         theInternalUnsafe.putLongVolatile(o, offset, x);
1415     }
1416 
1417     /** Volatile version of {@link #getFloat(Object, long)}.
1418      *
1419      * @deprecated Use {@link VarHandle#getVolatile(Object...)} instead.
1420      */
1421     @Deprecated(since="23", forRemoval=true)
1422     @ForceInline
1423     public float getFloatVolatile(Object o, long offset) {
1424         beforeMemoryAccess();
1425         return theInternalUnsafe.getFloatVolatile(o, offset);
1426     }
1427 
1428     /** Volatile version of {@link #putFloat(Object, long, float)}.
1429      *
1430      * @deprecated Use {@link VarHandle#setVolatile(Object...)} instead.
1431      */
1432     @Deprecated(since="23", forRemoval=true)
1433     @ForceInline
1434     public void putFloatVolatile(Object o, long offset, float x) {
1435         beforeMemoryAccess();
1436         theInternalUnsafe.putFloatVolatile(o, offset, x);
1437     }
1438 
1439     /** Volatile version of {@link #getDouble(Object, long)}.
1440      *
1441      * @deprecated Use {@link VarHandle#getVolatile(Object...)} instead.
1442      */
1443     @Deprecated(since="23", forRemoval=true)
1444     @ForceInline
1445     public double getDoubleVolatile(Object o, long offset) {
1446         beforeMemoryAccess();
1447         return theInternalUnsafe.getDoubleVolatile(o, offset);
1448     }
1449 
1450     /** Volatile version of {@link #putDouble(Object, long, double)}.
1451      *
1452      * @deprecated Use {@link VarHandle#setVolatile(Object...)} instead.
1453      */
1454     @Deprecated(since="23", forRemoval=true)
1455     @ForceInline
1456     public void putDoubleVolatile(Object o, long offset, double x) {
1457         beforeMemoryAccess();
1458         theInternalUnsafe.putDoubleVolatile(o, offset, x);
1459     }
1460 
1461     /**
1462      * Version of {@link #putObjectVolatile(Object, long, Object)}
1463      * that does not guarantee immediate visibility of the store to
1464      * other threads. This method is generally only useful if the
1465      * underlying field is a Java volatile (or if an array cell, one
1466      * that is otherwise only accessed using volatile accesses).
1467      *
1468      * Corresponds to C11 atomic_store_explicit(..., memory_order_release).
1469      *
1470      * @deprecated Use {@link VarHandle#setRelease(Object...)} instead.
1471      */
1472     @Deprecated(since="23", forRemoval=true)
1473     @ForceInline
1474     public void putOrderedObject(Object o, long offset, Object x) {
1475         beforeMemoryAccess();
1476         theInternalUnsafe.putReferenceRelease(o, offset, x);
1477     }
1478 
1479     /** Ordered/Lazy version of {@link #putIntVolatile(Object, long, int)}.
1480      *
1481      * @deprecated Use {@link VarHandle#setRelease(Object...)} instead.
1482      */
1483     @Deprecated(since="23", forRemoval=true)
1484     @ForceInline
1485     public void putOrderedInt(Object o, long offset, int x) {
1486         beforeMemoryAccess();
1487         theInternalUnsafe.putIntRelease(o, offset, x);
1488     }
1489 
1490     /** Ordered/Lazy version of {@link #putLongVolatile(Object, long, long)}.
1491      *
1492      * @deprecated Use {@link VarHandle#setRelease(Object...)} instead.
1493      */
1494     @Deprecated(since="23", forRemoval=true)
1495     @ForceInline
1496     public void putOrderedLong(Object o, long offset, long x) {
1497         beforeMemoryAccess();
1498         theInternalUnsafe.putLongRelease(o, offset, x);
1499     }
1500 
1501     /**
1502      * Unblocks the given thread blocked on {@code park}, or, if it is
1503      * not blocked, causes the subsequent call to {@code park} not to
1504      * block.  Note: this operation is "unsafe" solely because the
1505      * caller must somehow ensure that the thread has not been
1506      * destroyed. Nothing special is usually required to ensure this
1507      * when called from Java (in which there will ordinarily be a live
1508      * reference to the thread) but this is not nearly-automatically
1509      * so when calling from native code.
1510      *
1511      * @param thread the thread to unpark.
1512      *
1513      * @deprecated Use {@link java.util.concurrent.locks.LockSupport#unpark(Thread)} instead.
1514      */
1515     @Deprecated(since="22", forRemoval=true)
1516     @ForceInline
1517     public void unpark(Object thread) {
1518         theInternalUnsafe.unpark(thread);
1519     }
1520 
1521     /**
1522      * Blocks current thread, returning when a balancing
1523      * {@code unpark} occurs, or a balancing {@code unpark} has
1524      * already occurred, or the thread is interrupted, or, if not
1525      * absolute and time is not zero, the given time nanoseconds have
1526      * elapsed, or if absolute, the given deadline in milliseconds
1527      * since Epoch has passed, or spuriously (i.e., returning for no
1528      * "reason"). Note: This operation is in the Unsafe class only
1529      * because {@code unpark} is, so it would be strange to place it
1530      * elsewhere.
1531      *
1532      * @deprecated Use {@link java.util.concurrent.locks.LockSupport#parkNanos(long)} or
1533      * {@link java.util.concurrent.locks.LockSupport#parkUntil(long)} instead.
1534      */
1535     @Deprecated(since="22", forRemoval=true)
1536     @ForceInline
1537     public void park(boolean isAbsolute, long time) {
1538         theInternalUnsafe.park(isAbsolute, time);
1539     }
1540 
1541     /**
1542      * Gets the load average in the system run queue assigned
1543      * to the available processors averaged over various periods of time.
1544      * This method retrieves the given {@code nelem} samples and
1545      * assigns to the elements of the given {@code loadavg} array.
1546      * The system imposes a maximum of 3 samples, representing
1547      * averages over the last 1,  5,  and  15 minutes, respectively.
1548      *
1549      * @param loadavg an array of double of size nelems
1550      * @param nelems the number of samples to be retrieved and
1551      *        must be 1 to 3.
1552      *
1553      * @return the number of samples actually retrieved; or -1
1554      *         if the load average is unobtainable.
1555      *
1556      * @deprecated Use {@link java.management/java.lang.management.OperatingSystemMXBean#getSystemLoadAverage()}
1557      * instead.
1558      */
1559     @SuppressWarnings("doclint:reference") // cross-module links
1560     @Deprecated(since="22", forRemoval=true)
1561     @ForceInline
1562     public int getLoadAverage(double[] loadavg, int nelems) {
1563         return theInternalUnsafe.getLoadAverage(loadavg, nelems);
1564     }
1565 
1566     // The following contain CAS-based Java implementations used on
1567     // platforms not supporting native instructions
1568 
1569     /**
1570      * Atomically adds the given value to the current value of a field
1571      * or array element within the given object {@code o}
1572      * at the given {@code offset}.
1573      *
1574      * @param o object/array to update the field/element in
1575      * @param offset field/element offset
1576      * @param delta the value to add
1577      * @return the previous value
1578      * @since 1.8
1579      *
1580      * @deprecated Use {@link VarHandle#getAndAdd(Object...)} instead.
1581      */
1582     @Deprecated(since="23", forRemoval=true)
1583     @ForceInline
1584     public final int getAndAddInt(Object o, long offset, int delta) {
1585         beforeMemoryAccess();
1586         return theInternalUnsafe.getAndAddInt(o, offset, delta);
1587     }
1588 
1589     /**
1590      * Atomically adds the given value to the current value of a field
1591      * or array element within the given object {@code o}
1592      * at the given {@code offset}.
1593      *
1594      * @param o object/array to update the field/element in
1595      * @param offset field/element offset
1596      * @param delta the value to add
1597      * @return the previous value
1598      * @since 1.8
1599      *
1600      * @deprecated Use {@link VarHandle#getAndAdd(Object...)} instead.
1601      */
1602     @Deprecated(since="23", forRemoval=true)
1603     @ForceInline
1604     public final long getAndAddLong(Object o, long offset, long delta) {
1605         beforeMemoryAccess();
1606         return theInternalUnsafe.getAndAddLong(o, offset, delta);
1607     }
1608 
1609     /**
1610      * Atomically exchanges the given value with the current value of
1611      * a field or array element within the given object {@code o}
1612      * at the given {@code offset}.
1613      *
1614      * @param o object/array to update the field/element in
1615      * @param offset field/element offset
1616      * @param newValue new value
1617      * @return the previous value
1618      * @since 1.8
1619      *
1620      * @deprecated Use {@link VarHandle#getAndAdd(Object...)} instead.
1621      */
1622     @Deprecated(since="23", forRemoval=true)
1623     @ForceInline
1624     public final int getAndSetInt(Object o, long offset, int newValue) {
1625         beforeMemoryAccess();
1626         return theInternalUnsafe.getAndSetInt(o, offset, newValue);
1627     }
1628 
1629     /**
1630      * Atomically exchanges the given value with the current value of
1631      * a field or array element within the given object {@code o}
1632      * at the given {@code offset}.
1633      *
1634      * @param o object/array to update the field/element in
1635      * @param offset field/element offset
1636      * @param newValue new value
1637      * @return the previous value
1638      * @since 1.8
1639      *
1640      * @deprecated Use {@link VarHandle#getAndAdd(Object...)} instead.
1641      */
1642     @Deprecated(since="23", forRemoval=true)
1643     @ForceInline
1644     public final long getAndSetLong(Object o, long offset, long newValue) {
1645         beforeMemoryAccess();
1646         return theInternalUnsafe.getAndSetLong(o, offset, newValue);
1647     }
1648 
1649     /**
1650      * Atomically exchanges the given reference value with the current
1651      * reference value of a field or array element within the given
1652      * object {@code o} at the given {@code offset}.
1653      *
1654      * @param o object/array to update the field/element in
1655      * @param offset field/element offset
1656      * @param newValue new value
1657      * @return the previous value
1658      * @since 1.8
1659      *
1660      * @deprecated Use {@link VarHandle#getAndAdd(Object...)} instead.
1661      */
1662     @Deprecated(since="23", forRemoval=true)
1663     @ForceInline
1664     public final Object getAndSetObject(Object o, long offset, Object newValue) {
1665         beforeMemoryAccess();
1666         return theInternalUnsafe.getAndSetReference(o, offset, newValue);
1667     }
1668 
1669     /**
1670      * Ensures that loads before the fence will not be reordered with loads and
1671      * stores after the fence; a "LoadLoad plus LoadStore barrier".
1672      *
1673      * Corresponds to C11 atomic_thread_fence(memory_order_acquire)
1674      * (an "acquire fence").
1675      *
1676      * A pure LoadLoad fence is not provided, since the addition of LoadStore
1677      * is almost always desired, and most current hardware instructions that
1678      * provide a LoadLoad barrier also provide a LoadStore barrier for free.
1679      *
1680      * @deprecated Use {@link VarHandle#acquireFence()} instead.
1681      * @since 1.8
1682      */
1683     @Deprecated(since="22", forRemoval=true)
1684     @ForceInline
1685     public void loadFence() {
1686         theInternalUnsafe.loadFence();
1687     }
1688 
1689     /**
1690      * Ensures that loads and stores before the fence will not be reordered with
1691      * stores after the fence; a "StoreStore plus LoadStore barrier".
1692      *
1693      * Corresponds to C11 atomic_thread_fence(memory_order_release)
1694      * (a "release fence").
1695      *
1696      * A pure StoreStore fence is not provided, since the addition of LoadStore
1697      * is almost always desired, and most current hardware instructions that
1698      * provide a StoreStore barrier also provide a LoadStore barrier for free.
1699      *
1700      * @deprecated Use {@link VarHandle#releaseFence()} instead.
1701      * @since 1.8
1702      */
1703     @Deprecated(since="22", forRemoval=true)
1704     @ForceInline
1705     public void storeFence() {
1706         theInternalUnsafe.storeFence();
1707     }
1708 
1709     /**
1710      * Ensures that loads and stores before the fence will not be reordered
1711      * with loads and stores after the fence.  Implies the effects of both
1712      * loadFence() and storeFence(), and in addition, the effect of a StoreLoad
1713      * barrier.
1714      *
1715      * Corresponds to C11 atomic_thread_fence(memory_order_seq_cst).
1716      *
1717      * @deprecated Use {@link VarHandle#fullFence()} instead.
1718      * @since 1.8
1719      */
1720     @Deprecated(since="22", forRemoval=true)
1721     @ForceInline
1722     public void fullFence() {
1723         theInternalUnsafe.fullFence();
1724     }
1725 
1726     /**
1727      * Invokes the given direct byte buffer's cleaner, if any.
1728      *
1729      * @param directBuffer a direct byte buffer
1730      * @throws NullPointerException if {@code directBuffer} is null
1731      * @throws IllegalArgumentException if {@code directBuffer} is non-direct,
1732      * or is a {@link java.nio.Buffer#slice slice}, or is a
1733      * {@link java.nio.Buffer#duplicate duplicate}
1734      *
1735      * @deprecated Use a {@link MemorySegment} allocated in an {@link Arena} with the
1736      * appropriate temporal bounds. The {@link MemorySegment#asByteBuffer()} method
1737      * wraps a memory segment as a {@code ByteBuffer} to allow interop with existing
1738      * code.
1739      *
1740      * @since 9
1741      */
1742     @Deprecated(since="23", forRemoval=true)
1743     public void invokeCleaner(java.nio.ByteBuffer directBuffer) {
1744         if (!directBuffer.isDirect())
1745             throw new IllegalArgumentException("Not a direct buffer");
1746         beforeMemoryAccess();
1747         theInternalUnsafe.invokeCleaner(directBuffer);
1748     }
1749 
1750     // Infrastructure for --sun-misc-unsafe-memory-access=<value> command line option.
1751 
1752     private static final Object MEMORY_ACCESS_WARNED_BASE;
1753     private static final long MEMORY_ACCESS_WARNED_OFFSET;
1754     static {
1755         try {
1756             Field field = Unsafe.class.getDeclaredField("memoryAccessWarned");
1757             MEMORY_ACCESS_WARNED_BASE = theInternalUnsafe.staticFieldBase(field);
1758             MEMORY_ACCESS_WARNED_OFFSET = theInternalUnsafe.staticFieldOffset(field);
1759         } catch (Exception e) {
1760             throw new ExceptionInInitializerError(e);
1761         }
1762     }
1763     // set to true by first usage of memory-access method
1764     private static @Stable boolean memoryAccessWarned;
1765 
1766     private static boolean isMemoryAccessWarned() {
1767         return theInternalUnsafe.getBooleanVolatile(MEMORY_ACCESS_WARNED_BASE, MEMORY_ACCESS_WARNED_OFFSET);
1768     }
1769 
1770     private static boolean trySetMemoryAccessWarned() {
1771         return theInternalUnsafe.compareAndSetBoolean(MEMORY_ACCESS_WARNED_BASE, MEMORY_ACCESS_WARNED_OFFSET, false, true);
1772     }
1773 
1774     private static final MemoryAccessOption MEMORY_ACCESS_OPTION = MemoryAccessOption.value();
1775 
1776     /**
1777      * Invoked by all memory-access methods.
1778      */
1779     @ForceInline
1780     private static void beforeMemoryAccess() {
1781         if (MEMORY_ACCESS_OPTION == MemoryAccessOption.ALLOW) {
1782             return;
1783         }
1784 
1785         if (MEMORY_ACCESS_OPTION == MemoryAccessOption.WARN && isMemoryAccessWarned()) {
1786             // nothing to do if this is not the first usage
1787             return;
1788         }
1789 
1790         // warn && first usage, debug, or deny
1791         beforeMemoryAccessSlow();
1792     }
1793 
1794     private static void beforeMemoryAccessSlow() {
1795         assert MEMORY_ACCESS_OPTION != MemoryAccessOption.ALLOW;
1796 
1797         // stack trace without the frames for the beforeMemoryAccess methods
1798         List<StackWalker.StackFrame> stack = StackWalkerHolder.INSTANCE.walk(s ->
1799                 s.dropWhile(f -> (f.getDeclaringClass() == Unsafe.class)
1800                                 && f.getMethodName().startsWith("beforeMemoryAccess"))
1801                     .limit(32)
1802                     .toList()
1803         );
1804 
1805         // callerClass -> Unsafe.methodName
1806         String methodName = stack.get(0).getMethodName();
1807         Class<?> callerClass = stack.get(1).getDeclaringClass();
1808 
1809         switch (MEMORY_ACCESS_OPTION) {
1810             case WARN -> {
1811                 if (trySetMemoryAccessWarned()) {
1812                     log(multiLineWarning(callerClass, methodName));
1813                 }
1814             }
1815             case DEBUG -> {
1816                 String warning = singleLineWarning(callerClass, methodName);
1817                 StringBuilder sb = new StringBuilder(warning);
1818                 stack.stream()
1819                         .skip(1)
1820                         .forEach(f ->
1821                                 sb.append(System.lineSeparator()).append("\tat " + f)
1822                         );
1823                 log(sb.toString());
1824             }
1825             case DENY -> {
1826                 throw new UnsupportedOperationException(methodName);
1827             }
1828         }
1829     }
1830 
1831     /**
1832      * Represents the options for the depreacted method-access methods.
1833      */
1834     private enum MemoryAccessOption {
1835         /**
1836          * Allow use of the memory-access methods with no warnings.
1837          */
1838         ALLOW,
1839         /**
1840          * Warning on the first use of a memory-access method.
1841          */
1842         WARN,
1843         /**
1844          * One-line warning and a stack trace on every use of a memory-access method.
1845          */
1846         DEBUG,
1847         /**
1848          * Deny use of the memory-access methods.
1849          */
1850         DENY;
1851 
1852         private static MemoryAccessOption defaultValue() {
1853             return ALLOW;
1854         }
1855 
1856         /**
1857          * Return the value.
1858          */
1859         static MemoryAccessOption value() {
1860             String value = VM.getSavedProperty("sun.misc.unsafe.memory.access");
1861             if (value != null) {
1862                 return switch (value) {
1863                     case "allow" -> MemoryAccessOption.ALLOW;
1864                     case "warn"  -> MemoryAccessOption.WARN;
1865                     case "debug" -> MemoryAccessOption.DEBUG;
1866                     case "deny"  -> MemoryAccessOption.DENY;
1867                     default -> {
1868                         // should not happen
1869                         log("sun.misc.unsafe.memory.access ignored, value '" + value +
1870                                 "' is not a recognized value");
1871                         yield defaultValue();
1872                     }
1873                 };
1874             } else {
1875                 return defaultValue();
1876             }
1877         }
1878     }
1879 
1880     /**
1881      * Holder for StackWalker that retains class references.
1882      */
1883     private static class StackWalkerHolder {
1884         static final StackWalker INSTANCE;
1885         static {
1886             PrivilegedAction<StackWalker> pa = () ->
1887                     StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
1888             @SuppressWarnings("removal")
1889             StackWalker walker = AccessController.doPrivileged(pa);
1890             INSTANCE = walker;
1891         }
1892     }
1893 
1894     /**
1895      * Return the multi-line warning message for when the given class invokes the
1896      * given the Unsafe method.
1897      */
1898     private static String multiLineWarning(Class<?> callerClass, String methodName) {
1899         return String.format(
1900                 """
1901                 WARNING: A terminally deprecated method in sun.misc.Unsafe has been called
1902                 WARNING: sun.misc.Unsafe::%s has been called by %s
1903                 WARNING: Please consider reporting this to the maintainers of %s
1904                 WARNING: sun.misc.Unsafe::%s will be removed in a future release""",
1905                 methodName, callerAndLocation(callerClass), callerClass, methodName);
1906     }
1907 
1908     /**
1909      * Return the single-line warning message for when the given class invokes the
1910      * given the Unsafe method.
1911      */
1912     private static String singleLineWarning(Class<?> callerClass, String methodName) {
1913         return String.format("WARNING: sun.misc.Unsafe::%s called by %s",
1914                 methodName, callerAndLocation(callerClass));
1915     }
1916 
1917     /**
1918      * Returns a string with the caller class and the location URL from the CodeSource.
1919      */
1920     private static String callerAndLocation(Class<?> callerClass) {
1921         PrivilegedAction<ProtectionDomain> pa = callerClass::getProtectionDomain;
1922         @SuppressWarnings("removal")
1923         CodeSource cs = AccessController.doPrivileged(pa).getCodeSource();
1924         String who = callerClass.getName();
1925         if (cs != null && cs.getLocation() != null) {
1926             who += " (" + cs.getLocation() + ")";
1927         }
1928         return who;
1929     }
1930 
1931     /**
1932      * Prints the given message to the standard error.
1933      */
1934     private static void log(String message) {
1935         VM.initialErr().println(message);
1936     }
1937 }