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