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