* src/native/jni.cpp: [OPENJDK] Implemented jni_GetDirectBufferCapacity.
[cacao.git] / src / native / jni.cpp
index e0f5445d21b0e5dccdbc76ef24365e8ec0662485..661780662a239c07a46fd157f4ccce0377900621 100644 (file)
@@ -1,6 +1,6 @@
 /* src/native/jni.cpp - implementation of the Java Native Interface functions
 
-   Copyright (C) 1996-2005, 2006, 2007, 2008
+   Copyright (C) 1996-2011
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 #include "vm/types.h"
 
 #include "mm/gc.hpp"
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/jni.hpp"
 #include "native/llni.h"
-#include "native/localref.h"
-#include "native/native.h"
+#include "native/localref.hpp"
+#include "native/native.hpp"
 
 #if defined(ENABLE_JVMTI)
 # include "native/jvmti/cacaodbg.h"
 #endif
 
-#include "threads/lock-common.h"
+#include "threads/lock.hpp"
+#include "threads/mutex.hpp"
 #include "threads/thread.hpp"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
-#include "vm/array.h"
-#include "vm/builtin.h"
+#include "vm/array.hpp"
+#include "vm/jit/builtin.hpp"
 #include "vm/exceptions.hpp"
 #include "vm/global.h"
 #include "vm/globals.hpp"
-#include "vm/initialize.h"
+#include "vm/initialize.hpp"
 #include "vm/javaobjects.hpp"
-#include "vm/loader.h"
+#include "vm/loader.hpp"
 #include "vm/options.h"
 #include "vm/primitive.hpp"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 #include "vm/statistics.h"
 #include "vm/string.hpp"
 #include "vm/vm.hpp"
 
-#include "vm/jit/argument.h"
 #include "vm/jit/asmpart.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
 #include "vm/jit/stacktrace.hpp"
 
 
@@ -793,9 +793,7 @@ jint _Jv_JNI_GetVersion(JNIEnv *env)
 {
        TRACEJNICALLS(("_Jv_JNI_GetVersion(env=%p)", env));
 
-       /* We support JNI 1.6. */
-
-       return JNI_VERSION_1_6;
+       return JNI_VERSION_SUPPORTED;
 }
 
 
@@ -1448,24 +1446,21 @@ jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
 jmethodID jni_FromReflectedMethod(JNIEnv *env, jobject method)
 {
 #if defined(ENABLE_JAVASE)
-       java_handle_t* o;
        methodinfo*    m;
 
        TRACEJNICALLS(("jni_FromReflectedMethod(env=%p, method=%p)", env, method));
 
-       o = (java_handle_t *) method;
+       java_lang_Object o(method);
 
-       if (o == NULL)
+       if (o.is_null())
                return NULL;
 
-       // FIXME We can't access the object here directly.
-       if (o->vftbl->clazz == class_java_lang_reflect_Constructor) {
+       if (o.get_Class() == class_java_lang_reflect_Constructor) {
                java_lang_reflect_Constructor rc(method);
                m = rc.get_method();
        }
        else {
-               // FIXME We can't access the object here directly.
-               assert(o->vftbl->clazz == class_java_lang_reflect_Method);
+               assert(o.get_Class() == class_java_lang_reflect_Method);
 
                java_lang_reflect_Method rm(method);
                m = rm.get_method();
@@ -2074,6 +2069,8 @@ jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
 #define SET_FIELD(o,type,f,value) \
     *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset))) = (type) (value)
 
+#define GET_FIELDINFO(f) ((fieldinfo*) (f))
+
 #define JNI_SET_FIELD(name, type, intern)                                  \
 void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID,  \
                                                          type value)                                  \
@@ -2084,7 +2081,10 @@ void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID,  \
                                                                            \
        SET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID, value); \
                                                                               \
