• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &gt; 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