X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fnative%2Fvm%2Fsun_misc_Unsafe.c;h=737559da5cafcc99ee642645f7f5c7d593e0cdcd;hb=16f22a7638c7515675d10ab44107f40bf9197ba9;hp=3635b2a8cf4a70fe1571adde886e5ac57d7dee65;hpb=773281400f5bab23de28144498baeffcfed4159a;p=cacao.git diff --git a/src/native/vm/sun_misc_Unsafe.c b/src/native/vm/sun_misc_Unsafe.c index 3635b2a8c..737559da5 100644 --- a/src/native/vm/sun_misc_Unsafe.c +++ b/src/native/vm/sun_misc_Unsafe.c @@ -1,9 +1,7 @@ /* src/native/vm/sun_misc_Unsafe.c - sun/misc/Unsafe - Copyright (C) 2006, 2007 R. Grafl, A. Krall, C. Kruegel, C. Oates, - R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner, - C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger, - Institut f. Computersprachen - TU Wien + Copyright (C) 2006, 2007, 2008 + CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO This file is part of CACAO. @@ -22,24 +20,26 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: java_lang_VMObject.c 5153 2006-07-18 08:19:24Z twisti $ - */ #include "config.h" #include +#include + +#include "machine-instr.h" #include "mm/memory.h" #include "native/jni.h" +#include "native/llni.h" #include "native/native.h" #include "native/include/java_lang_Object.h" /* before c.l.C */ #include "native/include/java_lang_String.h" /* required by j.l.CL */ -#if defined(WITH_CLASSPATH_SUN) +#if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) # include "native/include/java_nio_ByteBuffer.h" /* required by j.l.CL */ #endif @@ -49,15 +49,20 @@ #include "native/include/java_lang_Thread.h" /* required by s.m.U */ #include "native/include/java_lang_Throwable.h" -#if defined(WITH_CLASSPATH_SUN) -# include "native/include/java_security_ProtectionDomain.h" /* required by smU*/ +#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) +# include "native/include/java_lang_reflect_VMField.h" #endif +#include "native/include/java_security_ProtectionDomain.h" /* required by smU */ + #include "native/include/sun_misc_Unsafe.h" +#include "vm/builtin.h" #include "vm/exceptions.h" #include "vm/initialize.h" +#include "vm/stringlocal.h" +#include "vmcore/system.h" #include "vmcore/utf8.h" @@ -66,28 +71,69 @@ static JNINativeMethod methods[] = { { "registerNatives", "()V", (void *) (intptr_t) &Java_sun_misc_Unsafe_registerNatives }, { "getInt", "(Ljava/lang/Object;J)I", (void *) (intptr_t) &Java_sun_misc_Unsafe_getInt__Ljava_lang_Object_2J }, + { "putInt", "(Ljava/lang/Object;JI)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putInt__Ljava_lang_Object_2JI }, + { "getObject", "(Ljava/lang/Object;J)Ljava/lang/Object;", (void *) (intptr_t) &Java_sun_misc_Unsafe_getObject }, + { "putObject", "(Ljava/lang/Object;JLjava/lang/Object;)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putObject }, { "getBoolean", "(Ljava/lang/Object;J)Z", (void *) (intptr_t) &Java_sun_misc_Unsafe_getBoolean }, { "putBoolean", "(Ljava/lang/Object;JZ)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putBoolean }, { "getByte", "(Ljava/lang/Object;J)B", (void *) (intptr_t) &Java_sun_misc_Unsafe_getByte__Ljava_lang_Object_2J }, { "putByte", "(Ljava/lang/Object;JB)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putByte__Ljava_lang_Object_2JB }, + { "getShort", "(Ljava/lang/Object;J)S", (void *) (intptr_t) &Java_sun_misc_Unsafe_getShort__Ljava_lang_Object_2J }, + { "putShort", "(Ljava/lang/Object;JS)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putShort__Ljava_lang_Object_2JS }, { "getChar", "(Ljava/lang/Object;J)C", (void *) (intptr_t) &Java_sun_misc_Unsafe_getChar__Ljava_lang_Object_2J }, { "putChar", "(Ljava/lang/Object;JC)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putChar__Ljava_lang_Object_2JC }, + { "getLong", "(Ljava/lang/Object;J)J", (void *) (intptr_t) &Java_sun_misc_Unsafe_getLong__Ljava_lang_Object_2J }, + { "putLong", "(Ljava/lang/Object;JJ)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putLong__Ljava_lang_Object_2JJ }, + { "getFloat", "(Ljava/lang/Object;J)F", (void *) (intptr_t) &Java_sun_misc_Unsafe_getFloat__Ljava_lang_Object_2J }, + { "putFloat", "(Ljava/lang/Object;JF)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putFloat__Ljava_lang_Object_2JF }, + { "getDouble", "(Ljava/lang/Object;J)D", (void *) (intptr_t) &Java_sun_misc_Unsafe_getDouble__Ljava_lang_Object_2J }, + { "putDouble", "(Ljava/lang/Object;JD)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putDouble__Ljava_lang_Object_2JD }, { "getByte", "(J)B", (void *) (intptr_t) &Java_sun_misc_Unsafe_getByte__J }, + { "putByte", "(JB)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putByte__JB }, + { "getShort", "(J)S", (void *) (intptr_t) &Java_sun_misc_Unsafe_getShort__J }, + { "putShort", "(JS)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putShort__JS }, + { "getChar", "(J)C", (void *) (intptr_t) &Java_sun_misc_Unsafe_getChar__J }, + { "putChar", "(JC)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putChar__JC }, { "getInt", "(J)I", (void *) (intptr_t) &Java_sun_misc_Unsafe_getInt__J }, + { "putInt", "(JI)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putInt__JI }, { "getLong", "(J)J", (void *) (intptr_t) &Java_sun_misc_Unsafe_getLong__J }, { "putLong", "(JJ)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putLong__JJ }, + { "getFloat", "(J)F", (void *) (intptr_t) &Java_sun_misc_Unsafe_getFloat__J }, { "objectFieldOffset", "(Ljava/lang/reflect/Field;)J", (void *) (intptr_t) &Java_sun_misc_Unsafe_objectFieldOffset }, { "allocateMemory", "(J)J", (void *) (intptr_t) &Java_sun_misc_Unsafe_allocateMemory }, +#if 0 + /* OpenJDK 7 */ + { "setMemory", "(Ljava/lang/Object;JJB)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_setMemory }, + { "copyMemory", "(Ljava/lang/Object;JLjava/lang/Object;JJ)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_copyMemory }, +#else + { "setMemory", "(JJB)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_setMemory }, + { "copyMemory", "(JJJ)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_copyMemory }, +#endif { "freeMemory", "(J)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_freeMemory }, { "staticFieldOffset", "(Ljava/lang/reflect/Field;)J", (void *) (intptr_t) &Java_sun_misc_Unsafe_staticFieldOffset }, { "staticFieldBase", "(Ljava/lang/reflect/Field;)Ljava/lang/Object;", (void *) (intptr_t) &Java_sun_misc_Unsafe_staticFieldBase }, { "ensureClassInitialized", "(Ljava/lang/Class;)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_ensureClassInitialized }, + { "arrayBaseOffset", "(Ljava/lang/Class;)I", (void *) (intptr_t) &Java_sun_misc_Unsafe_arrayBaseOffset }, + { "arrayIndexScale", "(Ljava/lang/Class;)I", (void *) (intptr_t) &Java_sun_misc_Unsafe_arrayIndexScale }, + { "addressSize", "()I", (void *) (intptr_t) &Java_sun_misc_Unsafe_addressSize }, + { "pageSize", "()I", (void *) (intptr_t) &Java_sun_misc_Unsafe_pageSize }, + { "defineClass", "(Ljava/lang/String;[BIILjava/lang/ClassLoader;Ljava/security/ProtectionDomain;)Ljava/lang/Class;", (void *) (intptr_t) &Java_sun_misc_Unsafe_defineClass__Ljava_lang_String_2_3BIILjava_lang_ClassLoader_2Ljava_security_ProtectionDomain_2 }, + { "allocateInstance", "(Ljava/lang/Class;)Ljava/lang/Object;", (void *) (intptr_t) &Java_sun_misc_Unsafe_allocateInstance }, { "throwException", "(Ljava/lang/Throwable;)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_throwException }, { "compareAndSwapObject", "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z", (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapObject }, { "compareAndSwapInt", "(Ljava/lang/Object;JII)Z", (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapInt }, { "compareAndSwapLong", "(Ljava/lang/Object;JJJ)Z", (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapLong }, { "getObjectVolatile", "(Ljava/lang/Object;J)Ljava/lang/Object;", (void *) (intptr_t) &Java_sun_misc_Unsafe_getObjectVolatile }, + { "putObjectVolatile", "(Ljava/lang/Object;JLjava/lang/Object;)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putObjectVolatile }, { "getIntVolatile", "(Ljava/lang/Object;J)I", (void *) (intptr_t) &Java_sun_misc_Unsafe_getIntVolatile }, + { "putIntVolatile", "(Ljava/lang/Object;JI)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putIntVolatile }, + { "getLongVolatile", "(Ljava/lang/Object;J)J", (void *) (intptr_t) &Java_sun_misc_Unsafe_getLongVolatile }, + { "putLongVolatile", "(Ljava/lang/Object;JJ)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putLongVolatile }, + { "putOrderedObject", "(Ljava/lang/Object;JLjava/lang/Object;)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putOrderedObject }, + { "putOrderedInt", "(Ljava/lang/Object;JI)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putOrderedInt }, + { "putOrderedLong", "(Ljava/lang/Object;JJ)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_putOrderedLong }, + { "unpark", "(Ljava/lang/Object;)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_unpark }, + { "park", "(ZJ)V", (void *) (intptr_t) &Java_sun_misc_Unsafe_park }, }; @@ -138,6 +184,54 @@ JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getInt__Ljava_lang_Object_2J(JNIE } +/* + * Class: sun/misc/Unsafe + * Method: putInt + * Signature: (Ljava/lang/Object;JI)V + */ +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putInt__Ljava_lang_Object_2JI(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int32_t x) +{ + int32_t *p; + + p = (int32_t *) (((uint8_t *) o) + offset); + + *p = x; +} + + +/* + * Class: sun/misc/Unsafe + * Method: getObject + * Signature: (Ljava/lang/Object;J)Ljava/lang/Object; + */ +JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_getObject(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset) +{ + void **p; + void *value; + + p = (void **) (((uint8_t *) o) + offset); + + value = *p; + + return value; +} + + +/* + * Class: sun/misc/Unsafe + * Method: putObject + * Signature: (Ljava/lang/Object;JLjava/lang/Object;)V + */ +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putObject(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, java_lang_Object *x) +{ + void **p; + + p = (void **) (((uint8_t *) o) + offset); + + *p = (void *) x; +} + + /* * Class: sun/misc/Unsafe * Method: getBoolean @@ -204,6 +298,39 @@ JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putByte__Ljava_lang_Object_2JB(JNIEn } +/* + * Class: sun/misc/Unsafe + * Method: getShort + * Signature: (Ljava/lang/Object;J)S + */ +JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getShort__Ljava_lang_Object_2J(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset) +{ + int32_t *p; + int32_t value; + + p = (int32_t *) (((uint8_t *) o) + offset); + + value = *p; + + return value; +} + + +/* + * Class: sun/misc/Unsafe + * Method: putShort + * Signature: (Ljava/lang/Object;JS)V + */ +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putShort__Ljava_lang_Object_2JS(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int32_t x) +{ + int32_t *p; + + p = (int32_t *) (((uint8_t *) o) + offset); + + *p = x; +} + + /* * Class: sun/misc/Unsafe * Method: getChar @@ -237,6 +364,105 @@ JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putChar__Ljava_lang_Object_2JC(JNIEn } +/* + * Class: sun/misc/Unsafe + * Method: getLong + * Signature: (Ljava/lang/Object;J)J + */ +JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_getLong__Ljava_lang_Object_2J(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset) +{ + int64_t *p; + int64_t value; + + p = (int64_t *) (((uint8_t *) o) + offset); + + value = *p; + + return value; +} + + +/* + * Class: sun/misc/Unsafe + * Method: putLong + * Signature: (Ljava/lang/Object;JJ)V + */ +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putLong__Ljava_lang_Object_2JJ(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int64_t x) +{ + int64_t *p; + + p = (int64_t *) (((uint8_t *) o) + offset); + + *p = x; +} + + +/* + * Class: sun/misc/Unsafe + * Method: getFloat + * Signature: (Ljava/lang/Object;J)F + */ +JNIEXPORT float JNICALL Java_sun_misc_Unsafe_getFloat__Ljava_lang_Object_2J(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset) +{ + float *p; + float value; + + p = (float *) (((uint8_t *) o) + offset); + + value = *p; + + return value; +} + + +/* + * Class: sun/misc/Unsafe + * Method: putFloat + * Signature: (Ljava/lang/Object;JF)V + */ +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putFloat__Ljava_lang_Object_2JF(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, float x) +{ + float *p; + + p = (float *) (((uint8_t *) o) + offset); + + *p = x; +} + + +/* + * Class: sun/misc/Unsafe + * Method: getDouble + * Signature: (Ljava/lang/Object;J)D + */ +JNIEXPORT double JNICALL Java_sun_misc_Unsafe_getDouble__Ljava_lang_Object_2J(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset) +{ + double *p; + double value; + + p = (double *) (((uint8_t *) o) + offset); + + value = *p; + + return value; +} + + +/* + * Class: sun/misc/Unsafe + * Method: putDouble + * Signature: (Ljava/lang/Object;JD)V + */ +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putDouble__Ljava_lang_Object_2JD(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, double x) +{ + double *p; + + p = (double *) (((uint8_t *) o) + offset); + + *p = x; +} + + /* * Class: sun/misc/Unsafe * Method: getByte @@ -255,6 +481,87 @@ JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getByte__J(JNIEnv *env, sun_misc_ } +/* + * Class: sun/misc/Unsafe + * Method: putByte + * Signature: (JB)V + */ +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putByte__JB(JNIEnv *env, sun_misc_Unsafe *this, int64_t address, int32_t value) +{ + int8_t *p; + + p = (int8_t *) (intptr_t) address; + + *p = (int8_t) value; +} + + +/* + * Class: sun/misc/Unsafe + * Method: getShort + * Signature: (J)S + */ +JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getShort__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address) +{ + int16_t *p; + int16_t value; + + p = (int16_t *) (intptr_t) address; + + value = *p; + + return (int32_t) value; +} + + +/* + * Class: sun/misc/Unsafe + * Method: putShort + * Signature: (JS)V + */ +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putShort__JS(JNIEnv *env, sun_misc_Unsafe *this, int64_t address, int32_t value) +{ + int16_t *p; + + p = (int16_t *) (intptr_t) address; + + *p = (int16_t) value; +} + + +/* + * Class: sun/misc/Unsafe + * Method: getChar + * Signature: (J)C + */ +JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getChar__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address) +{ + uint16_t *p; + uint16_t value; + + p = (uint16_t *) (intptr_t) address; + + value = *p; + + return (int32_t) value; +} + + +/* + * Class: sun/misc/Unsafe + * Method: putChar + * Signature: (JC)V + */ +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putChar__JC(JNIEnv *env, sun_misc_Unsafe *this, int64_t address, int32_t value) +{ + uint16_t *p; + + p = (uint16_t *) (intptr_t) address; + + *p = (uint16_t) value; +} + + /* * Class: sun/misc/Unsafe * Method: getInt @@ -273,6 +580,21 @@ JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getInt__J(JNIEnv *env, sun_misc_U } +/* + * Class: sun/misc/Unsafe + * Method: putInt + * Signature: (JI)V + */ +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putInt__JI(JNIEnv *env, struct sun_misc_Unsafe* this, int64_t address, int32_t value) +{ + int32_t *p; + + p = (int32_t *) (intptr_t) address; + + *p = value; +} + + /* * Class: sun/misc/Unsafe * Method: getLong @@ -306,18 +628,55 @@ JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putLong__JJ(JNIEnv *env, sun_misc_Un } +/* + * Class: sun/misc/Unsafe + * Method: getFloat + * Signature: (J)F + */ +JNIEXPORT float JNICALL Java_sun_misc_Unsafe_getFloat__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address) +{ + float *p; + float value; + + p = (float *) (intptr_t) address; + + value = *p; + + return value; +} + + /* * Class: sun/misc/Unsafe * Method: objectFieldOffset * Signature: (Ljava/lang/reflect/Field;)J */ -JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_objectFieldOffset(JNIEnv *env, sun_misc_Unsafe* this, java_lang_reflect_Field* field) +JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_objectFieldOffset(JNIEnv *env, sun_misc_Unsafe *this, java_lang_reflect_Field *field) { classinfo *c; fieldinfo *f; + int32_t slot; + +#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) + java_lang_reflect_VMField *rvmf; +#endif + +#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) - c = (classinfo *) field->clazz; - f = &c->fields[field->slot]; + LLNI_field_get_ref(field, f, rvmf); + LLNI_field_get_cls(rvmf, clazz, c); + LLNI_field_get_val(rvmf, slot , slot); + +#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) + + LLNI_field_get_cls(field, clazz, c); + LLNI_field_get_val(field, slot , slot); + +#else +# error unknown configuration +#endif + + f = &(c->fields[slot]); return (int64_t) f->offset; } @@ -346,6 +705,119 @@ JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_allocateMemory(JNIEnv *env, sun_m } +#if 0 +/* OpenJDK 7 */ + +/* + * Class: sun/misc/Unsafe + * Method: setMemory + * Signature: (Ljava/lang/Object;JJB)V + */ +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_setMemory(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int64_t bytes, int32_t value) +{ + size_t length; + void *p; + + length = (size_t) bytes; + + if ((length != (uint64_t) bytes) || (bytes < 0)) { + exceptions_throw_illegalargumentexception(); + return; + } + + /* XXX Missing LLNI: we need to unwrap this object. */ + + p = (void *) (((uint8_t *) o) + offset); + + /* XXX Not sure this is correct. */ + + system_memset(p, value, length); +} + + +/* + * Class: sun/misc/Unsafe + * Method: copyMemory + * Signature: (Ljava/lang/Object;JLjava/lang/Object;JJ)V + */ +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_copyMemory(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *srcBase, int64_t srcOffset, java_lang_Object *destBase, int64_t destOffset, int64_t bytes) +{ + size_t length; + void *src; + void *dest; + + if (bytes == 0) + return; + + length = (size_t) bytes; + + if ((length != (uint64_t) bytes) || (bytes < 0)) { + exceptions_throw_illegalargumentexception(); + return; + } + + /* XXX Missing LLNI: We need to unwrap these objects. */ + + src = (void *) (((uint8_t *) srcBase) + srcOffset); + dest = (void *) (((uint8_t *) destBase) + destOffset); + + system_memcpy(dest, src, length); +} +#else +/* + * Class: sun/misc/Unsafe + * Method: setMemory + * Signature: (JJB)V + */ +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_setMemory(JNIEnv *env, sun_misc_Unsafe *this, int64_t address, int64_t bytes, int32_t value) +{ + size_t length; + void *p; + + length = (size_t) bytes; + + if ((length != (uint64_t) bytes) || (bytes < 0)) { + exceptions_throw_illegalargumentexception(); + return; + } + + p = (void *) (intptr_t) address; + + /* XXX Not sure this is correct. */ + + system_memset(p, value, length); +} + + +/* + * Class: sun/misc/Unsafe + * Method: copyMemory + * Signature: (JJJ)V + */ +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_copyMemory(JNIEnv *env, sun_misc_Unsafe *this, int64_t srcAddress, int64_t destAddress, int64_t bytes) +{ + size_t length; + void *src; + void *dest; + + if (bytes == 0) + return; + + length = (size_t) bytes; + + if ((length != (uint64_t) bytes) || (bytes < 0)) { + exceptions_throw_illegalargumentexception(); + return; + } + + src = (void *) (intptr_t) srcAddress; + dest = (void *) (intptr_t) destAddress; + + system_memcpy(dest, src, length); +} +#endif + + /* * Class: sun/misc/Unsafe * Method: freeMemory @@ -371,15 +843,11 @@ JNIEXPORT void JNICALL Java_sun_misc_Unsafe_freeMemory(JNIEnv *env, sun_misc_Uns * Method: staticFieldOffset * Signature: (Ljava/lang/reflect/Field;)J */ -JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_staticFieldOffset(JNIEnv *env, sun_misc_Unsafe *this, java_lang_reflect_Field *field) +JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_staticFieldOffset(JNIEnv *env, sun_misc_Unsafe *this, java_lang_reflect_Field *f) { - classinfo *c; - fieldinfo *f; + /* The offset of static fields is 0. */ - c = (classinfo *) field->clazz; - f = &(c->fields[field->slot]); - - return (int64_t) (intptr_t) &(f->value); + return 0; } @@ -388,11 +856,34 @@ JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_staticFieldOffset(JNIEnv *env, su * Method: staticFieldBase * Signature: (Ljava/lang/reflect/Field;)Ljava/lang/Object; */ -JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_staticFieldBase(JNIEnv *env, sun_misc_Unsafe *this, java_lang_reflect_Field *f) +JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_staticFieldBase(JNIEnv *env, sun_misc_Unsafe *this, java_lang_reflect_Field *rf) { - /* In CACAO we return the absolute address in staticFieldOffset. */ + classinfo *c; + fieldinfo *f; + int32_t slot; + +#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) + java_lang_reflect_VMField *rvmf; +#endif + +#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) + + LLNI_field_get_ref(rf, f, rvmf); + LLNI_field_get_cls(rvmf, clazz, c); + LLNI_field_get_val(rvmf, slot , slot); + +#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) - return NULL; + LLNI_field_get_cls(rf, clazz, c); + LLNI_field_get_val(rf, slot , slot); + +#else +# error unknown configuration +#endif + + f = &(c->fields[slot]); + + return (java_lang_Object *) (f->value); } @@ -405,13 +896,162 @@ JNIEXPORT void JNICALL Java_sun_misc_Unsafe_ensureClassInitialized(JNIEnv *env, { classinfo *c; - c = (classinfo *) class; + c = LLNI_classinfo_unwrap(class); if (!(c->state & CLASS_INITIALIZED)) initialize_class(c); } +/* + * Class: sun/misc/Unsafe + * Method: arrayBaseOffset + * Signature: (Ljava/lang/Class;)I + */ +JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_arrayBaseOffset(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Class *arrayClass) +{ + classinfo *c; + arraydescriptor *ad; + + c = LLNI_classinfo_unwrap(arrayClass); + ad = c->vftbl->arraydesc; + + if (ad == NULL) { + /* XXX does that exception exist? */ + exceptions_throw_internalerror("java/lang/InvalidClassException"); + return 0; + } + + return ad->dataoffset; +} + + +/* + * Class: sun/misc/Unsafe + * Method: arrayIndexScale + * Signature: (Ljava/lang/Class;)I + */ +JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_arrayIndexScale(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Class *arrayClass) +{ + classinfo *c; + arraydescriptor *ad; + + c = LLNI_classinfo_unwrap(arrayClass); + ad = c->vftbl->arraydesc; + + if (ad == NULL) { + /* XXX does that exception exist? */ + exceptions_throw_internalerror("java/lang/InvalidClassException"); + return 0; + } + + return ad->componentsize; +} + + +/* + * Class: sun/misc/Unsafe + * Method: addressSize + * Signature: ()I + */ +JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_addressSize(JNIEnv *env, sun_misc_Unsafe *this) +{ + return SIZEOF_VOID_P; +} + + +/* + * Class: sun/misc/Unsafe + * Method: pageSize + * Signature: ()I + */ +JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_pageSize(JNIEnv *env, sun_misc_Unsafe *this) +{ + int sz; + + sz = getpagesize(); + + return sz; +} + + +/* + * Class: sun/misc/Unsafe + * Method: defineClass + * Signature: (Ljava/lang/String;[BIILjava/lang/ClassLoader;Ljava/security/ProtectionDomain;)Ljava/lang/Class; + */ +JNIEXPORT java_lang_Class* JNICALL Java_sun_misc_Unsafe_defineClass__Ljava_lang_String_2_3BIILjava_lang_ClassLoader_2Ljava_security_ProtectionDomain_2(JNIEnv *env, sun_misc_Unsafe *this, java_lang_String *name, java_handle_bytearray_t *b, int32_t off, int32_t len, java_lang_ClassLoader *loader, java_security_ProtectionDomain *protectionDomain) +{ + classloader_t *cl; + utf *utfname; + classinfo *c; + java_lang_Class *o; + + cl = loader_hashtable_classloader_add((java_handle_t *) loader); + + /* check if data was passed */ + + if (b == NULL) { + exceptions_throw_nullpointerexception(); + return NULL; + } + + /* check the indexes passed */ + + if ((off < 0) || (len < 0) || ((off + len) > LLNI_array_size(b))) { + exceptions_throw_arrayindexoutofboundsexception(); + return NULL; + } + + if (name != NULL) { + /* convert '.' to '/' in java string */ + + utfname = javastring_toutf((java_handle_t *) name, true); + } + else { + utfname = NULL; + } + + /* define the class */ + + c = class_define(utfname, cl, len, (uint8_t *) &(LLNI_array_direct(b, off)), + (java_handle_t *) protectionDomain); + + if (c == NULL) + return NULL; + + /* for convenience */ + + o = LLNI_classinfo_wrap(c); + +#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) + /* set ProtectionDomain */ + + LLNI_field_set_ref(o, pd, protectionDomain); +#endif + + return o; +} + + +/* + * Class: sun/misc/Unsafe + * Method: allocateInstance + * Signature: (Ljava/lang/Class;)Ljava/lang/Object; + */ +JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_allocateInstance(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Class *cls) +{ + classinfo *c; + java_handle_t *o; + + c = LLNI_classinfo_unwrap(cls); + + o = builtin_new(c); + + return (java_lang_Object *) o; +} + + /* * Class: sun/misc/Unsafe * Method: throwException @@ -419,9 +1059,9 @@ JNIEXPORT void JNICALL Java_sun_misc_Unsafe_ensureClassInitialized(JNIEnv *env, */ JNIEXPORT void JNICALL Java_sun_misc_Unsafe_throwException(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Throwable *ee) { - java_objectheader *o; + java_handle_t *o; - o = (java_objectheader *) ee; + o = (java_handle_t *) ee; exceptions_set_exception(o); } @@ -434,6 +1074,7 @@ JNIEXPORT void JNICALL Java_sun_misc_Unsafe_throwException(JNIEnv *env, sun_misc */ JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_compareAndSwapObject(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, java_lang_Object *expected, java_lang_Object *x) { +#if 1 void **p; void *value; @@ -450,6 +1091,21 @@ JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_compareAndSwapObject(JNIEnv *env, } return false; +#else + volatile void **p; + void *result; + + /* XXX Use LLNI */ + + p = (volatile void **) (((uint8_t *) o) + offset); + + result = atomic_compare_and_swap_address(p, expected, x); + + if (result == expected) + return true; + + return false; +#endif } @@ -458,24 +1114,40 @@ JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_compareAndSwapObject(JNIEnv *env, * Method: compareAndSwapInt * Signature: (Ljava/lang/Object;JII)Z */ -JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_compareAndSwapInt(JNIEnv *env, sun_misc_Unsafe* this, java_lang_Object* obj, int64_t offset, int32_t expect, int32_t update) +JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_compareAndSwapInt(JNIEnv *env, sun_misc_Unsafe* this, java_lang_Object* o, int64_t offset, int32_t expected, int32_t x) { +#if 1 int32_t *p; int32_t value; - p = (int32_t *) (((uint8_t *) obj) + offset); + p = (int32_t *) (((uint8_t *) o) + offset); /* XXX this should be atomic */ value = *p; - if (value == expect) { - *p = update; + if (value == expected) { + *p = x; return true; } return false; +#else + int32_t *p; + int32_t result; + + /* XXX Use LLNI */ + + p = (int32_t *) (((uint8_t *) o) + offset); + + result = atomic_compare_and_swap_int(p, expected, x); + + if (result == expected) + return true; + + return false; +#endif } @@ -523,6 +1195,60 @@ JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_getObjectVolatile(JNIEn } +/* + * Class: sun/misc/Unsafe + * Method: putObjectVolatile + * Signature: (Ljava/lang/Object;JLjava/lang/Object;)V + */ +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putObjectVolatile(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, java_lang_Object *x) +{ + volatile void **p; + + p = (volatile void **) (((uint8_t *) o) + offset); + + *p = x; +} + + +#define UNSAFE_GET_VOLATILE(type) \ + java_handle_t *_h; \ + java_object_t *_o; \ + volatile type *_p; \ + volatile type _x; \ + \ + _h = (java_handle_t *) o; \ + \ + LLNI_CRITICAL_START; \ + \ + _o = LLNI_UNWRAP(_h); \ + _p = (volatile type *) (((uint8_t *) _o) + offset); \ + \ + _x = *_p; \ + \ + LLNI_CRITICAL_END; \ + \ + return _x; + + +#define UNSAFE_PUT_VOLATILE(type) \ + java_handle_t *_h; \ + java_object_t *_o; \ + volatile type *_p; \ + \ + _h = (java_handle_t *) o; \ + \ + LLNI_CRITICAL_START; \ + \ + _o = LLNI_UNWRAP(_h); \ + _p = (volatile type *) (((uint8_t *) _o) + offset); \ + \ + *_p = x; \ + \ + MEMORY_BARRIER(); \ + \ + LLNI_CRITICAL_END; + + /* * Class: sun/misc/Unsafe * Method: getIntVolatile @@ -530,14 +1256,114 @@ JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_getObjectVolatile(JNIEn */ JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getIntVolatile(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset) { - volatile int32_t *p; - volatile int32_t value; + UNSAFE_GET_VOLATILE(int32_t); +} - p = (volatile int32_t *) (((uint8_t *) o) + offset); - value = *p; +/* + * Class: sun/misc/Unsafe + * Method: putIntVolatile + * Signature: (Ljava/lang/Object;JI)V + */ +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putIntVolatile(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int32_t x) +{ + UNSAFE_PUT_VOLATILE(int32_t); +} - return value; + +/* + * Class: sun/misc/Unsafe + * Method: getLongVolatile + * Signature: (Ljava/lang/Object;J)J + */ +JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_getLongVolatile(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset) +{ + UNSAFE_GET_VOLATILE(int64_t); +} + + +/* + * Class: sun/misc/Unsafe + * Method: putLongVolatile + * Signature: (Ljava/lang/Object;JJ)V + */ +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putLongVolatile(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int64_t x) +{ + UNSAFE_PUT_VOLATILE(int64_t); +} + + +/* + * Class: sun/misc/Unsafe + * Method: putOrderedObject + * Signature: (Ljava/lang/Object;JLjava/lang/Object;)V + */ +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putOrderedObject(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, java_lang_Object *x) +{ + java_handle_t *_h; + java_handle_t *_hx; + java_object_t *_o; + java_object_t *_x; + volatile void **_p; + + _h = (java_handle_t *) o; + _hx = (java_handle_t *) x; + + LLNI_CRITICAL_START; + + _o = LLNI_UNWRAP(_h); + _x = LLNI_UNWRAP(_hx); + _p = (volatile void **) (((uint8_t *) _o) + offset); + + *_p = _x; + + MEMORY_BARRIER(); + + LLNI_CRITICAL_END; +} + + +/* + * Class: sun/misc/Unsafe + * Method: putOrderedInt + * Signature: (Ljava/lang/Object;JI)V + */ +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putOrderedInt(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int32_t x) +{ + UNSAFE_PUT_VOLATILE(int32_t); +} + + +/* + * Class: sun/misc/Unsafe + * Method: putOrderedLong + * Signature: (Ljava/lang/Object;JJ)V + */ +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putOrderedLong(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int64_t x) +{ + UNSAFE_PUT_VOLATILE(int64_t); +} + + +/* + * Class: sun/misc/Unsafe + * Method: unpark + * Signature: (Ljava/lang/Object;)V + */ +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_unpark(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *thread) +{ + /* XXX IMPLEMENT ME */ +} + + +/* + * Class: sun/misc/Unsafe + * Method: park + * Signature: (ZJ)V + */ +JNIEXPORT void JNICALL Java_sun_misc_Unsafe_park(JNIEnv *env, sun_misc_Unsafe *this, int32_t isAbsolute, int64_t time) +{ + /* XXX IMPLEMENT ME */ }