-       LLNI_CRITICAL_START;                                                   \
+       LLNI_CRITICAL_END;                                                     \
+                                                                                                                                                  \
+       if (GET_FIELDINFO(fieldID)->flags & ACC_VOLATILE)                      \
+               Atomic::memory_barrier();                                          \
 }
 
 JNI_SET_FIELD(Boolean, jboolean, s4)
@@ -2107,6 +2107,9 @@ void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
        SET_FIELD(obj, java_handle_t*, fieldID, LLNI_UNWRAP((java_handle_t*) value));
 
        LLNI_CRITICAL_END;
+
+       if (GET_FIELDINFO(fieldID)->flags & ACC_VOLATILE)
+               Atomic::memory_barrier();
 }
 
 
@@ -2258,7 +2261,7 @@ jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
        methodinfo    *m;
        java_handle_t *o;
 
-       TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
+       TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodV(env=%p, clazz=%p, methodID=%p)", env, clazz, methodID));
 
        m = (methodinfo *) methodID;
 
@@ -2305,7 +2308,7 @@ void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
 {
        methodinfo *m;
 
-       TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
+       TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodV(env=%p, clazz=%p, methodID=%p)", env, clazz, methodID));
 
        m = (methodinfo *) methodID;
 
@@ -2444,6 +2447,9 @@ void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
                        return;                                            \
                                                                \
        f->value->field = value;                                   \
+                                                                                                                          \
+       if (f->flags & ACC_VOLATILE)                               \
+               Atomic::memory_barrier();                              \
 }
 
 JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
@@ -2472,6 +2478,9 @@ void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
                        return;
 
        f->value->a = LLNI_UNWRAP((java_handle_t *) value);
+
+       if (f->flags & ACC_VOLATILE)
+               Atomic::memory_barrier();
 }
 
 
@@ -2487,22 +2496,25 @@ void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
 jstring jni_NewString(JNIEnv *env, const jchar *buf, jsize len)
 {
        TRACEJNICALLS(("jni_NewString(env=%p, buf=%p, len=%d)", env, buf, len));
-       
-       java_handle_chararray_t* a = builtin_newarray_char(len);
 
-       if (a == NULL)
+       CharArray ca(len);
+
+       if (ca.is_null())
                return NULL;
 
        /* copy text */
+
+       // XXX: Fix me!
+       uint16_t* ptr = (uint16_t*) ca.get_raw_data_ptr();
        for (jsize i = 0; i < len; i++)
-               LLNI_array_direct(a, i) = buf[i];
+               ptr[i] = buf[i];
 
        java_handle_t* h = builtin_new(class_java_lang_String);
 
        if (h == NULL)
                return NULL;
 
-       java_lang_String s(h, a, len, 0);
+       java_lang_String s(h, ca.get_handle(), len, 0);
 
        return (jstring) jni_NewLocalRef(env, (jobject) s.get_handle());
 }
@@ -2550,11 +2562,12 @@ const jchar* jni_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
 
        java_lang_String s(str);
 
-       java_handle_chararray_t* ca     = s.get_value();
-       int32_t                  count  = s.get_count();
-       int32_t                  offset = s.get_offset();
+       CharArray ca(s.get_value());
+
+       int32_t count  = s.get_count();
+       int32_t offset = s.get_offset();
        
-       if (ca == NULL)
+       if (ca.is_null())
                return NULL;
 
        /* allocate memory */
@@ -2563,8 +2576,10 @@ const jchar* jni_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
 
        /* copy text */
 
+       // XXX: Fix me!
+       uint16_t* ptr = (uint16_t*) ca.get_raw_data_ptr();
        for (i = 0; i < count; i++)
-               stringbuffer[i] = LLNI_array_direct(ca, offset + i);
+               stringbuffer[i] = ptr[offset + i];
        
        /* terminate string */
 
@@ -2624,11 +2639,12 @@ jsize jni_GetStringUTFLength(JNIEnv *env, jstring string)
        TRACEJNICALLS(("jni_GetStringUTFLength(env=%p, string=%p)", env, string));
 
        java_lang_String s(string);
-       java_handle_chararray_t* ca     = s.get_value();
-       int32_t                  count  = s.get_count();
+       CharArray        ca(s.get_value());
+       int32_t          count = s.get_count();
 
        // FIXME GC critical section!
-       int32_t length = u2_utflength(ca->data, count);
+       uint16_t* ptr = (uint16_t*) ca.get_raw_data_ptr();
+       int32_t length = u2_utflength(ptr, count);
 
        return length;
 }
@@ -2692,14 +2708,11 @@ void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
 
 jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
 {
-       java_handle_t *a;
-       jsize          size;
-
        TRACEJNICALLS(("_Jv_JNI_GetArrayLength(env=%p, array=%p)", env, array));
 
-       a = (java_handle_t *) array;
+       Array a(array);
 
-       size = LLNI_array_size(a);
+       jsize size = a.get_length();
 
        return size;
 }
@@ -2715,10 +2728,9 @@ jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
 jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
                                                                        jclass elementClass, jobject initialElement)
 {
-       classinfo                 *c;
-       java_handle_t             *o;
-       java_handle_objectarray_t *oa;
-       s4                         i;
+       classinfo*     c;
+       java_handle_t* o;
+       s4             i;
 
        STATISTICS(jniinvokation());
 
@@ -2730,36 +2742,33 @@ jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
                return NULL;
        }
 
-    oa = builtin_anewarray(length, c);
+       ObjectArray oa(length, c);
 
-       if (oa == NULL)
+       if (oa.is_null())
                return NULL;
 
        /* set all elements to initialElement */
 
        for (i = 0; i < length; i++)
-               array_objectarray_element_set(oa, i, o);
+               oa.set_element(i, o);
 
-       return (jobjectArray) jni_NewLocalRef(env, (jobject) oa);
+       return (jobjectArray) jni_NewLocalRef(env, (jobject) oa.get_handle());
 }
 
 
 jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
                                                                          jsize index)
 {
-       java_handle_objectarray_t *oa;
-       java_handle_t             *o;
-
        STATISTICS(jniinvokation());
 
-       oa = (java_handle_objectarray_t *) array;
+       ObjectArray oa(array);
 
-       if (index >= LLNI_array_size(oa)) {
+       if (index >= oa.get_length()) {
                exceptions_throw_arrayindexoutofboundsexception();
                return NULL;
        }
 
-       o = array_objectarray_element_get(oa, index);
+       java_handle_t* o = oa.get_element(index);
 
        return jni_NewLocalRef(env, (jobject) o);
 }
@@ -2768,15 +2777,11 @@ jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
 void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
                                                                   jsize index, jobject val)
 {
-       java_handle_objectarray_t *oa;
-       java_handle_t             *o;
-
        STATISTICS(jniinvokation());
 
-       oa = (java_handle_objectarray_t *) array;
-       o  = (java_handle_t *) val;
+       ObjectArray oa(array);
 
-       if (index >= LLNI_array_size(oa)) {
+       if (index >= oa.get_length()) {
                exceptions_throw_arrayindexoutofboundsexception();
                return;
        }
@@ -2784,18 +2789,18 @@ void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
        /* check if the class of value is a subclass of the element class
           of the array */
 
-       if (!builtin_canstore(oa, o))
+       java_handle_t* o  = (java_handle_t *) val;
+
+       if (!builtin_canstore(oa.get_handle(), o))
                return;
 
-       array_objectarray_element_set(oa, index, o);
+       oa.set_element(index, o);
 }
 
 
-#define JNI_NEW_ARRAY(name, type, intern)                \
+#define JNI_NEW_ARRAY(name, type)                        \
 type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len)    \
 {                                                        \
-       java_handle_##intern##array_t *a;                    \
-                                                         \
        STATISTICS(jniinvokation());                         \
                                                          \
        if (len < 0) {                                       \
@@ -2803,19 +2808,20 @@ type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len)    \
                return NULL;                                     \
        }                                                    \
                                                          \
