All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sun.misc.Unsafe Maven / Gradle / Ivy

There is a newer version: 1.14.0
Show newest version
/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package sun.misc;

import dalvik.system.VMStack;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

/**
 * The package name notwithstanding, this class is the quasi-standard
 * way for Java code to gain access to and use functionality which,
 * when unsupervised, would allow one to break the pointer/type safety
 * of Java.
 */
public final class Unsafe {
    /** Traditional dalvik name. */
    private static final Unsafe THE_ONE = new Unsafe();
    /** Traditional RI name. */
    private static final Unsafe theUnsafe = THE_ONE;

    /**
     * This class is only privately instantiable.
     */
    private Unsafe() {}

    /**
     * Gets the unique instance of this class. This is only allowed in
     * very limited situations.
     */
    public static Unsafe getUnsafe() {
        /*
         * Only code on the bootclasspath is allowed to get at the
         * Unsafe instance.
         */
        ClassLoader calling = VMStack.getCallingClassLoader();
        if ((calling != null) && (calling != Unsafe.class.getClassLoader())) {
            throw new SecurityException("Unsafe access denied");
        }

        return THE_ONE;
    }

    /**
     * Gets the raw byte offset from the start of an object's memory to
     * the memory used to store the indicated instance field.
     *
     * @param field non-null; the field in question, which must be an
     * instance field
     * @return the offset to the field
     */
    public long objectFieldOffset(Field field) {
        if (Modifier.isStatic(field.getModifiers())) {
            throw new IllegalArgumentException(
                    "valid for instance fields only");
        }

        return objectFieldOffset0(field);
    }

    /**
     * Helper for {@link #objectFieldOffset}, which does all the work,
     * assuming the parameter is deemed valid.
     *
     * @param field non-null; the instance field
     * @return the offset to the field
     */
    private static native long objectFieldOffset0(Field field);

    /**
     * Gets the offset from the start of an array object's memory to
     * the memory used to store its initial (zeroeth) element.
     *
     * @param clazz non-null; class in question; must be an array class
     * @return the offset to the initial element
     */
    public int arrayBaseOffset(Class clazz) {
        if (! clazz.isArray()) {
            throw new IllegalArgumentException(
                    "valid for array classes only");
        }

        return arrayBaseOffset0(clazz);
    }

    /**
     * Helper for {@link #arrayBaseOffset}, which does all the work,
     * assuming the parameter is deemed valid.
     *
     * @return the offset to the field
     */
    private static native int arrayBaseOffset0(Class clazz);

    /**
     * Gets the size of each element of the given array class.
     *
     * @param clazz non-null; class in question; must be an array class
     * @return > 0; the size of each element of the array
     */
    public int arrayIndexScale(Class clazz) {
        if (! clazz.isArray()) {
            throw new IllegalArgumentException(
                    "valid for array classes only");
        }

        return arrayIndexScale0(clazz);
    }

    /**
     * Helper for {@link #arrayIndexScale}, which does all the work,
     * assuming the parameter is deemed valid.
     *
     * @return the offset to the field
     */
    private static native int arrayIndexScale0(Class clazz);

    /**
     * Performs a compare-and-set operation on an int
     * field within the given object.
     *
     * @param obj non-null; object containing the field
     * @param offset offset to the field within obj
     * @param expectedValue expected value of the field
     * @param newValue new value to store in the field if the contents are
     * as expected
     * @return true if the new value was in fact stored, and
     * false if not
     */
    public native boolean compareAndSwapInt(Object obj, long offset,
            int expectedValue, int newValue);

    /**
     * Performs a compare-and-set operation on a long
     * field within the given object.
     *
     * @param obj non-null; object containing the field
     * @param offset offset to the field within obj
     * @param expectedValue expected value of the field
     * @param newValue new value to store in the field if the contents are
     * as expected
     * @return true if the new value was in fact stored, and
     * false if not
     */
    public native boolean compareAndSwapLong(Object obj, long offset,
            long expectedValue, long newValue);

    /**
     * Performs a compare-and-set operation on an Object
     * field (that is, a reference field) within the given object.
     *
     * @param obj non-null; object containing the field
     * @param offset offset to the field within obj
     * @param expectedValue expected value of the field
     * @param newValue new value to store in the field if the contents are
     * as expected
     * @return true if the new value was in fact stored, and
     * false if not
     */
    public native boolean compareAndSwapObject(Object obj, long offset,
            Object expectedValue, Object newValue);

