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