* Removed all Id tags.
[cacao.git] / src / native / vm / sun_misc_Unsafe.c
index 82c54860ec76022bf9aa27f75891bdb8887c0e0c..8d715faeb1d95fffb4c0466dbce68b830ba13353 100644 (file)
    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 <stdint.h>
+#include <unistd.h>
+
+#include "mm/memory.h"
 
 #include "native/jni.h"
+#include "native/llni.h"
 #include "native/native.h"
 
-#include "native/include/java_lang_Object.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)
+# include "native/include/java_nio_ByteBuffer.h"        /* required by j.l.CL */
+#endif
+
+#include "native/include/java_lang_ClassLoader.h"        /* required by j.l.C */
+#include "native/include/java_lang_Class.h"
 #include "native/include/java_lang_reflect_Field.h"
 #include "native/include/java_lang_Thread.h"             /* required by s.m.U */
+#include "native/include/java_lang_Throwable.h"
+
+#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/utf8.h"
 
 
 /* native methods implemented by this file ************************************/
 
 static JNINativeMethod methods[] = {
-       { "objectFieldOffset",    "(Ljava/lang/reflect/Field;)J",                               (void *) (intptr_t) &Java_sun_misc_Unsafe_objectFieldOffset    },
-       { "compareAndSwapInt",    "(Ljava/lang/Object;JII)Z",                                   (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapInt    },
-#if 0
-       { "compareAndSwapLong",   "(Ljava/lang/Object;JJJ)Z",                                   (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapLong   },
-       { "compareAndSwapObject", "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z", (void *) (intptr_t) &Java_sun_misc_Unsafe_compareAndSwapObject },
-       { "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       },
-       { "putOrderedObject",     "(Ljava/lang/Object;JLjava/lang/Object;)V",                   (void *) (intptr_t) &Java_sun_misc_Unsafe_putOrderedObject     },
-       { "putIntVolatile",       "(Ljava/lang/Object;JI)V",                                    (void *) (intptr_t) &Java_sun_misc_Unsafe_putIntVolatile       },
-       { "getIntVolatile",       "(Ljava/lang/Object;J)I",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getIntVolatile       },
-       { "putLongVolatile",      "(Ljava/lang/Object;JJ)V",                                    (void *) (intptr_t) &Java_sun_misc_Unsafe_putLongVolatile      },
-       { "putLong",              "(Ljava/lang/Object;JJ)V",                                    (void *) (intptr_t) &Java_sun_misc_Unsafe_putLong              },
-       { "getLongVolatile",      "(Ljava/lang/Object;J)J",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getLongVolatile      },
-       { "getLong",              "(Ljava/lang/Object;J)J",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getLong              },
-       { "putObjectVolatile",    "(Ljava/lang/Object;JLjava/lang/Object;)V",                   (void *) (intptr_t) &Java_sun_misc_Unsafe_putObjectVolatile    },
-       { "putObject",            "(Ljava/lang/Object;JLjava/lang/Object;)V",                   (void *) (intptr_t) &Java_sun_misc_Unsafe_putObject            },
-       { "getObjectVolatile",    "(Ljava/lang/Object;J)Ljava/lang/Object;",                    (void *) (intptr_t) &Java_sun_misc_Unsafe_getObjectVolatile    },
-       { "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      },
-       { "unpark",               "(Ljava/lang/Thread;)V",                                      (void *) (intptr_t) &Java_sun_misc_Unsafe_unpark               },
-       { "park",                 "(ZJ)V",                                                      (void *) (intptr_t) &Java_sun_misc_Unsafe_park                 },
-#endif
+       { "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 },
+       { "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 },
+       { "putFloat",               "(Ljava/lang/Object;JF)V",                                    (void *) (intptr_t) &Java_sun_misc_Unsafe_putFloat__Ljava_lang_Object_2JF },
+       { "getByte",                "(J)B",                                                       (void *) (intptr_t) &Java_sun_misc_Unsafe_getByte__J                     },
+       { "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                    },
+       { "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                 },
+       { "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              },
+       { "getIntVolatile",         "(Ljava/lang/Object;J)I",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getIntVolatile                 },
+       { "getLongVolatile",        "(Ljava/lang/Object;J)J",                                     (void *) (intptr_t) &Java_sun_misc_Unsafe_getLongVolatile                },
+       { "unpark",                 "(Ljava/lang/Object;)V",                                      (void *) (intptr_t) &Java_sun_misc_Unsafe_unpark                         },
+       { "park",                   "(ZJ)V",                                                      (void *) (intptr_t) &Java_sun_misc_Unsafe_park                           },
 };
 
 
@@ -89,185 +124,403 @@ void _Jv_sun_misc_Unsafe_init(void)
 
 /*
  * Class:     sun/misc/Unsafe
- * Method:    objectFieldOffset
- * Signature: (Ljava/lang/reflect/Field;)J
+ * Method:    registerNatives
+ * Signature: ()V
  */
-JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_objectFieldOffset(JNIEnv *env, sun_misc_Unsafe* this, java_lang_reflect_Field* field)
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_registerNatives(JNIEnv *env, jclass clazz)
 {
-       classinfo *c;
-       fieldinfo *f;
+       /* The native methods of this function are already registered in
+          _Jv_sun_misc_Unsafe_init() which is called during VM
+          startup. */
+}
 
-       c = (classinfo *) field->declaringClass;
-       f = &c->fields[field->slot];
 
-       return (int64_t) f->offset;
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    getInt
+ * Signature: (Ljava/lang/Object;J)I
+ */
+JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getInt__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:    compareAndSwapInt
- * Signature: (Ljava/lang/Object;JII)Z
+ * Method:    putInt
+ * Signature: (Ljava/lang/Object;JI)V
  */
-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 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
+ * Signature: (Ljava/lang/Object;J)Z
+ */
+JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getBoolean(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
 {
        int32_t *p;
        int32_t  value;
 
-       p = (int32_t *) (((u1 *) obj) + offset);
+       p = (int32_t *) (((uint8_t *) o) + offset);
+
+       value = *p;
+
+       return value;
+}
 
-       /* XXX this should be atomic */
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    putBoolean
+ * Signature: (Ljava/lang/Object;JZ)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putBoolean(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:    getByte
+ * Signature: (Ljava/lang/Object;J)B
+ */
+JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getByte__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;
 
-       if (value == expect) {
-               *p = update;
+       return value;
+}
 
-               return true;
-       }
 
-       return false;
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    putByte
+ * Signature: (Ljava/lang/Object;JB)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putByte__Ljava_lang_Object_2JB(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;
 }
 
 
-#if 0
 /*
  * Class:     sun/misc/Unsafe
- * Method:    compareAndSwapLong
- * Signature: (Ljava/lang/Object;JJJ)Z
+ * Method:    putShort
+ * Signature: (Ljava/lang/Object;JS)V
  */
-JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_compareAndSwapLong(JNIEnv *env, struct sun_misc_Unsafe* this, struct java_lang_Object* par1, int64_t par2, int64_t par3, int64_t par4)
+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:    compareAndSwapObject
- * Signature: (Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z
+ * Method:    getChar
+ * Signature: (Ljava/lang/Object;J)C
  */
-JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_compareAndSwapObject(JNIEnv *env, struct sun_misc_Unsafe* this, struct java_lang_Object* par1, int64_t par2, struct java_lang_Object* par3, struct java_lang_Object* par4)
+JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getChar__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:    putOrderedInt
- * Signature: (Ljava/lang/Object;JI)V
+ * Method:    putChar
+ * Signature: (Ljava/lang/Object;JC)V
  */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putOrderedInt(JNIEnv *env, struct sun_misc_Unsafe* this, struct java_lang_Object* par1, int64_t par2, int32_t par3)
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putChar__Ljava_lang_Object_2JC(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:    putOrderedLong
- * Signature: (Ljava/lang/Object;JJ)V
+ * Method:    putFloat
+ * Signature: (Ljava/lang/Object;JF)V
  */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putOrderedLong(JNIEnv *env, struct sun_misc_Unsafe* this, struct java_lang_Object* par1, int64_t par2, int64_t par3)
+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:    putOrderedObject
- * Signature: (Ljava/lang/Object;JLjava/lang/Object;)V
+ * Method:    getByte
+ * Signature: (J)B
  */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putOrderedObject(JNIEnv *env, struct sun_misc_Unsafe* this, struct java_lang_Object* par1, int64_t par2, struct java_lang_Object* par3)
+JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getByte__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
 {
+       int8_t *p;
+       int8_t  value;
+
+       p = (int8_t *) (intptr_t) address;
+
+       value = *p;
+
+       return (int32_t) value;
 }
 
 
 /*
  * Class:     sun/misc/Unsafe
- * Method:    putIntVolatile
- * Signature: (Ljava/lang/Object;JI)V
+ * Method:    getInt
+ * Signature: (J)I
  */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putIntVolatile(JNIEnv *env, struct sun_misc_Unsafe* this, struct java_lang_Object* par1, int64_t par2, int32_t par3)
+JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getInt__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
 {
+       int32_t *p;
+       int32_t  value;
+
+       p = (int32_t *) (intptr_t) address;
+
+       value = *p;
+
+       return value;
 }
 
 
 /*
  * Class:     sun/misc/Unsafe
- * Method:    getIntVolatile
- * Signature: (Ljava/lang/Object;J)I
+ * Method:    putInt
+ * Signature: (JI)V
  */
-JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_getIntVolatile(JNIEnv *env, struct sun_misc_Unsafe* this, struct java_lang_Object* par1, int64_t par2)
+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:    putLongVolatile
- * Signature: (Ljava/lang/Object;JJ)V
+ * Method:    getLong
+ * Signature: (J)J
  */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putLongVolatile(JNIEnv *env, struct sun_misc_Unsafe* this, struct java_lang_Object* par1, int64_t par2, int64_t par3)
+JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_getLong__J(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
 {
+       int64_t *p;
+       int64_t  value;
+
+       p = (int64_t *) (intptr_t) address;
+
+       value = *p;
+
+       return value;
 }
 
 
 /*
  * Class:     sun/misc/Unsafe
  * Method:    putLong
- * Signature: (Ljava/lang/Object;JJ)V
+ * Signature: (JJ)V
  */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putLong(JNIEnv *env, struct sun_misc_Unsafe* this, struct java_lang_Object* par1, int64_t par2, int64_t par3)
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putLong__JJ(JNIEnv *env, sun_misc_Unsafe *this, int64_t address, int64_t value)
 {
+       int64_t *p;
+
+       p = (int64_t *) (intptr_t) address;
+
+       *p = value;
 }
 
 
 /*
  * Class:     sun/misc/Unsafe
- * Method:    getLongVolatile
- * Signature: (Ljava/lang/Object;J)J
+ * Method:    objectFieldOffset
+ * Signature: (Ljava/lang/reflect/Field;)J
  */
-JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_getLongVolatile(JNIEnv *env, struct sun_misc_Unsafe* this, struct java_lang_Object* par1, int64_t par2)
+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;
+
+       LLNI_field_get_cls(field, clazz, c);
+       LLNI_field_get_val(field, slot , slot);
+       f = &c->fields[slot];
+
+       return (int64_t) f->offset;
 }
 
 
 /*
  * Class:     sun/misc/Unsafe
- * Method:    getLong
- * Signature: (Ljava/lang/Object;J)J
+ * Method:    allocateMemory
+ * Signature: (J)J
  */
-JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_getLong(JNIEnv *env, struct sun_misc_Unsafe* this, struct java_lang_Object* par1, int64_t par2)
+JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_allocateMemory(JNIEnv *env, sun_misc_Unsafe *this, int64_t bytes)
 {
+       size_t  length;
+       void   *p;
+
+       length = (size_t) bytes;
+
+       if ((length != (uint64_t) bytes) || (bytes < 0)) {
+               exceptions_throw_illegalargumentexception();
+               return 0;
+       }
+
+       p = MNEW(uint8_t, length);
+
+       return (int64_t) (intptr_t) p;
 }
 
 
 /*
  * Class:     sun/misc/Unsafe
- * Method:    putObjectVolatile
- * Signature: (Ljava/lang/Object;JLjava/lang/Object;)V
+ * Method:    freeMemory
+ * Signature: (J)V
  */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putObjectVolatile(JNIEnv *env, struct sun_misc_Unsafe* this, struct java_lang_Object* par1, int64_t par2, struct java_lang_Object* par3)
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_freeMemory(JNIEnv *env, sun_misc_Unsafe *this, int64_t address)
 {
+       void *p;
+
+       p = (void *) (intptr_t) address;
+
+       if (p == NULL)
+               return;
+
+       /* we pass length 1 to trick the free function */
+
+       MFREE(p, uint8_t, 1);
 }
 
 
 /*
  * Class:     sun/misc/Unsafe
- * Method:    putObject
- * Signature: (Ljava/lang/Object;JLjava/lang/Object;)V
+ * Method:    staticFieldOffset
+ * Signature: (Ljava/lang/reflect/Field;)J
  */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putObject(JNIEnv *env, struct sun_misc_Unsafe* this, struct java_lang_Object* par1, int64_t par2, struct java_lang_Object* par3)
+JNIEXPORT int64_t JNICALL Java_sun_misc_Unsafe_staticFieldOffset(JNIEnv *env, sun_misc_Unsafe *this, java_lang_reflect_Field *field)
 {
+       classinfo *c;
+       fieldinfo *f;
+       int32_t    slot;
+
+       LLNI_field_get_cls(field, clazz, c);
+       LLNI_field_get_val(field, slot , slot);
+       f = &(c->fields[slot]);
+
+       return (int64_t) (intptr_t) f->value;
 }
 
 
 /*
  * Class:     sun/misc/Unsafe
- * Method:    getObjectVolatile
- * Signature: (Ljava/lang/Object;J)Ljava/lang/Object;
+ * 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)
+{
+       /* In CACAO we return the absolute address in staticFieldOffset. */
+
+       return NULL;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    ensureClassInitialized
+ * Signature: (Ljava/lang/Class;)V
  */
-JNIEXPORT struct java_lang_Object* JNICALL Java_sun_misc_Unsafe_getObjectVolatile(JNIEnv *env, struct sun_misc_Unsafe* this, struct java_lang_Object* par1, int64_t par2)
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_ensureClassInitialized(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Class *class)
 {
+       classinfo *c;
+
+       c = LLNI_classinfo_unwrap(class);
+
+       if (!(c->state & CLASS_INITIALIZED))
+               initialize_class(c);
 }
 
 
@@ -276,8 +529,21 @@ JNIEXPORT struct java_lang_Object* JNICALL Java_sun_misc_Unsafe_getObjectVolatil
  * Method:    arrayBaseOffset
  * Signature: (Ljava/lang/Class;)I
  */
-JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_arrayBaseOffset(JNIEnv *env, struct sun_misc_Unsafe* this, struct java_lang_Class* par1)
+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;
 }
 
 
@@ -286,18 +552,282 @@ JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_arrayBaseOffset(JNIEnv *env, stru
  * Method:    arrayIndexScale
  * Signature: (Ljava/lang/Class;)I
  */
-JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_arrayIndexScale(JNIEnv *env, struct sun_misc_Unsafe* this, struct java_lang_Class* par1)
+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     *cl;
+       utf             *utfname;
+       classinfo       *c;
+       java_lang_Class *o;
+
+       cl = (classloader *) 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, (const uint8_t *) &b->data[off],
+                                        protectionDomain);
+
+       if (c == NULL)
+               return NULL;
+
+       /* for convenience */
+
+       o = LLNI_classinfo_wrap(c);
+
+#if defined(WITH_CLASSPATH_GNU)
+       /* 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_object_t *o;
+
+       c = LLNI_classinfo_unwrap(cls);
+
+       o = builtin_new(c);
+
+       return (java_lang_Object *) o;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    throwException
+ * Signature: (Ljava/lang/Throwable;)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_throwException(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Throwable *ee)
+{
+       java_handle_t *o;
+
+       o = (java_handle_t *) ee;
+
+       exceptions_set_exception(o);
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    compareAndSwapObject
+ * Signature: (Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z
+ */
+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)
+{
+       void **p;
+       void  *value;
+
+       p = (void **) (((uint8_t *) o) + offset);
+
+       /* XXX this should be atomic */
+
+       value = *p;
+
+       if (value == expected) {
+               *p = x;
+
+               return true;
+       }
+
+       return false;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * 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)
+{
+       int32_t *p;
+       int32_t  value;
+
+       p = (int32_t *) (((uint8_t *) obj) + offset);
+
+       /* XXX this should be atomic */
+
+       value = *p;
+
+       if (value == expect) {
+               *p = update;
+
+               return true;
+       }
+
+       return false;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    compareAndSwapLong
+ * Signature: (Ljava/lang/Object;JJJ)Z
+ */
+JNIEXPORT int32_t JNICALL Java_sun_misc_Unsafe_compareAndSwapLong(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset, int64_t expected, int64_t x)
+{
+       int64_t *p;
+       int64_t  value;
+
+       p = (int64_t *) (((uint8_t *) o) + offset);
+
+       /* XXX this should be atomic */
+
+       value = *p;
+
+       if (value == expected) {
+               *p = x;
+
+               return true;
+       }
+
+       return false;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    getObjectVolatile
+ * Signature: (Ljava/lang/Object;J)Ljava/lang/Object;
+ */
+JNIEXPORT java_lang_Object* JNICALL Java_sun_misc_Unsafe_getObjectVolatile(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *o, int64_t offset)
+{
+       volatile void **p;
+       volatile void  *value;
+
+       p = (volatile void **) (((uint8_t *) o) + offset);
+
+       value = *p;
+
+       return (java_lang_Object *) value;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    getIntVolatile
+ * Signature: (Ljava/lang/Object;J)I
+ */
+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;
+
+       p = (volatile int32_t *) (((uint8_t *) o) + offset);
+
+       value = *p;
+
+       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)
+{
+       volatile int64_t *p;
+       volatile int64_t  value;
+
+       p = (volatile int64_t *) (((uint8_t *) o) + offset);
+
+       value = *p;
+
+       return value;
 }
 
 
 /*
  * Class:     sun/misc/Unsafe
  * Method:    unpark
- * Signature: (Ljava/lang/Thread;)V
+ * Signature: (Ljava/lang/Object;)V
  */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_unpark(JNIEnv *env, struct sun_misc_Unsafe* this, struct java_lang_Thread* par1)
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_unpark(JNIEnv *env, sun_misc_Unsafe *this, java_lang_Object *thread)
 {
+       /* XXX IMPLEMENT ME */
 }
 
 
@@ -306,10 +836,10 @@ JNIEXPORT void JNICALL Java_sun_misc_Unsafe_unpark(JNIEnv *env, struct sun_misc_
  * Method:    park
  * Signature: (ZJ)V
  */
-JNIEXPORT void JNICALL Java_sun_misc_Unsafe_park(JNIEnv *env, struct sun_misc_Unsafe* this, int32_t par1, int64_t par2)
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_park(JNIEnv *env, sun_misc_Unsafe *this, int32_t isAbsolute, int64_t time)
 {
+       /* XXX IMPLEMENT ME */
 }
-#endif
 
 
 /*