-       a = builtin_newarray_##intern(len);                  \
+       name##Array a(len);                                  \
                                                          \
-       return (type) jni_NewLocalRef(env, (jobject) a); \
+       return (type) jni_NewLocalRef(env,                   \
+                       (jobject) a.get_handle());                   \
 }
 
-JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
-JNI_NEW_ARRAY(Byte,    jbyteArray,    byte)
-JNI_NEW_ARRAY(Char,    jcharArray,    char)
-JNI_NEW_ARRAY(Short,   jshortArray,   short)
-JNI_NEW_ARRAY(Int,     jintArray,     int)
-JNI_NEW_ARRAY(Long,    jlongArray,    long)
-JNI_NEW_ARRAY(Float,   jfloatArray,   float)
-JNI_NEW_ARRAY(Double,  jdoubleArray,  double)
+JNI_NEW_ARRAY(Boolean, jbooleanArray)
+JNI_NEW_ARRAY(Byte,    jbyteArray)
+JNI_NEW_ARRAY(Char,    jcharArray)
+JNI_NEW_ARRAY(Short,   jshortArray)
+JNI_NEW_ARRAY(Int,     jintArray)
+JNI_NEW_ARRAY(Long,    jlongArray)
+JNI_NEW_ARRAY(Float,   jfloatArray)
+JNI_NEW_ARRAY(Double,  jdoubleArray)
 
 
 /* Get<PrimitiveType>ArrayElements *********************************************
@@ -2828,16 +2834,14 @@ JNI_NEW_ARRAY(Double,  jdoubleArray,  double)
 type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
                                                                                 jboolean *isCopy)             \
 {                                                                      \
-       java_handle_##intern##array_t *a;                                  \
-                                                                       \
        TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayElements(env=%p, array=%p, isCopy=%d)", env, array, isCopy)); \
                                                                        \
-       a = (java_handle_##intern##array_t *) array;                       \
+       name##Array a(array);                                              \
                                                                        \
        if (isCopy)                                                        \
                *isCopy = JNI_FALSE;                                           \
                                                                        \
-       return (type *) LLNI_array_data(a);                                \
+       return (type *) a.get_raw_data_ptr();                              \
 }
 
 JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
@@ -2865,19 +2869,17 @@ JNI_GET_ARRAY_ELEMENTS(Double,  jdouble,  double)
 void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array,  \
                                                                                  type *elems, jint mode)          \
 {                                                                          \
-       java_handle_##intern##array_t *a;                                      \
-                                                                           \
        STATISTICS(jniinvokation());                                           \
                                                                            \
-       a = (java_handle_##intern##array_t *) array;                           \
+       name##Array a(array);                                                  \
                                                                            \
-       if (elems != (type *) LLNI_array_data(a)) {                            \
+       if (elems != (type *) a.get_raw_data_ptr()) {                          \
                switch (mode) {                                                    \
                case JNI_COMMIT:                                                   \
-                       MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
+                       a.set_region(0, a.get_length(), (intern2 *) elems);            \
                        break;                                                         \
                case 0:                                                            \
-                       MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
+                       a.set_region(0, a.get_length(), (intern2 *) elems);            \
                        /* XXX TWISTI how should it be freed? */                       \
                        break;                                                         \
                case JNI_ABORT:                                                    \
