* src/native/jni.cpp (GetObjectClass): Remove null pointer check.
[cacao.git] / src / native / jni.cpp
index d33892469c10a7621c96efdc14b6e8dd2a921708..bf1401a65938524be30623e3d156548fbdf9a221 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-2012
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
@@ -881,8 +881,31 @@ jclass jni_FindClass(JNIEnv *env, const char *name)
 
        if (cc == NULL)
                c = load_class_from_sysloader(u);
-       else
-               c = load_class_from_classloader(u, cc->classloader);
+       else {
+               classloader_t *cl = cc->classloader;
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+               /* See jni_FindClass in Hotspot's src/share/vm/prims/jni.cpp */
+               if (!cl && cc->name == utf_java_lang_ClassLoader_NativeLibrary)
+               {
+                       methodinfo *m = class_resolveclassmethod(
+                               cc,
+                               utf_new_char("getFromClass"),
+                               utf_new_char("()Ljava/lang/Class;"),
+                               NULL,
+                               true);
+
+                       java_handle_t *h;
+                       if (m)
+                               h = vm_call_method(m, NULL);
+
+                       if (m && exceptions_get_exception() == NULL)
+                               cl = ((classinfo *) LLNI_UNWRAP(h))->classloader;
+                       else
+                               return NULL;
+               }
+#endif
+               c = load_class_from_classloader(u, cl);
+       }
 
        if (c == NULL) {
                resolve_handle_pending_exception(true);
@@ -1402,9 +1425,6 @@ jclass jni_GetObjectClass(JNIEnv *env, jobject obj)
 
        o = (java_handle_t *) obj;
 
-       if ((o == NULL) || (LLNI_vftbl_direct(o) == NULL))
-               return NULL;
-
        LLNI_class_get(o, c);
 
        java_handle_t* h = LLNI_classinfo_wrap(c);
@@ -2069,6 +2089,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)                                  \
@@ -2079,7 +2101,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)
@@ -2102,6 +2127,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();
 }
 
 
@@ -2253,7 +2281,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;
 
@@ -2300,7 +2328,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;
 
@@ -2439,6 +2467,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)
@@ -2467,6 +2498,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();
 }
 
 
@@ -2965,14 +2999,10 @@ jint jni_RegisterNatives(JNIEnv* env, jclass clazz, const JNINativeMethod* metho
 
        classinfo* 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);
 
-    return 0;
+       return 0;
 }
 
 
@@ -3555,7 +3585,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;
@@ -3567,6 +3598,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");