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