@@ -2908,16 +2910,14 @@ JNI_RELEASE_ARRAY_ELEMENTS(Double,  jdouble,  double,  double)
 void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array,     \
                                                                        jsize start, jsize len, type *buf)  \
 {                                                                       \
-       java_handle_##intern##array_t *a;                                   \
-                                                                        \
        TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayRegion(env=%p, array=%p, start=%d, len=%d, buf=%p)", env, array, start, len, buf)); \
                                                                         \
-       a = (java_handle_##intern##array_t *) array;                        \
+       name##Array a(array);                                               \
                                                                         \
-       if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
+       if ((start < 0) || (len < 0) || (start + len > a.get_length()))     \
                exceptions_throw_arrayindexoutofboundsexception();              \
        else                                                                \
-               MCOPY(buf, &LLNI_array_direct(a, start), intern2, len);         \
+               a.get_region(start, len, (intern2 *) buf);                      \
 }
 
 JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
@@ -2941,16 +2941,14 @@ JNI_GET_ARRAY_REGION(Double,  jdouble,  double,  double)
 void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array,          \
                                                                        jsize start, jsize len, const type *buf) \
 {                                                                            \
-       java_handle_##intern##array_t *a;                                        \
-                                                                             \
        STATISTICS(jniinvokation());                                             \
                                                                              \
-       a = (java_handle_##intern##array_t *) array;                             \
+       name##Array a(array);                                                    \
                                                                              \
-       if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a)))      \
+       if ((start < 0) || (len < 0) || (start + len > a.get_length()))          \
                exceptions_throw_arrayindexoutofboundsexception();                   \
        else                                                                     \
-               MCOPY(&LLNI_array_direct(a, start), buf, intern2, len);              \
+               a.set_region(start, len, (intern2 *) buf);                           \
 }
 
 JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
@@ -2975,22 +2973,16 @@ JNI_SET_ARRAY_REGION(Double,  jdouble,  double,  double)
 
 *******************************************************************************/
 
-jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
-                                                        const JNINativeMethod *methods, jint nMethods)
+jint jni_RegisterNatives(JNIEnv* env, jclass clazz, const JNINativeMethod* methods, jint nMethods)
 {
-       classinfo *c;
+       TRACEJNICALLS(("jni_RegisterNatives(env=%p, clazz=%p, methods=%p, nMethods=%d)", env, clazz, methods, nMethods));
 
-       STATISTICS(jniinvokation());
+       classinfo* c = LLNI_classinfo_unwrap(clazz);
 
-       c = LLNI_classinfo_unwrap(clazz);
-
-       /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
-       if (jvmti) jvmti_NativeMethodBind(method, address,  new_address_ptr);
-       */
+       NativeMethods& nm = VM::get_current()->get_nativemethods();
+       nm.register_methods(c->name, methods, nMethods);
 
-       native_method_register(c->name, methods, nMethods);
-
-    return 0;
+       return 0;
 }
 
 
@@ -3081,7 +3073,7 @@ jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **javavm)
 {
        STATISTICS(jniinvokation());
 
-    *javavm = vm->get_javavm();
+    *javavm = VM::get_current()->get_javavm();
 
        return 0;
 }
@@ -3099,15 +3091,15 @@ jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **javavm)
 void jni_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
 {
        java_lang_String s(str);
-       java_handle_chararray_t* ca    = s.get_value();
-       int32_t                  count = s.get_count();
+       CharArray        ca(s.get_value());
+       int32_t          count = s.get_count();
 
        if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
                exceptions_throw_stringindexoutofboundsexception();
                return;
        }
 
-       MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
+       ca.get_region(start, len, buf);
 }
 
 
