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.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      */
     51     private Unsafe() {}
     52 
     53     /**
     54      * Gets the unique instance of this class. This is only allowed in
     55      * very limited situations.
     56      */
     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      */
     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      */
     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 &gt; 0; the size of each element of the array
    105      */
    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
    115     private static native int getArrayBaseOffsetForComponentType(Class component_class);
    116     @FastNative
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    252     public native void putInt(Object obj, long offset, int newValue);
    253 
    254     /**
    255      * Lazy set an int field.
    256      */
    257     @FastNative
    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
    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
    278     public native void putLong(Object obj, long offset, long newValue);
    279 
    280     /**
    281      * Lazy set a long field.
    282      */
    283     @FastNative
    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
    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
    304     public native void putObject(Object obj, long offset, Object newValue);
    305 
    306     /**
    307      * Lazy set an object field.
    308      */
    309     @FastNative
    310     public native void putOrderedObject(Object obj, long offset,
    311             Object newValue);
    312 
    313 
    314     @FastNative
    315     public native boolean getBoolean(Object obj, long offset);
    316     @FastNative
    317     public native void putBoolean(Object obj, long offset, boolean newValue);
    318     @FastNative
    319     public native byte getByte(Object obj, long offset);
    320     @FastNative
    321     public native void putByte(Object obj, long offset, byte newValue);
    322     @FastNative
    323     public native char getChar(Object obj, long offset);
    324     @FastNative
    325     public native void putChar(Object obj, long offset, char newValue);
    326     @FastNative
    327     public native short getShort(Object obj, long offset);
    328     @FastNative
    329     public native void putShort(Object obj, long offset, short newValue);
    330     @FastNative
    331     public native float getFloat(Object obj, long offset);
    332     @FastNative
    333     public native void putFloat(Object obj, long offset, float newValue);
    334     @FastNative
    335     public native double getDouble(Object obj, long offset);
    336     @FastNative
    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      */
    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      */
    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      */
    382     public native Object allocateInstance(Class<?> c);
    383 
    384     @FastNative
    385     public native int addressSize();
    386 
    387     @FastNative
    388     public native int pageSize();
    389 
    390     @FastNative
    391     public native long allocateMemory(long bytes);
    392 
    393     @FastNative
    394     public native void freeMemory(long address);
    395 
    396     @FastNative
    397     public native void setMemory(long address, long bytes, byte value);
    398 
    399     @FastNative
    400     public native byte getByte(long address);
    401 
    402     @FastNative
    403     public native void putByte(long address, byte x);
    404 
    405     @FastNative
    406     public native short getShort(long address);
    407 
    408     @FastNative
    409     public native void putShort(long address, short x);
    410 
    411     @FastNative
    412     public native char getChar(long address);
    413 
    414     @FastNative
    415     public native void putChar(long address, char x);
    416 
    417     @FastNative
    418     public native int getInt(long address);
    419 
    420     @FastNative
    421     public native void putInt(long address, int x);
    422 
    423     @FastNative
    424     public native long getLong(long address);
    425 
    426     @FastNative
    427     public native void putLong(long address, long x);
    428 
    429     @FastNative
    430     public native float getFloat(long address);
    431 
    432     @FastNative
    433     public native void putFloat(long address, float x);
    434 
    435     @FastNative
    436     public native double getDouble(long address);
    437 
    438     @FastNative
    439     public native void putDouble(long address, double x);
    440 
    441     @FastNative
    442     public native void copyMemoryToPrimitiveArray(long srcAddr,
    443             Object dst, long dstOffset, long bytes);
    444 
    445     @FastNative
    446     public native void copyMemoryFromPrimitiveArray(Object src, long srcOffset,
    447             long dstAddr, long bytes);
    448 
    449     @FastNative
    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
    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
    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
    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
    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
    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
    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
    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
    600     public native void fullFence();
    601 }
    602