    /**
     * Gets an int field from the given object,
     * using volatile semantics.
     *
     * @param obj non-null; object containing the field
     * @param offset offset to the field within obj
     * @return the retrieved value
     */
    public native int getIntVolatile(Object obj, long offset);

    /**
     * Stores an int field into the given object,
     * using volatile semantics.
     *
     * @param obj non-null; object containing the field
     * @param offset offset to the field within obj
     * @param newValue the value to store
     */
    public native void putIntVolatile(Object obj, long offset, int newValue);

    /**
     * Gets a long field from the given object,
     * using volatile semantics.
     *
     * @param obj non-null; object containing the field
     * @param offset offset to the field within obj
     * @return the retrieved value
     */
    public native long getLongVolatile(Object obj, long offset);

    /**
     * Stores a long field into the given object,
     * using volatile semantics.
     *
     * @param obj non-null; object containing the field
     * @param offset offset to the field within obj
     * @param newValue the value to store
     */
    public native void putLongVolatile(Object obj, long offset, long newValue);

    /**
     * Gets an Object field from the given object,
     * using volatile semantics.
     *
     * @param obj non-null; object containing the field
     * @param offset offset to the field within obj
     * @return the retrieved value
     */
    public native Object getObjectVolatile(Object obj, long offset);

    /**
     * Stores an Object field into the given object,
     * using volatile semantics.
     *
     * @param obj non-null; object containing the field
     * @param offset offset to the field within obj
     * @param newValue the value to store
     */
    public native void putObjectVolatile(Object obj, long offset,
            Object newValue);

    /**
     * Gets an int field from the given object.
     *
     * @param obj non-null; object containing the field
     * @param offset offset to the field within obj
     * @return the retrieved value
     */
    public native int getInt(Object obj, long offset);

    /**
     * Stores an int field into the given object.
     *
     * @param obj non-null; object containing the field
     * @param offset offset to the field within obj
     * @param newValue the value to store
     */
    public native void putInt(Object obj, long offset, int newValue);

    /**
     * Lazy set an int field.
     */
    public native void putOrderedInt(Object obj, long offset, int newValue);

    /**
     * Gets a long field from the given object.
     *
     * @param obj non-null; object containing the field
     * @param offset offset to the field within obj
     * @return the retrieved value
     */
    public native long getLong(Object obj, long offset);

    /**
     * Stores a long field into the given object.
     *
     * @param obj non-null; object containing the field
     * @param offset offset to the field within obj
     * @param newValue the value to store
     */
    public native void putLong(Object obj, long offset, long newValue);

    /**
     * Lazy set a long field.
     */
    public native void putOrderedLong(Object obj, long offset, long newValue);

    /**
     * Gets an Object field from the given object.
     *
     * @param obj non-null; object containing the field
     * @param offset offset to the field within obj
     * @return the retrieved value
     */
    public native Object getObject(Object obj, long offset);

    /**
     * Stores an Object field into the given object.
     *
     * @param obj non-null; object containing the field
     * @param offset offset to the field within obj
     * @param newValue the value to store
     */
    public native void putObject(Object obj, long offset, Object newValue);

    /**
     * Lazy set an object field.
     */
    public native void putOrderedObject(Object obj, long offset,
            Object newValue);

    /**
     * Parks the calling thread for the specified amount of time,
     * unless the "permit" for the thread is already available (due to
     * a previous call to {@link #unpark}. This method may also return
     * spuriously (that is, without the thread being told to unpark
     * and without the indicated amount of time elapsing).
     *
     * 

See {@link java.util.concurrent.locks.LockSupport} for more * in-depth information of the behavior of this method.

* * @param absolute whether the given time value is absolute * milliseconds-since-the-epoch (true) or relative * nanoseconds-from-now (false) * @param time the (absolute millis or relative nanos) time value */ public void park(boolean absolute, long time) { if (absolute) { Thread.currentThread().parkUntil(time); } else { Thread.currentThread().parkFor(time); } } /** * Unparks the given object, which must be a {@link Thread}. * *

See {@link java.util.concurrent.locks.LockSupport} for more * in-depth information of the behavior of this method.

* * @param obj non-null; the object to unpark */ public void unpark(Object obj) { if (obj instanceof Thread) { ((Thread) obj).unpark(); } else { throw new IllegalArgumentException("valid for Threads only"); } } /** * Allocates an instance of the given class without running the constructor. * The class' will be run, if necessary. */ public native Object allocateInstance(Class c); }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy