/*
 * Copyright (C) 2008 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.
 */

/*
 * sun.misc.Unsafe
 */
#include "Dalvik.h"
#include "native/InternalNativePriv.h"


/*
 * private static native long objectFieldOffset0(Field field);
 */
static void Dalvik_sun_misc_Unsafe_objectFieldOffset0(const u4* args,
    JValue* pResult)
{
    Object* fieldObject = (Object*) args[0];
    InstField* field = (InstField*) dvmGetFieldFromReflectObj(fieldObject);
    s8 result = ((s8) field->byteOffset);

    RETURN_LONG(result);
}

/*
 * private static native int arrayBaseOffset0(Class clazz);
 */
static void Dalvik_sun_misc_Unsafe_arrayBaseOffset0(const u4* args,
    JValue* pResult)
{
    // The base offset is not type-dependent in this vm.
    UNUSED_PARAMETER(args);
    RETURN_INT(offsetof(ArrayObject, contents));
}

/*
 * private static native int arrayIndexScale0(Class clazz);
 */
static void Dalvik_sun_misc_Unsafe_arrayIndexScale0(const u4* args,
    JValue* pResult)
{
    ClassObject* clazz = (ClassObject*) args[0];
    RETURN_INT(dvmArrayClassElementWidth(clazz));
}

/*
 * public native boolean compareAndSwapInt(Object obj, long offset,
 *         int expectedValue, int newValue);
 */
static void Dalvik_sun_misc_Unsafe_compareAndSwapInt(const u4* args,
    JValue* pResult)
{
    // We ignore the this pointer in args[0].
    Object* obj = (Object*) args[1];
    s8 offset = GET_ARG_LONG(args, 2);
    s4 expectedValue = args[4];
    s4 newValue = args[5];
    volatile int32_t* address = (volatile int32_t*) (((u1*) obj) + offset);

    // Note: android_atomic_release_cas() returns 0 on success, not failure.
    int result = android_atomic_release_cas(expectedValue, newValue, address);

    RETURN_BOOLEAN(result == 0);
}

/*
 * public native boolean compareAndSwapLong(Object obj, long offset,
 *         long expectedValue, long newValue);
 */
static void Dalvik_sun_misc_Unsafe_compareAndSwapLong(const u4* args,
    JValue* pResult)
{
    // We ignore the this pointer in args[0].
    Object* obj = (Object*) args[1];
    s8 offset = GET_ARG_LONG(args, 2);
    s8 expectedValue = GET_ARG_LONG(args, 4);
    s8 newValue = GET_ARG_LONG(args, 6);
    volatile int64_t* address = (volatile int64_t*) (((u1*) obj) + offset);

    // Note: android_atomic_cmpxchg() returns 0 on success, not failure.
    int result =
        dvmQuasiAtomicCas64(expectedValue, newValue, address);

    RETURN_BOOLEAN(result == 0);
}

/*
 * public native boolean compareAndSwapObject(Object obj, long offset,
 *         Object expectedValue, Object newValue);
 */
static void Dalvik_sun_misc_Unsafe_compareAndSwapObject(const u4* args,
    JValue* pResult)
{
    // We ignore the this pointer in args[0].
    Object* obj = (Object*) args[1];
    s8 offset = GET_ARG_LONG(args, 2);
    Object* expectedValue = (Object*) args[4];
    Object* newValue = (Object*) args[5];
    int32_t* address = (int32_t*) (((u1*) obj) + offset);

    // Note: android_atomic_cmpxchg() returns 0 on success, not failure.
    int result = android_atomic_release_cas((int32_t) expectedValue,
            (int32_t) newValue, address);
    dvmWriteBarrierField(obj, address);
    RETURN_BOOLEAN(result == 0);
}

/*
 * public native int getIntVolatile(Object obj, long offset);
 */
static void Dalvik_sun_misc_Unsafe_getIntVolatile(const u4* args,
    JValue* pResult)
{
    // We ignore the this pointer in args[0].
    Object* obj = (Object*) args[1];
    s8 offset = GET_ARG_LONG(args, 2);
    volatile int32_t* address = (volatile int32_t*) (((u1*) obj) + offset);

    int32_t value = android_atomic_acquire_load(address);
    RETURN_INT(value);
}

/*
 * public native void putIntVolatile(Object obj, long offset, int newValue);
 */
static void Dalvik_sun_misc_Unsafe_putIntVolatile(const u4* args,
    JValue* pResult)
{
    // We ignore the this pointer in args[0].
    Object* obj = (Object*) args[1];
    s8 offset = GET_ARG_LONG(args, 2);
    s4 value = (s4) args[4];
    volatile int32_t* address = (volatile int32_t*) (((u1*) obj) + offset);

    android_atomic_release_store(value, address);
    RETURN_VOID();
}

/*
 * public native long getLongVolatile(Object obj, long offset);
 */
static void Dalvik_sun_misc_Unsafe_getLongVolatile(const u4* args,
    JValue* pResult)
{
    // We ignore the this pointer in args[0].
    Object* obj = (Object*) args[1];
    s8 offset = GET_ARG_LONG(args, 2);
    volatile int64_t* address = (volatile int64_t*) (((u1*) obj) + offset);

    assert((offset & 7) == 0);
    RETURN_LONG(dvmQuasiAtomicRead64(address));
}

/*
 * public native void putLongVolatile(Object obj, long offset, long newValue);
 */
static void Dalvik_sun_misc_Unsafe_putLongVolatile(const u4* args,
    JValue* pResult)
{
    // We ignore the this pointer in args[0].
    Object* obj = (Object*) args[1];
    s8 offset = GET_ARG_LONG(args, 2);
    s8 value = GET_ARG_LONG(args, 4);
    volatile int64_t* address = (volatile int64_t*) (((u1*) obj) + offset);

    assert((offset & 7) == 0);
    dvmQuasiAtomicSwap64(value, address);
    RETURN_VOID();
}

/*
 * public native Object getObjectVolatile(Object obj, long offset);
 */
static void Dalvik_sun_misc_Unsafe_getObjectVolatile(const u4* args,
    JValue* pResult)
{
    // We ignore the this pointer in args[0].
    Object* obj = (Object*) args[1];
    s8 offset = GET_ARG_LONG(args, 2);
    volatile int32_t* address = (volatile int32_t*) (((u1*) obj) + offset);

    RETURN_PTR((Object*) android_atomic_acquire_load(address));
}

/*
 * public native void putObjectVolatile(Object obj, long offset,
 *         Object newValue);
 */
static void Dalvik_sun_misc_Unsafe_putObjectVolatile(const u4* args,
    JValue* pResult)
{
    // We ignore the this pointer in args[0].
    Object* obj = (Object*) args[1];
    s8 offset = GET_ARG_LONG(args, 2);
    Object* value = (Object*) args[4];
    volatile int32_t* address = (volatile int32_t*) (((u1*) obj) + offset);

    android_atomic_release_store((int32_t)value, address);
    dvmWriteBarrierField(obj, (void *)address);
    RETURN_VOID();
}

/*
 * public native int getInt(Object obj, long offset);
 */
static void Dalvik_sun_misc_Unsafe_getInt(const u4* args, JValue* pResult)
{
    // We ignore the this pointer in args[0].
    Object* obj = (Object*) args[1];
    s8 offset = GET_ARG_LONG(args, 2);
    s4* address = (s4*) (((u1*) obj) + offset);

    RETURN_INT(*address);
}

/*
 * public native void putInt(Object obj, long offset, int newValue);
 */
static void Dalvik_sun_misc_Unsafe_putInt(const u4* args, JValue* pResult)
{
    // We ignore the this pointer in args[0].
    Object* obj = (Object*) args[1];
    s8 offset = GET_ARG_LONG(args, 2);
    s4 value = (s4) args[4];
    s4* address = (s4*) (((u1*) obj) + offset);

    *address = value;
    RETURN_VOID();
}

/*
 * public native void putOrderedInt(Object obj, long offset, int newValue);
 */
static void Dalvik_sun_misc_Unsafe_putOrderedInt(const u4* args,
    JValue* pResult)
{
    // We ignore the this pointer in args[0].
    Object* obj = (Object*) args[1];
    s8 offset = GET_ARG_LONG(args, 2);
    s4 value = (s4) args[4];
    s4* address = (s4*) (((u1*) obj) + offset);

    ANDROID_MEMBAR_STORE();
    *address = value;
    RETURN_VOID();
}

/*
 * public native long getLong(Object obj, long offset);
 */
static void Dalvik_sun_misc_Unsafe_getLong(const u4* args, JValue* pResult)
{
    // We ignore the this pointer in args[0].
    Object* obj = (Object*) args[1];
    s8 offset = GET_ARG_LONG(args, 2);
    s8* address = (s8*) (((u1*) obj) + offset);

    RETURN_LONG(*address);
}

/*
 * public native void putLong(Object obj, long offset, long newValue);
 */
static void Dalvik_sun_misc_Unsafe_putLong(const u4* args, JValue* pResult)
{
    // We ignore the this pointer in args[0].
    Object* obj = (Object*) args[1];
    s8 offset = GET_ARG_LONG(args, 2);
    s8 value = GET_ARG_LONG(args, 4);
    s8* address = (s8*) (((u1*) obj) + offset);

    *address = value;
    RETURN_VOID();
}

/*
 * public native void putOrderedLong(Object obj, long offset, long newValue);
 */
static void Dalvik_sun_misc_Unsafe_putOrderedLong(const u4* args,
    JValue* pResult)
{
    // We ignore the this pointer in args[0].
    Object* obj = (Object*) args[1];
    s8 offset = GET_ARG_LONG(args, 2);
    s8 value = GET_ARG_LONG(args, 4);
    s8* address = (s8*) (((u1*) obj) + offset);

    ANDROID_MEMBAR_STORE();
    *address = value;
    RETURN_VOID();
}

/*
 * public native Object getObject(Object obj, long offset);
 */
static void Dalvik_sun_misc_Unsafe_getObject(const u4* args, JValue* pResult)
{
    // We ignore the this pointer in args[0].
    Object* obj = (Object*) args[1];
    s8 offset = GET_ARG_LONG(args, 2);
    Object** address = (Object**) (((u1*) obj) + offset);

    RETURN_PTR(*address);
}

/*
 * public native void putObject(Object obj, long offset, Object newValue);
 */
static void Dalvik_sun_misc_Unsafe_putObject(const u4* args, JValue* pResult)
{
    // We ignore the this pointer in args[0].
    Object* obj = (Object*) args[1];
    s8 offset = GET_ARG_LONG(args, 2);
    Object* value = (Object*) args[4];
    Object** address = (Object**) (((u1*) obj) + offset);

    *address = value;
    dvmWriteBarrierField(obj, address);
    RETURN_VOID();
}

/*
 * public native void putOrderedObject(Object obj, long offset,
 *      Object newValue);
 */
static void Dalvik_sun_misc_Unsafe_putOrderedObject(const u4* args,
    JValue* pResult)
{
    // We ignore the this pointer in args[0].
    Object* obj = (Object*) args[1];
    s8 offset = GET_ARG_LONG(args, 2);
    Object* value = (Object*) args[4];
    Object** address = (Object**) (((u1*) obj) + offset);

    ANDROID_MEMBAR_STORE();
    *address = value;
    dvmWriteBarrierField(obj, address);
    RETURN_VOID();
}

const DalvikNativeMethod dvm_sun_misc_Unsafe[] = {
    { "objectFieldOffset0", "(Ljava/lang/reflect/Field;)J",
      Dalvik_sun_misc_Unsafe_objectFieldOffset0 },
    { "arrayBaseOffset0", "(Ljava/lang/Class;)I",
      Dalvik_sun_misc_Unsafe_arrayBaseOffset0 },
    { "arrayIndexScale0", "(Ljava/lang/Class;)I",
      Dalvik_sun_misc_Unsafe_arrayIndexScale0 },
    { "compareAndSwapInt", "(Ljava/lang/Object;JII)Z",
      Dalvik_sun_misc_Unsafe_compareAndSwapInt },
    { "compareAndSwapLong", "(Ljava/lang/Object;JJJ)Z",
      Dalvik_sun_misc_Unsafe_compareAndSwapLong },
    { "compareAndSwapObject",
      "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
      Dalvik_sun_misc_Unsafe_compareAndSwapObject },
    { "getIntVolatile", "(Ljava/lang/Object;J)I",
      Dalvik_sun_misc_Unsafe_getIntVolatile },
    { "putIntVolatile", "(Ljava/lang/Object;JI)V",
      Dalvik_sun_misc_Unsafe_putIntVolatile },
    { "getLongVolatile", "(Ljava/lang/Object;J)J",
      Dalvik_sun_misc_Unsafe_getLongVolatile },
    { "putLongVolatile", "(Ljava/lang/Object;JJ)V",
      Dalvik_sun_misc_Unsafe_putLongVolatile },
    { "getObjectVolatile", "(Ljava/lang/Object;J)Ljava/lang/Object;",
      Dalvik_sun_misc_Unsafe_getObjectVolatile },
    { "putObjectVolatile", "(Ljava/lang/Object;JLjava/lang/Object;)V",
      Dalvik_sun_misc_Unsafe_putObjectVolatile },
    { "getInt", "(Ljava/lang/Object;J)I",
      Dalvik_sun_misc_Unsafe_getInt },
    { "putInt", "(Ljava/lang/Object;JI)V",
      Dalvik_sun_misc_Unsafe_putInt },
    { "putOrderedInt", "(Ljava/lang/Object;JI)V",
      Dalvik_sun_misc_Unsafe_putOrderedInt },
    { "getLong", "(Ljava/lang/Object;J)J",
      Dalvik_sun_misc_Unsafe_getLong },
    { "putLong", "(Ljava/lang/Object;JJ)V",
      Dalvik_sun_misc_Unsafe_putLong },
    { "putOrderedLong", "(Ljava/lang/Object;JJ)V",
      Dalvik_sun_misc_Unsafe_putOrderedLong },
    { "getObject", "(Ljava/lang/Object;J)Ljava/lang/Object;",
      Dalvik_sun_misc_Unsafe_getObject },
    { "putObject", "(Ljava/lang/Object;JLjava/lang/Object;)V",
      Dalvik_sun_misc_Unsafe_putObject },
    { "putOrderedObject", "(Ljava/lang/Object;JLjava/lang/Object;)V",
      Dalvik_sun_misc_Unsafe_putOrderedObject },
    { NULL, NULL, NULL },
};
