X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fnative%2Fjni.cpp;h=661780662a239c07a46fd157f4ccce0377900621;hb=03349a3953e0f217d686d88b99fa176509a27559;hp=c88888fed4680812a67dae23e7244ad3feb07705;hpb=5d04b5e115ff03f66de55645d385adf74dfb4be2;p=cacao.git diff --git a/src/native/jni.cpp b/src/native/jni.cpp index c88888fed..661780662 100644 --- a/src/native/jni.cpp +++ b/src/native/jni.cpp @@ -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. @@ -32,7 +32,7 @@ #include "vm/types.h" #include "mm/gc.hpp" -#include "mm/memory.h" +#include "mm/memory.hpp" #include "native/jni.hpp" #include "native/llni.h" @@ -47,19 +47,19 @@ #include "threads/mutex.hpp" #include "threads/thread.hpp" -#include "toolbox/logging.h" +#include "toolbox/logging.hpp" #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.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" @@ -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; } @@ -2071,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) \ @@ -2081,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) @@ -2104,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(); } @@ -2255,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; @@ -2302,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; @@ -2441,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) @@ -2469,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(); } @@ -2484,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()); } @@ -2547,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 */ @@ -2560,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 */ @@ -2621,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; } @@ -2689,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; } @@ -2712,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()); @@ -2727,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); } @@ -2765,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; } @@ -2781,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) { \ @@ -2800,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) /* GetArrayElements ********************************************* @@ -2825,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) @@ -2862,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: \ @@ -2905,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) @@ -2938,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) @@ -2978,14 +2979,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; } @@ -3094,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); } @@ -3121,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(); @@ -3132,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'; } @@ -3564,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; @@ -3576,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"); @@ -4125,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; }