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