@@ -3126,9 +3118,11 @@ void jni_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start, jsize len, ch
        TRACEJNICALLS(("jni_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf));
 
        java_lang_String s(str);
-       java_handle_chararray_t* ca     = s.get_value();
-       int32_t                  count  = s.get_count();
-       int32_t                  offset = s.get_offset();
+
+       CharArray ca(s.get_value());
+
+       int32_t count  = s.get_count();
+       int32_t offset = s.get_offset();
 
        if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
                exceptions_throw_stringindexoutofboundsexception();
@@ -3137,8 +3131,10 @@ void jni_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start, jsize len, ch
 
        int32_t i;
 
+       // XXX: Fix me!
+       uint16_t* ptr = (uint16_t*) ca.get_raw_data_ptr();
        for (i = 0; i < len; i++)
-               buf[i] = LLNI_array_direct(ca, offset + start + i);
+               buf[i] = ptr[offset + start + i];
 
        buf[i] = '\0';
 }
@@ -3244,7 +3240,7 @@ void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
    argument.
 
 *******************************************************************************/
-    
+
 jobject jni_NewGlobalRef(JNIEnv* env, jobject obj)
 {
        hashtable_global_ref_entry *gre;
@@ -3256,7 +3252,7 @@ jobject jni_NewGlobalRef(JNIEnv* env, jobject obj)
 
        o = (java_handle_t *) obj;
 
-       LOCK_MONITOR_ENTER(hashtable_global_ref->header);
+       hashtable_global_ref->mutex->lock();
 
        LLNI_CRITICAL_START;
 
@@ -3311,7 +3307,7 @@ jobject jni_NewGlobalRef(JNIEnv* env, jobject obj)
                hashtable_global_ref->entries++;
        }
 
-       LOCK_MONITOR_EXIT(hashtable_global_ref->header);
+       hashtable_global_ref->mutex->unlock();
 
 #if defined(ENABLE_HANDLES)
        return gre;
@@ -3339,7 +3335,7 @@ void jni_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
 
        o = (java_handle_t *) globalRef;
 
-       LOCK_MONITOR_ENTER(hashtable_global_ref->header);
+       hashtable_global_ref->mutex->lock();
 
        LLNI_CRITICAL_START;
 
@@ -3382,7 +3378,7 @@ void jni_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
 
                        LLNI_CRITICAL_END;
 
-                       LOCK_MONITOR_EXIT(hashtable_global_ref->header);
+                       hashtable_global_ref->mutex->unlock();
 
                        return;
                }
@@ -3395,7 +3391,7 @@ void jni_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
 
        LLNI_CRITICAL_END;
 
-       LOCK_MONITOR_EXIT(hashtable_global_ref->header);
+       hashtable_global_ref->mutex->unlock();
 }
 
 
@@ -3569,7 +3565,8 @@ void* jni_GetDirectBufferAddress(JNIEnv *env, jobject buf)
 
 jlong jni_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
 {
-#if defined(ENABLE_JAVASE) && defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+#if defined(ENABLE_JAVASE)
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
        TRACEJNICALLS(("jni_GetDirectBufferCapacity(env=%p, buf=%p)", env, buf));
 
        java_handle_t* h = (java_handle_t *) buf;
@@ -3581,6 +3578,23 @@ jlong jni_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
        jlong capacity = b.get_cap();
 
        return capacity;
+# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+
+       TRACEJNICALLS(("jni_GetDirectBufferCapacity(env=%p, buf=%p)", env, buf));
+
+       java_nio_Buffer jnb(buf);
+
+       if (!builtin_instanceof(jnb.get_handle(), class_sun_nio_ch_DirectBuffer))
+               return -1;
+
+       jlong capacity = jnb.get_capacity();
+
+       return capacity;
+
+# else
+#  error unknown classpath configuration
+# endif
+
 #else
        vm_abort("jni_GetDirectBufferCapacity: not implemented in this configuration");
 
@@ -3621,7 +3635,7 @@ jint _Jv_JNI_DestroyJavaVM(JavaVM *javavm)
 
        TRACEJNICALLS(("_Jv_JNI_DestroyJavaVM(javavm=%p)", javavm));
 
-       if (vm->is_created() == false)
+       if (VM::get_current()->is_created() == false)
                return JNI_ERR;
 
     status = vm_destroy(javavm);
@@ -3656,7 +3670,7 @@ static int jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon
        result = thread_current_is_attached();
 
        if (result == true) {
-               *p_env = vm->get_jnienv();
+               *p_env = VM::get_current()->get_jnienv();
                return JNI_OK;
        }
 
@@ -3675,7 +3689,7 @@ static int jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon
                return JNI_ERR;
 #endif
 
-       *p_env = vm->get_jnienv();
+       *p_env = VM::get_current()->get_jnienv();
 
        return JNI_OK;
 }
