Home | History | Annotate | Download | only in misc
      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      */
     50     private Unsafe() {}
     51 
     52     /**
     53      * Gets the unique instance of this class. This is only allowed in
     54      * very limited situations.
     55      */
     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      */
     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      */
     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 &gt; 0; the size of each element of the array
    104      */
    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 
    113     private static native int getArrayBaseOffsetForComponentType(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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    238     public native void putInt(Object obj, long offset, int newValue);
    239 
    240     /**
    241      * Lazy set an int field.
    242      */
    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      */
    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      */
    261     public native void putLong(Object obj, long offset, long newValue);
    262 
    263     /**
    264      * Lazy set a long field.
    265      */
    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      */
    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      */
    284     public native void putObject(Object obj, long offset, Object newValue);
    285 
    286     /**
    287      * Lazy set an object field.
    288      */
    289     public native void putOrderedObject(Object obj, long offset,
    290             Object newValue);
    291 
    292 
    293     public native boolean getBoolean(Object obj, long offset);
    294     public native void putBoolean(Object obj, long offset, boolean newValue);
    295     public native byte getByte(Object obj, long offset);
    296     public native void putByte(Object obj, long offset, byte newValue);
    297     public native char getChar(Object obj, long offset);
    298     public native void putChar(Object obj, long offset, char newValue);
    299     public native short getShort(Object obj, long offset);
    300     public native void putShort(Object obj, long offset, short newValue);
    301     public native float getFloat(Object obj, long offset);
    302     public native void putFloat(Object obj, long offset, float newValue);
    303     public native double getDouble(Object obj, long offset);
    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      */
    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      */
    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      */
    349     public native Object allocateInstance(Class<?> c);
    350 
    351     public native int addressSize();
    352 
    353     public native int pageSize();
    354 
    355     public native long allocateMemory(long bytes);
    356 
    357     public native void freeMemory(long address);
    358 
    359     public native void setMemory(long address, long bytes, byte value);
    360 
    361     public native byte getByte(long address);
    362 
    363     public native void putByte(long address, byte x);
    364 
    365     public native short getShort(long address);
    366 
    367     public native void putShort(long address, short x);
    368 
    369     public native char getChar(long address);
    370 
    371     public native void putChar(long address, char x);
    372 
    373     public native int getInt(long address);
    374 
    375     public native void putInt(long address, int x);
    376 
    377     public native long getLong(long address);
    378 
    379     public native void putLong(long address, long x);
    380 
    381     public native float getFloat(long address);
    382 
    383     public native void putFloat(long address, float x);
    384 
    385     public native double getDouble(long address);
    386 
    387     public native void putDouble(long address, double x);
    388 
    389     public native void copyMemoryToPrimitiveArray(long srcAddr,
    390             Object dst, long dstOffset, long bytes);
    391 
    392     public native void copyMemoryFromPrimitiveArray(Object src, long srcOffset,
    393             long dstAddr, long bytes);
    394 
    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
    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
    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
    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
    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
    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
    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
    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
    542     public native void fullFence();
    543 }
    544