1 /* 2 * Copyright (c) 2000, 2013, 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 dalvik.annotation.optimization.FastNative; 29 import sun.reflect.Reflection; 30 31 import java.lang.reflect.Field; 32 import java.lang.reflect.Modifier; 33 34 /** 35 * A collection of methods for performing low-level, unsafe operations. 36 * Although the class and all methods are public, use of this class is 37 * limited because only trusted code can obtain instances of it. 38 * 39 * @author John R. Rose 40 * @see #getUnsafe 41 */ 42 public final class Unsafe { 43 /** Traditional dalvik name. */ 44 private static final Unsafe THE_ONE = new Unsafe(); 45 46 private static final Unsafe theUnsafe = THE_ONE; 47 public static final int INVALID_FIELD_OFFSET = -1; 48 49 /** 50 * This class is only privately instantiable. 51 */ Unsafe()52 private Unsafe() {} 53 54 /** 55 * Gets the unique instance of this class. This is only allowed in 56 * very limited situations. 57 */ getUnsafe()58 public static Unsafe getUnsafe() { 59 Class<?> caller = Reflection.getCallerClass(); 60 /* 61 * Only code on the bootclasspath is allowed to get at the 62 * Unsafe instance. 63 */ 64 ClassLoader calling = (caller == null) ? null : caller.getClassLoader(); 65 if ((calling != null) && (calling != Unsafe.class.getClassLoader())) { 66 throw new SecurityException("Unsafe access denied"); 67 } 68 69 return THE_ONE; 70 } 71 72 /** 73 * Gets the raw byte offset from the start of an object's memory to 74 * the memory used to store the indicated instance field. 75 * 76 * @param field non-null; the field in question, which must be an 77 * instance field 78 * @return the offset to the field 79 */ objectFieldOffset(Field field)80 public long objectFieldOffset(Field field) { 81 if (Modifier.isStatic(field.getModifiers())) { 82 throw new IllegalArgumentException("valid for instance fields only"); 83 } 84 return field.getOffset(); 85 } 86 87 /** 88 * Gets the offset from the start of an array object's memory to 89 * the memory used to store its initial (zeroeth) element. 90 * 91 * @param clazz non-null; class in question; must be an array class 92 * @return the offset to the initial element 93 */ arrayBaseOffset(Class clazz)94 public int arrayBaseOffset(Class clazz) { 95 Class<?> component = clazz.getComponentType(); 96 if (component == null) { 97 throw new IllegalArgumentException("Valid for array classes only: " + clazz); 98 } 99 return getArrayBaseOffsetForComponentType(component); 100 } 101 102 /** 103 * Gets the size of each element of the given array class. 104 * 105 * @param clazz non-null; class in question; must be an array class 106 * @return > 0; the size of each element of the array 107 */ arrayIndexScale(Class clazz)108 public int arrayIndexScale(Class clazz) { 109 Class<?> component = clazz.getComponentType(); 110 if (component == null) { 111 throw new IllegalArgumentException("Valid for array classes only: " + clazz); 112 } 113 return getArrayIndexScaleForComponentType(component); 114 } 115 116 @FastNative getArrayBaseOffsetForComponentType(Class component_class)117 private static native int getArrayBaseOffsetForComponentType(Class component_class); 118 @FastNative getArrayIndexScaleForComponentType(Class component_class)119 private static native int getArrayIndexScaleForComponentType(Class component_class); 120 121 /** 122 * Performs a compare-and-set operation on an <code>int</code> 123 * field within the given object. 124 * 125 * @param obj non-null; object containing the field 126 * @param offset offset to the field within <code>obj</code> 127 * @param expectedValue expected value of the field 128 * @param newValue new value to store in the field if the contents are 129 * as expected 130 * @return <code>true</code> if the new value was in fact stored, and 131 * <code>false</code> if not 132 */ 133 @FastNative compareAndSwapInt(Object obj, long offset, int expectedValue, int newValue)134 public native boolean compareAndSwapInt(Object obj, long offset, 135 int expectedValue, int newValue); 136 137 /** 138 * Performs a compare-and-set operation on a <code>long</code> 139 * field within the given object. 140 * 141 * @param obj non-null; object containing the field 142 * @param offset offset to the field within <code>obj</code> 143 * @param expectedValue expected value of the field 144 * @param newValue new value to store in the field if the contents are 145 * as expected 146 * @return <code>true</code> if the new value was in fact stored, and 147 * <code>false</code> if not 148 */ 149 @FastNative compareAndSwapLong(Object obj, long offset, long expectedValue, long newValue)150 public native boolean compareAndSwapLong(Object obj, long offset, 151 long expectedValue, long newValue); 152 153 /** 154 * Performs a compare-and-set operation on an <code>Object</code> 155 * field (that is, a reference field) within the given object. 156 * 157 * @param obj non-null; object containing the field 158 * @param offset offset to the field within <code>obj</code> 159 * @param expectedValue expected value of the field 160 * @param newValue new value to store in the field if the contents are 161 * as expected 162 * @return <code>true</code> if the new value was in fact stored, and 163 * <code>false</code> if not 164 */ 165 @FastNative compareAndSwapObject(Object obj, long offset, Object expectedValue, Object newValue)166 public native boolean compareAndSwapObject(Object obj, long offset, 167 Object expectedValue, Object newValue); 168 169 /** 170 * Gets an <code>int</code> field from the given object, 171 * using <code>volatile</code> semantics. 172 * 173 * @param obj non-null; object containing the field 174 * @param offset offset to the field within <code>obj</code> 175 * @return the retrieved value 176 */ 177 @FastNative getIntVolatile(Object obj, long offset)178 public native int getIntVolatile(Object obj, long offset); 179 180 /** 181 * Stores an <code>int</code> field into the given object, 182 * using <code>volatile</code> semantics. 183 * 184 * @param obj non-null; object containing the field 185 * @param offset offset to the field within <code>obj</code> 186 * @param newValue the value to store 187 */ 188 @FastNative putIntVolatile(Object obj, long offset, int newValue)189 public native void putIntVolatile(Object obj, long offset, int newValue); 190 191 /** 192 * Gets a <code>long</code> field from the given object, 193 * using <code>volatile</code> semantics. 194 * 195 * @param obj non-null; object containing the field 196 * @param offset offset to the field within <code>obj</code> 197 * @return the retrieved value 198 */ 199 @FastNative getLongVolatile(Object obj, long offset)200 public native long getLongVolatile(Object obj, long offset); 201 202 /** 203 * Stores a <code>long</code> field into the given object, 204 * using <code>volatile</code> semantics. 205 * 206 * @param obj non-null; object containing the field 207 * @param offset offset to the field within <code>obj</code> 208 * @param newValue the value to store 209 */ 210 @FastNative putLongVolatile(Object obj, long offset, long newValue)211 public native void putLongVolatile(Object obj, long offset, long newValue); 212 213 /** 214 * Gets an <code>Object</code> field from the given object, 215 * using <code>volatile</code> semantics. 216 * 217 * @param obj non-null; object containing the field 218 * @param offset offset to the field within <code>obj</code> 219 * @return the retrieved value 220 */ 221 @FastNative getObjectVolatile(Object obj, long offset)222 public native Object getObjectVolatile(Object obj, long offset); 223 224 /** 225 * Stores an <code>Object</code> field into the given object, 226 * using <code>volatile</code> semantics. 227 * 228 * @param obj non-null; object containing the field 229 * @param offset offset to the field within <code>obj</code> 230 * @param newValue the value to store 231 */ 232 @FastNative putObjectVolatile(Object obj, long offset, Object newValue)233 public native void putObjectVolatile(Object obj, long offset, 234 Object newValue); 235 236 /** 237 * Gets an <code>int</code> field from the given object. 238 * 239 * @param obj non-null; object containing the field 240 * @param offset offset to the field within <code>obj</code> 241 * @return the retrieved value 242 */ 243 @FastNative getInt(Object obj, long offset)244 public native int getInt(Object obj, long offset); 245 246 /** 247 * Stores an <code>int</code> field into the given object. 248 * 249 * @param obj non-null; object containing the field 250 * @param offset offset to the field within <code>obj</code> 251 * @param newValue the value to store 252 */ 253 @FastNative putInt(Object obj, long offset, int newValue)254 public native void putInt(Object obj, long offset, int newValue); 255 256 /** 257 * Lazy set an int field. 258 */ 259 @FastNative putOrderedInt(Object obj, long offset, int newValue)260 public native void putOrderedInt(Object obj, long offset, int newValue); 261 262 /** 263 * Gets a <code>long</code> field from the given object. 264 * 265 * @param obj non-null; object containing the field 266 * @param offset offset to the field within <code>obj</code> 267 * @return the retrieved value 268 */ 269 @FastNative getLong(Object obj, long offset)270 public native long getLong(Object obj, long offset); 271 272 /** 273 * Stores a <code>long</code> field into the given object. 274 * 275 * @param obj non-null; object containing the field 276 * @param offset offset to the field within <code>obj</code> 277 * @param newValue the value to store 278 */ 279 @FastNative putLong(Object obj, long offset, long newValue)280 public native void putLong(Object obj, long offset, long newValue); 281 282 /** 283 * Lazy set a long field. 284 */ 285 @FastNative putOrderedLong(Object obj, long offset, long newValue)286 public native void putOrderedLong(Object obj, long offset, long newValue); 287 288 /** 289 * Gets an <code>Object</code> field from the given object. 290 * 291 * @param obj non-null; object containing the field 292 * @param offset offset to the field within <code>obj</code> 293 * @return the retrieved value 294 */ 295 @FastNative getObject(Object obj, long offset)296 public native Object getObject(Object obj, long offset); 297 298 /** 299 * Stores an <code>Object</code> field into the given object. 300 * 301 * @param obj non-null; object containing the field 302 * @param offset offset to the field within <code>obj</code> 303 * @param newValue the value to store 304 */ 305 @FastNative putObject(Object obj, long offset, Object newValue)306 public native void putObject(Object obj, long offset, Object newValue); 307 308 /** 309 * Lazy set an object field. 310 */ 311 @FastNative putOrderedObject(Object obj, long offset, Object newValue)312 public native void putOrderedObject(Object obj, long offset, 313 Object newValue); 314 315 316 @FastNative getBoolean(Object obj, long offset)317 public native boolean getBoolean(Object obj, long offset); 318 @FastNative putBoolean(Object obj, long offset, boolean newValue)319 public native void putBoolean(Object obj, long offset, boolean newValue); 320 @FastNative getByte(Object obj, long offset)321 public native byte getByte(Object obj, long offset); 322 @FastNative putByte(Object obj, long offset, byte newValue)323 public native void putByte(Object obj, long offset, byte newValue); 324 @FastNative getChar(Object obj, long offset)325 public native char getChar(Object obj, long offset); 326 @FastNative putChar(Object obj, long offset, char newValue)327 public native void putChar(Object obj, long offset, char newValue); 328 @FastNative getShort(Object obj, long offset)329 public native short getShort(Object obj, long offset); 330 @FastNative putShort(Object obj, long offset, short newValue)331 public native void putShort(Object obj, long offset, short newValue); 332 @FastNative getFloat(Object obj, long offset)333 public native float getFloat(Object obj, long offset); 334 @FastNative putFloat(Object obj, long offset, float newValue)335 public native void putFloat(Object obj, long offset, float newValue); 336 @FastNative getDouble(Object obj, long offset)337 public native double getDouble(Object obj, long offset); 338 @FastNative putDouble(Object obj, long offset, double newValue)339 public native void putDouble(Object obj, long offset, double newValue); 340 341 /** 342 * Parks the calling thread for the specified amount of time, 343 * unless the "permit" for the thread is already available (due to 344 * a previous call to {@link #unpark}. This method may also return 345 * spuriously (that is, without the thread being told to unpark 346 * and without the indicated amount of time elapsing). 347 * 348 * <p>See {@link java.util.concurrent.locks.LockSupport} for more 349 * in-depth information of the behavior of this method.</p> 350 * 351 * @param absolute whether the given time value is absolute 352 * milliseconds-since-the-epoch (<code>true</code>) or relative 353 * nanoseconds-from-now (<code>false</code>) 354 * @param time the (absolute millis or relative nanos) time value 355 */ park(boolean absolute, long time)356 public native void park(boolean absolute, long time); 357 /** 358 * Unparks the given object, which must be a {@link Thread}. 359 * 360 * <p>See {@link java.util.concurrent.locks.LockSupport} for more 361 * in-depth information of the behavior of this method.</p> 362 * 363 * @param obj non-null; the object to unpark 364 */ 365 @FastNative unpark(Object obj)366 public native void unpark(Object obj); 367 /** 368 * Allocates an instance of the given class without running the constructor. 369 * The class' <clinit> will be run, if necessary. 370 */ allocateInstance(Class<?> c)371 public native Object allocateInstance(Class<?> c); 372 373 @FastNative addressSize()374 public native int addressSize(); 375 376 @FastNative pageSize()377 public native int pageSize(); 378 379 @FastNative allocateMemory(long bytes)380 public native long allocateMemory(long bytes); 381 382 @FastNative freeMemory(long address)383 public native void freeMemory(long address); 384 385 @FastNative setMemory(long address, long bytes, byte value)386 public native void setMemory(long address, long bytes, byte value); 387 388 @FastNative getByte(long address)389 public native byte getByte(long address); 390 391 @FastNative putByte(long address, byte x)392 public native void putByte(long address, byte x); 393 394 @FastNative getShort(long address)395 public native short getShort(long address); 396 397 @FastNative putShort(long address, short x)398 public native void putShort(long address, short x); 399 400 @FastNative getChar(long address)401 public native char getChar(long address); 402 403 @FastNative putChar(long address, char x)404 public native void putChar(long address, char x); 405 406 @FastNative getInt(long address)407 public native int getInt(long address); 408 409 @FastNative putInt(long address, int x)410 public native void putInt(long address, int x); 411 412 @FastNative getLong(long address)413 public native long getLong(long address); 414 415 @FastNative putLong(long address, long x)416 public native void putLong(long address, long x); 417 418 @FastNative getFloat(long address)419 public native float getFloat(long address); 420 421 @FastNative putFloat(long address, float x)422 public native void putFloat(long address, float x); 423 424 @FastNative getDouble(long address)425 public native double getDouble(long address); 426 427 @FastNative putDouble(long address, double x)428 public native void putDouble(long address, double x); 429 430 @FastNative copyMemoryToPrimitiveArray(long srcAddr, Object dst, long dstOffset, long bytes)431 public native void copyMemoryToPrimitiveArray(long srcAddr, 432 Object dst, long dstOffset, long bytes); 433 434 @FastNative copyMemoryFromPrimitiveArray(Object src, long srcOffset, long dstAddr, long bytes)435 public native void copyMemoryFromPrimitiveArray(Object src, long srcOffset, 436 long dstAddr, long bytes); 437 438 @FastNative copyMemory(long srcAddr, long dstAddr, long bytes)439 public native void copyMemory(long srcAddr, long dstAddr, long bytes); 440 441 442 // The following contain CAS-based Java implementations used on 443 // platforms not supporting native instructions 444 445 /** 446 * Atomically adds the given value to the current value of a field 447 * or array element within the given object {@code o} 448 * at the given {@code offset}. 449 * 450 * @param o object/array to update the field/element in 451 * @param offset field/element offset 452 * @param delta the value to add 453 * @return the previous value 454 * @since 1.8 455 */ 456 // @HotSpotIntrinsicCandidate getAndAddInt(Object o, long offset, int delta)457 public final int getAndAddInt(Object o, long offset, int delta) { 458 int v; 459 do { 460 v = getIntVolatile(o, offset); 461 } while (!compareAndSwapInt(o, offset, v, v + delta)); 462 return v; 463 } 464 465 /** 466 * Atomically adds the given value to the current value of a field 467 * or array element within the given object {@code o} 468 * at the given {@code offset}. 469 * 470 * @param o object/array to update the field/element in 471 * @param offset field/element offset 472 * @param delta the value to add 473 * @return the previous value 474 * @since 1.8 475 */ 476 // @HotSpotIntrinsicCandidate getAndAddLong(Object o, long offset, long delta)477 public final long getAndAddLong(Object o, long offset, long delta) { 478 long v; 479 do { 480 v = getLongVolatile(o, offset); 481 } while (!compareAndSwapLong(o, offset, v, v + delta)); 482 return v; 483 } 484 485 /** 486 * Atomically exchanges the given value with the current value of 487 * a field or array element within the given object {@code o} 488 * at the given {@code offset}. 489 * 490 * @param o object/array to update the field/element in 491 * @param offset field/element offset 492 * @param newValue new value 493 * @return the previous value 494 * @since 1.8 495 */ 496 // @HotSpotIntrinsicCandidate getAndSetInt(Object o, long offset, int newValue)497 public final int getAndSetInt(Object o, long offset, int newValue) { 498 int v; 499 do { 500 v = getIntVolatile(o, offset); 501 } while (!compareAndSwapInt(o, offset, v, newValue)); 502 return v; 503 } 504 505 /** 506 * Atomically exchanges the given value with the current value of 507 * a field or array element within the given object {@code o} 508 * at the given {@code offset}. 509 * 510 * @param o object/array to update the field/element in 511 * @param offset field/element offset 512 * @param newValue new value 513 * @return the previous value 514 * @since 1.8 515 */ 516 // @HotSpotIntrinsicCandidate getAndSetLong(Object o, long offset, long newValue)517 public final long getAndSetLong(Object o, long offset, long newValue) { 518 long v; 519 do { 520 v = getLongVolatile(o, offset); 521 } while (!compareAndSwapLong(o, offset, v, newValue)); 522 return v; 523 } 524 525 /** 526 * Atomically exchanges the given reference value with the current 527 * reference value of a field or array element within the given 528 * object {@code o} at the given {@code offset}. 529 * 530 * @param o object/array to update the field/element in 531 * @param offset field/element offset 532 * @param newValue new value 533 * @return the previous value 534 * @since 1.8 535 */ 536 // @HotSpotIntrinsicCandidate getAndSetObject(Object o, long offset, Object newValue)537 public final Object getAndSetObject(Object o, long offset, Object newValue) { 538 Object v; 539 do { 540 v = getObjectVolatile(o, offset); 541 } while (!compareAndSwapObject(o, offset, v, newValue)); 542 return v; 543 } 544 545 546 /** 547 * Ensures that loads before the fence will not be reordered with loads and 548 * stores after the fence; a "LoadLoad plus LoadStore barrier". 549 * 550 * Corresponds to C11 atomic_thread_fence(memory_order_acquire) 551 * (an "acquire fence"). 552 * 553 * A pure LoadLoad fence is not provided, since the addition of LoadStore 554 * is almost always desired, and most current hardware instructions that 555 * provide a LoadLoad barrier also provide a LoadStore barrier for free. 556 * @since 1.8 557 */ 558 // @HotSpotIntrinsicCandidate 559 @FastNative loadFence()560 public native void loadFence(); 561 562 /** 563 * Ensures that loads and stores before the fence will not be reordered with 564 * stores after the fence; a "StoreStore plus LoadStore barrier". 565 * 566 * Corresponds to C11 atomic_thread_fence(memory_order_release) 567 * (a "release fence"). 568 * 569 * A pure StoreStore fence is not provided, since the addition of LoadStore 570 * is almost always desired, and most current hardware instructions that 571 * provide a StoreStore barrier also provide a LoadStore barrier for free. 572 * @since 1.8 573 */ 574 // @HotSpotIntrinsicCandidate 575 @FastNative storeFence()576 public native void storeFence(); 577 578 /** 579 * Ensures that loads and stores before the fence will not be reordered 580 * with loads and stores after the fence. Implies the effects of both 581 * loadFence() and storeFence(), and in addition, the effect of a StoreLoad 582 * barrier. 583 * 584 * Corresponds to C11 atomic_thread_fence(memory_order_seq_cst). 585 * @since 1.8 586 */ 587 // @HotSpotIntrinsicCandidate 588 @FastNative fullFence()589 public native void fullFence(); 590 } 591