@@ -3687,7 +3701,7 @@ jint jni_AttachCurrentThread(JavaVM *javavm, void **p_env, void *thr_args)
 
        TRACEJNICALLS(("jni_AttachCurrentThread(javavm=%p, p_env=%p, thr_args=%p)", javavm, p_env, thr_args));
 
-       if (vm->is_created() == false)
+       if (VM::get_current()->is_created() == false)
                return JNI_ERR;
 
        result = jni_attach_current_thread(p_env, thr_args, false);
@@ -3756,7 +3770,7 @@ jint jni_GetEnv(JavaVM *javavm, void **env, jint version)
 {
        TRACEJNICALLS(("jni_GetEnv(javavm=%p, env=%p, version=%d)", javavm, env, version));
 
-       if (vm->is_created() == false) {
+       if (VM::get_current()->is_created() == false) {
                *env = NULL;
                return JNI_EDETACHED;
        }
@@ -3772,7 +3786,7 @@ jint jni_GetEnv(JavaVM *javavm, void **env, jint version)
        /* Check the JNI version. */
 
        if (jni_version_check(version) == true) {
-               *env = vm->get_jnienv();
+               *env = VM::get_current()->get_jnienv();
                return JNI_OK;
        }
 
@@ -3812,7 +3826,7 @@ jint jni_AttachCurrentThreadAsDaemon(JavaVM *javavm, void **penv, void *args)
 
        TRACEJNICALLS(("jni_AttachCurrentThreadAsDaemon(javavm=%p, penv=%p, args=%p)", javavm, penv, args));
 
-       if (vm->is_created() == false)
+       if (VM::get_current()->is_created() == false)
                return JNI_ERR;
 
        result = jni_attach_current_thread(penv, args, true);
@@ -4077,7 +4091,7 @@ struct JNINativeInterface_ _Jv_JNINativeInterface = {
        _Jv_JNI_SetFloatArrayRegion,
        _Jv_JNI_SetDoubleArrayRegion,
 
-       _Jv_JNI_RegisterNatives,
+       jni_RegisterNatives,
        _Jv_JNI_UnregisterNatives,
 
        _Jv_JNI_MonitorEnter,
@@ -4130,22 +4144,28 @@ jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
        /* GNU classpath currently supports JNI 1.2 */
 
        switch (_vm_args->version) {
-    case JNI_VERSION_1_1:
+       case JNI_VERSION_1_1:
                _vm_args->version = JNI_VERSION_1_1;
                break;
 
-    case JNI_VERSION_1_2:
-    case JNI_VERSION_1_4:
+       case JNI_VERSION_1_2:
+       case JNI_VERSION_1_4:
                _vm_args->ignoreUnrecognized = JNI_FALSE;
                _vm_args->options = NULL;
                _vm_args->nOptions = 0;
                break;
 
-    default:
-               return -1;
+       case JNI_VERSION_CACAO:
+               // We reveal ourselves by accepting this version number,
+               // this actually means we are using the supported JNI version.
+               _vm_args->version = JNI_VERSION_SUPPORTED;
+               break;
+
+       default:
+               return JNI_ERR;
        }
-  
-       return 0;
+
+       return JNI_OK;
 }
 
 
@@ -4167,7 +4187,7 @@ jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
 
        // We currently only support 1 VM running.
 
-       vmBuf[0] = vm->get_javavm();
+       vmBuf[0] = VM::get_current()->get_javavm();
        *nVMs    = 1;
 
     return JNI_OK;