/* src/native/jni.c - implementation of the Java Native Interface functions
- Copyright (C) 1996-2005, 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) 1996-2005, 2006, 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: jni.c 8391 2007-08-21 20:34:27Z michi $
-
*/
#include "vm/types.h"
-#include "mm/gc-common.h"
+#include "mm/gc.hpp"
#include "mm/memory.h"
#include "native/jni.h"
#include "native/native.h"
#if defined(ENABLE_JAVASE)
-# if defined(WITH_CLASSPATH_GNU)
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
# include "native/include/gnu_classpath_Pointer.h"
# if SIZEOF_VOID_P == 8
#endif
#include "native/include/java_lang_Object.h"
-#include "native/include/java_lang_Byte.h"
-#include "native/include/java_lang_Character.h"
-#include "native/include/java_lang_Short.h"
-#include "native/include/java_lang_Integer.h"
-#include "native/include/java_lang_Boolean.h"
-#include "native/include/java_lang_Long.h"
-#include "native/include/java_lang_Float.h"
-#include "native/include/java_lang_Double.h"
#include "native/include/java_lang_String.h"
#include "native/include/java_lang_Throwable.h"
#if defined(ENABLE_JAVASE)
-# 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
+/* java_lang_ClassLoader is used in java_lang_Class and vice versa, so
+ we pre-define it here to prevent a compiler warning for Sun
+ configurations. */
+
+struct java_lang_ClassLoader;
+
+# include "native/include/java_lang_Class.h"
# include "native/include/java_lang_ClassLoader.h"
# include "native/include/java_lang_reflect_Constructor.h"
# include "native/include/java_nio_Buffer.h"
-# if defined(WITH_CLASSPATH_GNU)
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+# include "native/include/java_lang_reflect_VMConstructor.h"
+# include "native/include/java_lang_reflect_VMField.h"
+# include "native/include/java_lang_reflect_VMMethod.h"
+
# include "native/include/java_nio_DirectByteBufferImpl.h"
# endif
+#elif defined(ENABLE_JAVAME_CLDC1_1)
+# include "native/include/java_lang_Class.h"
#endif
#if defined(ENABLE_JVMTI)
# include "native/jvmti/cacaodbg.h"
#endif
-#include "native/vm/java_lang_Class.h"
-
#if defined(ENABLE_JAVASE)
-# include "native/vm/java_lang_ClassLoader.h"
# include "native/vm/reflect.h"
#endif
#include "threads/lock-common.h"
-#include "threads/threads-common.h"
+#include "threads/thread.h"
#include "toolbox/logging.h"
+#include "vm/array.h"
#include "vm/builtin.h"
#include "vm/exceptions.h"
#include "vm/global.h"
#include "vm/initialize.h"
-#include "vm/primitive.h"
+#include "vm/primitive.hpp"
#include "vm/resolve.h"
#include "vm/stringlocal.h"
-#include "vm/vm.h"
+#include "vm/vm.hpp"
+#include "vm/jit/argument.h"
#include "vm/jit/asmpart.h"
#include "vm/jit/jit.h"
#include "vm/jit/stacktrace.h"
/* debug **********************************************************************/
#if !defined(NDEBUG)
-# define TRACEJNICALLS(format, ...) \
- do { \
- if (opt_TraceJNICalls) { \
- log_println((format), __VA_ARGS__); \
- } \
+
+# define TRACEJNICALLS(x) \
+ do { \
+ if (opt_TraceJNICalls) { \
+ log_println x; \
+ } \
} while (0)
+
+# define TRACEJNICALLSENTER(x) \
+ do { \
+ if (opt_TraceJNICalls) { \
+ log_start(); \
+ log_print x; \
+ } \
+ } while (0)
+
+# define TRACEJNICALLSEXIT(x) \
+ do { \
+ if (opt_TraceJNICalls) { \
+ log_print x; \
+ log_finish(); \
+ } \
+ } while (0)
+
#else
-# define TRACEJNICALLS(format, ...)
+
+# define TRACEJNICALLS(x)
+# define TRACEJNICALLSENTER(x)
+# define TRACEJNICALLSEXIT(x)
+
#endif
#if defined(ENABLE_JAVASE)
static classinfo *class_java_nio_Buffer;
+
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+
static classinfo *class_java_nio_DirectByteBufferImpl;
static classinfo *class_java_nio_DirectByteBufferImpl_ReadWrite;
-# if defined(WITH_CLASSPATH_GNU)
# if SIZEOF_VOID_P == 8
static classinfo *class_gnu_classpath_Pointer64;
# else
static classinfo *class_gnu_classpath_Pointer32;
# endif
-# endif
static methodinfo *dbbirw_init;
-#endif
+# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-/* accessing instance fields macros *******************************************/
+static classinfo *class_sun_nio_ch_DirectBuffer;
+static classinfo *class_java_nio_DirectByteBuffer;
-#define SET_FIELD(o,type,f,value) \
- *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset))) = (type) (value)
+static methodinfo *dbb_init;
-#define GET_FIELD(o,type,f) \
- *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset)))
+# endif
+#endif
/* some forward declarations **************************************************/
-jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref);
+jobject jni_NewLocalRef(JNIEnv *env, jobject ref);
/* jni_init ********************************************************************
bool jni_init(void)
{
+ TRACESUBSYSTEMINITIALIZATION("jni_init");
+
/* create global ref hashtable */
hashtable_global_ref = NEW(hashtable);
#if defined(ENABLE_JAVASE)
- /* direct buffer stuff */
+ /* Direct buffer stuff. */
if (!(class_java_nio_Buffer =
load_class_bootstrap(utf_new_char("java/nio/Buffer"))) ||
!link_class(class_java_nio_Buffer))
return false;
-# if defined(WITH_CLASSPATH_GNU)
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+
if (!(class_java_nio_DirectByteBufferImpl =
load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl"))) ||
!link_class(class_java_nio_DirectByteBufferImpl))
!link_class(class_gnu_classpath_Pointer32))
return false;
# endif
+
+# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+
+ if (!(class_sun_nio_ch_DirectBuffer =
+ load_class_bootstrap(utf_new_char("sun/nio/ch/DirectBuffer"))))
+ vm_abort("jni_init: loading sun/nio/ch/DirectBuffer failed");
+
+ if (!link_class(class_sun_nio_ch_DirectBuffer))
+ vm_abort("jni_init: linking sun/nio/ch/DirectBuffer failed");
+
+ if (!(class_java_nio_DirectByteBuffer =
+ load_class_bootstrap(utf_new_char("java/nio/DirectByteBuffer"))))
+ vm_abort("jni_init: loading java/nio/DirectByteBuffer failed");
+
+ if (!link_class(class_java_nio_DirectByteBuffer))
+ vm_abort("jni_init: linking java/nio/DirectByteBuffer failed");
+
+ if (!(dbb_init =
+ class_resolvemethod(class_java_nio_DirectByteBuffer,
+ utf_init,
+ utf_new_char("(JI)V"))))
+ vm_abort("jni_init: resolving java/nio/DirectByteBuffer.init(JI)V failed");
+
# endif
+
#endif /* defined(ENABLE_JAVASE) */
return true;
}
+/* jni_version_check ***********************************************************
+
+ Check if the given JNI version is supported.
+
+ IN:
+ version....JNI version to check
+
+ RETURN VALUE:
+ true.......supported
+ false......not supported
+
+*******************************************************************************/
+
+bool jni_version_check(int version)
+{
+ switch (version) {
+ case JNI_VERSION_1_1:
+ case JNI_VERSION_1_2:
+ case JNI_VERSION_1_4:
+ case JNI_VERSION_1_6:
+ return true;
+ default:
+ return false;
+ }
+}
+
+
/* _Jv_jni_CallObjectMethod ****************************************************
Internal function to call Java Object methods.
}
-/* _Jv_jni_invokeNative ********************************************************
-
- Invoke a method on the given object with the given arguments.
-
- For instance methods OBJ must be != NULL and the method is looked up
- in the vftbl of the object.
-
- For static methods, OBJ is ignored.
-
-*******************************************************************************/
-
-java_handle_t *_Jv_jni_invokeNative(methodinfo *m, java_handle_t *o,
- java_handle_objectarray_t *params)
-{
- methodinfo *resm;
- java_handle_t *ro;
- s4 argcount;
- s4 paramcount;
- java_handle_t *xptr;
- int32_t dumpsize;
- uint64_t *array;
- imm_union value;
-
- if (m == NULL) {
- exceptions_throw_nullpointerexception();
- return NULL;
- }
-
- argcount = m->parseddesc->paramcount;
- paramcount = argcount;
-
- /* if method is non-static, remove the `this' pointer */
-
- if (!(m->flags & ACC_STATIC))
- paramcount--;
-
- /* For instance methods the object has to be an instance of the
- class the method belongs to. For static methods the obj
- parameter is ignored. */
-
- if (!(m->flags & ACC_STATIC) && o && (!builtin_instanceof(o, m->class))) {
- exceptions_throw_illegalargumentexception();
- return NULL;
- }
-
- /* check if we got the right number of arguments */
-
- if (((params == NULL) && (paramcount != 0)) ||
- (params && (LLNI_array_size(params) != paramcount)))
- {
- exceptions_throw_illegalargumentexception();
- return NULL;
- }
-
- /* for instance methods we need an object */
-
- if (!(m->flags & ACC_STATIC) && (o == NULL)) {
- /* XXX not sure if that is the correct exception */
- exceptions_throw_nullpointerexception();
- return NULL;
- }
-
- /* for static methods, zero object to make subsequent code simpler */
- if (m->flags & ACC_STATIC)
- o = NULL;
-
- if (o != NULL) {
- /* for instance methods we must do a vftbl lookup */
- resm = method_vftbl_lookup(LLNI_vftbl_direct(o), m);
- }
- else {
- /* for static methods, just for convenience */
- resm = m;
- }
-
- /* mark start of dump memory area */
-
- dumpsize = dump_size();
-
- /* Fill the argument array from a object-array. */
-
- array = vm_array_from_objectarray(resm, o, params);
-
- /* The array can be NULL if we don't have any arguments to pass
- and the architecture does not have any argument registers
- (e.g. i386). In that case we additionally check for an
- exception thrown. */
-
- if ((array == NULL) && (exceptions_get_exception() != NULL)) {
- /* release dump area */
-
- dump_release(dumpsize);
-
- return NULL;
- }
-
- switch (resm->parseddesc->returntype.decltype) {
- case TYPE_VOID:
- (void) vm_call_array(resm, array);
- ro = NULL;
- break;
-
- case PRIMITIVETYPE_BOOLEAN:
- case PRIMITIVETYPE_BYTE:
- case PRIMITIVETYPE_CHAR:
- case PRIMITIVETYPE_SHORT:
- case PRIMITIVETYPE_INT:
- value.i = vm_call_int_array(resm, array);
- ro = primitive_box(resm->parseddesc->returntype.decltype, value);
- break;
-
- case PRIMITIVETYPE_LONG:
- value.l = vm_call_long_array(resm, array);
- ro = primitive_box(resm->parseddesc->returntype.decltype, value);
- break;
-
- case PRIMITIVETYPE_FLOAT:
- value.f = vm_call_float_array(resm, array);
- ro = primitive_box(resm->parseddesc->returntype.decltype, value);
- break;
-
- case PRIMITIVETYPE_DOUBLE:
- value.d = vm_call_double_array(resm, array);
- ro = primitive_box(resm->parseddesc->returntype.decltype, value);
- break;
-
- case TYPE_ADR:
- ro = vm_call_array(resm, array);
- break;
-
- default:
- vm_abort("_Jv_jni_invokeNative: invalid return type %d", resm->parseddesc->returntype.decltype);
- }
-
- xptr = exceptions_get_exception();
-
- if (xptr != NULL) {
- /* clear exception pointer, we are calling JIT code again */
-
- exceptions_clear_exception();
-
- exceptions_throw_invocationtargetexception(xptr);
- }
-
- /* release dump area */
-
- dump_release(dumpsize);
-
- return ro;
-}
-
-
/* GetVersion ******************************************************************
Returns the major version number in the higher 16 bits and the
jint _Jv_JNI_GetVersion(JNIEnv *env)
{
- STATISTICS(jniinvokation());
+ TRACEJNICALLS(("_Jv_JNI_GetVersion(env=%p)", env));
- /* we support JNI 1.4 */
+ /* We support JNI 1.6. */
- return JNI_VERSION_1_4;
+ return JNI_VERSION_1_6;
}
{
#if defined(ENABLE_JAVASE)
utf *u;
- classloader *cl;
+ classloader_t *cl;
classinfo *c;
java_lang_Class *co;
- TRACEJNICALLS("_Jv_JNI_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d", env, name, loader, buf, bufLen);
+ TRACEJNICALLS(("_Jv_JNI_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d)", env, name, loader, buf, bufLen));
u = utf_new_char(name);
cl = loader_hashtable_classloader_add((java_handle_t *) loader);
- c = class_define(u, cl, bufLen, (const uint8_t *) buf);
+ c = class_define(u, cl, bufLen, (uint8_t *) buf, NULL);
co = LLNI_classinfo_wrap(c);
- return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
+ return (jclass) jni_NewLocalRef(env, (jobject) co);
#else
vm_abort("_Jv_JNI_DefineClass: not implemented in this configuration");
*******************************************************************************/
-jclass _Jv_JNI_FindClass(JNIEnv *env, const char *name)
+jclass jni_FindClass(JNIEnv *env, const char *name)
{
#if defined(ENABLE_JAVASE)
+
utf *u;
classinfo *cc;
classinfo *c;
java_lang_Class *co;
- STATISTICS(jniinvokation());
+ TRACEJNICALLS(("jni_FindClass(env=%p, name=%s)", env, name));
+
+ /* FIXME If name is NULL we have a problem here. */
u = utf_new_char_classname((char *) name);
+ if ((u == NULL) /*|| (int)strlen(name) > symbolOopDesc::max_length() */) {
+ exceptions_throw_noclassdeffounderror(u);
+ return NULL;
+ }
+
/* Check stacktrace for classloader, if one found use it,
otherwise use the system classloader. */
its associated class loader. In that case, the result of
ClassLoader.getBaseClassLoader is used." */
- cc = stacktrace_getCurrentClass();
+ cc = stacktrace_get_current_class();
if (cc == NULL)
c = load_class_from_sysloader(u);
else
c = load_class_from_classloader(u, cc->classloader);
- if (c == NULL)
+ if (c == NULL) {
+ resolve_handle_pending_exception(true);
return NULL;
+ }
if (!link_class(c))
return NULL;
co = LLNI_classinfo_wrap(c);
- return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
+ return (jclass) jni_NewLocalRef(env, (jobject) co);
+
+#elif defined(ENABLE_JAVAME_CLDC1_1)
+
+ utf *u;
+ classinfo *c;
+
+ TRACEJNICALLS(("jni_FindClass(env=%p, name=%s)", env, name));
+
+ u = utf_new_char_classname((char *) name);
+ c = load_class_bootstrap(u);
+
+ if (c == NULL) {
+ resolve_handle_pending_exception(true);
+ return NULL;
+ }
+
+ if (!link_class(c))
+ return NULL;
+
+ return (jclass) jni_NewLocalRef(env, (jobject) c);
+
#else
- vm_abort("_Jv_JNI_FindClass: not implemented in this configuration");
+ vm_abort("jni_FindClass: not implemented in this configuration");
/* keep compiler happy */
classinfo *super;
java_lang_Class *co;
- TRACEJNICALLS("_Jv_JNI_GetSuperclass(env=%p, sub=%p)", env, sub);
+ TRACEJNICALLS(("_Jv_JNI_GetSuperclass(env=%p, sub=%p)", env, sub));
c = LLNI_classinfo_unwrap(sub);
co = LLNI_classinfo_wrap(super);
- return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
+ return (jclass) jni_NewLocalRef(env, (jobject) co);
}
jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
{
- java_lang_Class *csup;
- java_lang_Class *csub;
+ classinfo *to;
+ classinfo *from;
- csup = (java_lang_Class *) sup;
- csub = (java_lang_Class *) sub;
+ TRACEJNICALLS(("_Jv_JNI_IsAssignableFrom(env=%p, sub=%p, sup=%p)", env, sub, sup));
- STATISTICS(jniinvokation());
+ to = (classinfo *) sup;
+ from = (classinfo *) sub;
- return _Jv_java_lang_Class_isAssignableFrom(csup, csub);
+ return class_is_assignable_from(to, from);
}
{
java_handle_t *o;
- STATISTICS(jniinvokation());
+ TRACEJNICALLS(("_Jv_JNI_ExceptionOccurred(env=%p)", env));
o = exceptions_get_exception();
- return _Jv_JNI_NewLocalRef(env, (jthrowable) o);
+ return jni_NewLocalRef(env, (jthrowable) o);
}
*******************************************************************************/
-void _Jv_JNI_ExceptionDescribe(JNIEnv *env)
+void jni_ExceptionDescribe(JNIEnv *env)
{
- java_handle_t *o;
- classinfo *c;
- methodinfo *m;
-
- STATISTICS(jniinvokation());
-
- o = exceptions_get_exception();
-
- if (o == NULL) {
- /* clear exception, because we are calling jit code again */
-
- exceptions_clear_exception();
-
- /* get printStackTrace method from exception class */
-
- LLNI_class_get(o, c);
-
- m = class_resolveclassmethod(c,
- utf_printStackTrace,
- utf_void__void,
- NULL,
- true);
-
- if (m == NULL)
- /* XXX what should we do? */
- return;
-
- /* print the stacktrace */
+ TRACEJNICALLS(("jni_ExceptionDescribe(env=%p)", env));
- (void) vm_call_method(m, o);
- }
+ exceptions_print_stacktrace();
}
*******************************************************************************/
-void _Jv_JNI_ExceptionClear(JNIEnv *env)
+void jni_ExceptionClear(JNIEnv *env)
{
- STATISTICS(jniinvokation());
+ TRACEJNICALLS(("jni_ExceptionClear(env=%p)", env));
exceptions_clear_exception();
}
*******************************************************************************/
-jint _Jv_JNI_PushLocalFrame(JNIEnv* env, jint capacity)
+jint jni_PushLocalFrame(JNIEnv* env, jint capacity)
{
- STATISTICS(jniinvokation());
+ TRACEJNICALLS(("jni_PushLocalFrame(env=%p, capacity=%d)", env, capacity));
if (capacity <= 0)
return -1;
*******************************************************************************/
-jobject _Jv_JNI_PopLocalFrame(JNIEnv* env, jobject result)
+jobject jni_PopLocalFrame(JNIEnv* env, jobject result)
{
- STATISTICS(jniinvokation());
+ TRACEJNICALLS(("jni_PopLocalFrame(env=%p, result=%p)", env, result));
/* release all current local frames */
/* add local reference and return the value */
- return _Jv_JNI_NewLocalRef(env, result);
+ return jni_NewLocalRef(env, result);
}
*******************************************************************************/
-void _Jv_JNI_DeleteLocalRef(JNIEnv *env, jobject localRef)
+void jni_DeleteLocalRef(JNIEnv *env, jobject localRef)
{
- java_handle_t *o;
+ java_handle_t *o;
- STATISTICS(jniinvokation());
+ TRACEJNICALLS(("jni_DeleteLocalRef(env=%p, ref=%p)", env, localRef));
o = (java_handle_t *) localRef;
+ if (o == NULL)
+ return;
+
/* delete the reference */
localref_del(o);
*******************************************************************************/
-jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref)
+jobject jni_NewLocalRef(JNIEnv *env, jobject ref)
{
java_handle_t *o;
java_handle_t *localref;
- STATISTICS(jniinvokation());
-
- if (ref == NULL)
- return NULL;
+ TRACEJNICALLS(("jni_NewLocalRef(env=%p, ref=%p)", env, ref));
o = (java_handle_t *) ref;
+ if (o == NULL)
+ return NULL;
+
/* insert the reference */
localref = localref_add(LLNI_DIRECT(o));
- return localref;
+ return (jobject) localref;
}
*******************************************************************************/
-jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity)
+jint jni_EnsureLocalCapacity(JNIEnv* env, jint capacity)
{
localref_table *lrt;
- STATISTICS(jniinvokation());
+ TRACEJNICALLS(("jni_EnsureLocalCapacity(env=%p, capacity=%d)", env, capacity));
/* get local reference table (thread specific) */
/* check if capacity elements are available in the local references table */
if ((lrt->used + capacity) > lrt->capacity)
- return _Jv_JNI_PushLocalFrame(env, capacity);
+ return jni_PushLocalFrame(env, capacity);
return 0;
}
o = builtin_new(c);
- return _Jv_JNI_NewLocalRef(env, (jobject) o);
+ return jni_NewLocalRef(env, (jobject) o);
}
*******************************************************************************/
-jobject _Jv_JNI_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
+jobject jni_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
{
java_handle_t *o;
classinfo *c;
methodinfo *m;
va_list ap;
- STATISTICS(jniinvokation());
+ TRACEJNICALLSENTER(("jni_NewObject(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
c = LLNI_classinfo_unwrap(clazz);
m = (methodinfo *) methodID;
_Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
va_end(ap);
- return _Jv_JNI_NewLocalRef(env, (jobject) o);
+ TRACEJNICALLSEXIT(("->%p", o));
+
+ return jni_NewLocalRef(env, (jobject) o);
}
_Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
- return _Jv_JNI_NewLocalRef(env, (jobject) o);
+ return jni_NewLocalRef(env, (jobject) o);
}
_Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
- return _Jv_JNI_NewLocalRef(env, (jobject) o);
+ return jni_NewLocalRef(env, (jobject) o);
}
co = LLNI_classinfo_wrap(c);
- return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) co);
+ return (jclass) jni_NewLocalRef(env, (jobject) co);
}
jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
{
- java_lang_Class *c;
- java_lang_Object *o;
+ classinfo *c;
+ java_handle_t *h;
- STATISTICS(jniinvokation());
+ TRACEJNICALLS(("_Jv_JNI_IsInstanceOf(env=%p, obj=%p, clazz=%p)", env, obj, clazz));
- c = (java_lang_Class *) clazz;
- o = (java_lang_Object *) obj;
+ /* XXX Is this correct? */
+ c = LLNI_classinfo_unwrap(clazz);
+ h = (java_handle_t *) obj;
- return _Jv_java_lang_Class_isInstance(c, o);
+ return class_is_instance(c, h);
}
*******************************************************************************/
-jmethodID _Jv_JNI_FromReflectedMethod(JNIEnv *env, jobject method)
+jmethodID jni_FromReflectedMethod(JNIEnv *env, jobject method)
{
#if defined(ENABLE_JAVASE)
- java_handle_t *o;
- classinfo *c;
- methodinfo *m;
- s4 slot;
+ java_handle_t *o;
+ java_lang_reflect_Method *rm;
+ java_lang_reflect_Constructor *rc;
+ classinfo *c;
+ methodinfo *m;
+ int32_t slot;
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+ java_lang_reflect_VMMethod *rvmm;
+ java_lang_reflect_VMConstructor *rvmc;
+#endif
- STATISTICS(jniinvokation());
+ TRACEJNICALLS(("jni_FromReflectedMethod(env=%p, method=%p)", env, method));
o = (java_handle_t *) method;
if (o == NULL)
return NULL;
-
- if (builtin_instanceof(o, class_java_lang_reflect_Method)) {
- java_lang_reflect_Method *rm;
- rm = (java_lang_reflect_Method *) method;
- LLNI_field_get_cls(rm, clazz, c);
- LLNI_field_get_val(rm, slot , slot);
- }
- else if (builtin_instanceof(o, class_java_lang_reflect_Constructor)) {
- java_lang_reflect_Constructor *rc;
+ if (o->vftbl->clazz == class_java_lang_reflect_Constructor) {
+ rc = (java_lang_reflect_Constructor *) method;
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+
+ LLNI_field_get_ref(rc, cons , rvmc);
+ LLNI_field_get_cls(rvmc, clazz, c);
+ LLNI_field_get_val(rvmc, slot , slot);
+
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
- rc = (java_lang_reflect_Constructor *) method;
LLNI_field_get_cls(rc, clazz, c);
LLNI_field_get_val(rc, slot , slot);
+
+#else
+# error unknown configuration
+#endif
+ }
+ else {
+ assert(o->vftbl->clazz == class_java_lang_reflect_Method);
+
+ rm = (java_lang_reflect_Method *) method;
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+
+ LLNI_field_get_ref(rm, m , rvmm);
+ LLNI_field_get_cls(rvmm, clazz, c);
+ LLNI_field_get_val(rvmm, slot , slot);
+
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+
+ LLNI_field_get_cls(rm, clazz, c);
+ LLNI_field_get_val(rm, slot , slot);
+
+#else
+# error unknown configuration
+#endif
}
- else
- return NULL;
m = &(c->methods[slot]);
return (jmethodID) m;
#else
- vm_abort("_Jv_JNI_FromReflectedMethod: not implemented in this configuration");
+ vm_abort("jni_FromReflectedMethod: Not implemented in this configuration.");
- /* keep compiler happy */
+ /* Keep compiler happy. */
return NULL;
#endif
*******************************************************************************/
-jfieldID _Jv_JNI_FromReflectedField(JNIEnv* env, jobject field)
+jfieldID jni_FromReflectedField(JNIEnv* env, jobject field)
{
#if defined(ENABLE_JAVASE)
- java_lang_reflect_Field *rf;
- classinfo *c;
- fieldinfo *f;
- int32_t slot;
+ java_lang_reflect_Field *rf;
+ classinfo *c;
+ fieldinfo *f;
+ int32_t slot;
- STATISTICS(jniinvokation());
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+ java_lang_reflect_VMField *rvmf;
+#endif
+
+ TRACEJNICALLS(("jni_FromReflectedField(env=%p, field=%p)", env, field));
rf = (java_lang_reflect_Field *) field;
if (rf == NULL)
return NULL;
+#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)
+
LLNI_field_get_cls(rf, clazz, c);
LLNI_field_get_val(rf, slot , slot);
+
+#else
+# error unknown configuration
+#endif
+
f = &(c->fields[slot]);
return (jfieldID) f;
#else
- vm_abort("_Jv_JNI_FromReflectedField: not implemented in this configuration");
+ vm_abort("jni_FromReflectedField: Not implemented in this configuration.");
- /* keep compiler happy */
+ /* Keep compiler happy. */
return NULL;
#endif
java_lang_reflect_Constructor *rc;
java_lang_reflect_Method *rm;
- STATISTICS(jniinvokation());
+ TRACEJNICALLS(("_Jv_JNI_ToReflectedMethod(env=%p, cls=%p, methodID=%p, isStatic=%d)", env, cls, methodID, isStatic));
m = (methodinfo *) methodID;
ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, ap);
va_end(ap);
- return _Jv_JNI_NewLocalRef(env, (jobject) ret);
+ return jni_NewLocalRef(env, (jobject) ret);
}
ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, args);
- return _Jv_JNI_NewLocalRef(env, (jobject) ret);
+ return jni_NewLocalRef(env, (jobject) ret);
}
ret = _Jv_jni_CallObjectMethodA(o, LLNI_vftbl_direct(o), m, args);
- return _Jv_JNI_NewLocalRef(env, (jobject) ret);
+ return jni_NewLocalRef(env, (jobject) ret);
}
r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
va_end(ap);
- return _Jv_JNI_NewLocalRef(env, (jobject) r);
+ return jni_NewLocalRef(env, (jobject) r);
}
r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
- return _Jv_JNI_NewLocalRef(env, (jobject) r);
+ return jni_NewLocalRef(env, (jobject) r);
}
{
log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
- return _Jv_JNI_NewLocalRef(env, NULL);
+ return jni_NewLocalRef(env, NULL);
}
*******************************************************************************/
+#define GET_FIELD(o,type,f) \
+ *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset)))
+
#define JNI_GET_FIELD(name, type, intern) \
type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
{ \
intern ret; \
\
- STATISTICS(jniinvokation()); \
+ TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "Field(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID)); \
+ \
+ LLNI_CRITICAL_START; \
+ \
+ ret = GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID); \
\
- ret = GET_FIELD(obj, intern, fieldID); \
+ LLNI_CRITICAL_END; \
\
return (type) ret; \
}
{
java_handle_t *o;
- STATISTICS(jniinvokation());
+ TRACEJNICALLS(("_Jv_JNI_GetObjectField(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID));
+
+ LLNI_CRITICAL_START;
- vm_abort("this needs to be fixed");
- o = GET_FIELD(obj, java_handle_t*, fieldID);
+ o = LLNI_WRAP(GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), java_object_t*, fieldID));
- return _Jv_JNI_NewLocalRef(env, (jobject) o);
+ LLNI_CRITICAL_END;
+
+ return jni_NewLocalRef(env, (jobject) o);
}
*******************************************************************************/
-#define JNI_SET_FIELD(name, type, intern) \
-void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
- type value) \
-{ \
- STATISTICS(jniinvokation()); \
- \
- SET_FIELD(obj, intern, fieldID, value); \
+#define SET_FIELD(o,type,f,value) \
+ *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset))) = (type) (value)
+
+#define JNI_SET_FIELD(name, type, intern) \
+void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
+ type value) \
+{ \
+ TRACEJNICALLS(("_Jv_JNI_Set" STR(name) "Field(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value)); \
+ \
+ LLNI_CRITICAL_START; \
+ \
+ SET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID, value); \
+ \
+ LLNI_CRITICAL_START; \
}
JNI_SET_FIELD(Boolean, jboolean, s4)
void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
jobject value)
{
- STATISTICS(jniinvokation());
+ TRACEJNICALLS(("_Jv_JNI_SetObjectField(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value));
+
+ LLNI_CRITICAL_START;
+
+ SET_FIELD(obj, java_handle_t*, fieldID, LLNI_UNWRAP((java_handle_t*) value));
- vm_abort("this needs to be fixed");
- SET_FIELD(obj, java_handle_t*, fieldID, value);
+ LLNI_CRITICAL_END;
}
utf *udesc;
methodinfo *m;
- STATISTICS(jniinvokation());
+ TRACEJNICALLS(("_Jv_JNI_GetStaticMethodID(env=%p, clazz=%p, name=%s, sig=%s)", env, clazz, name, sig));
c = LLNI_classinfo_unwrap(clazz);
- if (!c)
+ if (c == NULL)
return NULL;
if (!(c->state & CLASS_INITIALIZED))
java_handle_t *o;
va_list ap;
+ TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
+
m = (methodinfo *) methodID;
va_start(ap, methodID);
o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
va_end(ap);
- return _Jv_JNI_NewLocalRef(env, (jobject) o);
+ return jni_NewLocalRef(env, (jobject) o);
}
methodinfo *m;
java_handle_t *o;
+ TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
+
m = (methodinfo *) methodID;
o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
- return _Jv_JNI_NewLocalRef(env, (jobject) o);
+ return jni_NewLocalRef(env, (jobject) o);
}
methodinfo *m;
java_handle_t *o;
+ TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
+
m = (methodinfo *) methodID;
o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
- return _Jv_JNI_NewLocalRef(env, (jobject) o);
+ return jni_NewLocalRef(env, (jobject) o);
}
methodinfo *m;
va_list ap;
+ TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
+
m = (methodinfo *) methodID;
va_start(ap, methodID);
{
methodinfo *m;
+ TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodV(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
+
m = (methodinfo *) methodID;
_Jv_jni_CallVoidMethod(NULL, NULL, m, args);
{
methodinfo *m;
+ TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
+
m = (methodinfo *) methodID;
_Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
jfieldID fieldID)
{
- classinfo *c;
- fieldinfo *f;
+ classinfo *c;
+ fieldinfo *f;
+ java_handle_t *h;
STATISTICS(jniinvokation());
if (!initialize_class(c))
return NULL;
- return _Jv_JNI_NewLocalRef(env, f->value->a);
+ h = LLNI_WRAP(f->value->a);
+
+ return jni_NewLocalRef(env, (jobject) h);
}
if (!initialize_class(c))
return;
- f->value->a = value;
+ f->value->a = LLNI_UNWRAP((java_handle_t *) value);
}
LLNI_field_set_val(s, offset, 0);
LLNI_field_set_val(s, count , len);
- return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
+ return (jstring) jni_NewLocalRef(env, (jobject) s);
}
java_lang_String *s;
jsize len;
- TRACEJNICALLS("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str);
+ TRACEJNICALLS(("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str));
s = (java_lang_String *) str;
{
java_lang_String *s;
- TRACEJNICALLS("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes);
+ TRACEJNICALLS(("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes));
s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
- return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
+ return (jstring) jni_NewLocalRef(env, (jobject) s);
}
java_lang_String *s;
s4 length;
- TRACEJNICALLS("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string);
+ TRACEJNICALLS(("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string));
s = (java_lang_String *) string;
java_handle_t *a;
jsize size;
- STATISTICS(jniinvokation());
+ TRACEJNICALLS(("_Jv_JNI_GetArrayLength(env=%p, array=%p)", env, array));
a = (java_handle_t *) array;
/* set all elements to initialElement */
for (i = 0; i < length; i++)
- LLNI_objectarray_element_set(oa, i, o);
+ array_objectarray_element_set(oa, i, o);
- return (jobjectArray) _Jv_JNI_NewLocalRef(env, (jobject) oa);
+ return (jobjectArray) jni_NewLocalRef(env, (jobject) oa);
}
return NULL;
}
- LLNI_objectarray_element_get(oa, index, o);
+ o = array_objectarray_element_get(oa, index);
- return _Jv_JNI_NewLocalRef(env, (jobject) o);
+ return jni_NewLocalRef(env, (jobject) o);
}
/* check if the class of value is a subclass of the element class
of the array */
- if (!builtin_canstore(LLNI_DIRECT(oa), LLNI_DIRECT(o)))
+ if (!builtin_canstore(oa, o))
return;
- LLNI_objectarray_element_set(oa, index, o);
+ array_objectarray_element_set(oa, index, o);
}
\
a = builtin_newarray_##intern(len); \
\
- return (type) _Jv_JNI_NewLocalRef(env, (jobject) a); \
+ return (type) jni_NewLocalRef(env, (jobject) a); \
}
JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
JNI_NEW_ARRAY(Byte, jbyteArray, byte)
JNI_NEW_ARRAY(Char, jcharArray, char)
-JNI_NEW_ARRAY(Short, jshortArray, byte)
+JNI_NEW_ARRAY(Short, jshortArray, short)
JNI_NEW_ARRAY(Int, jintArray, int)
JNI_NEW_ARRAY(Long, jlongArray, long)
JNI_NEW_ARRAY(Float, jfloatArray, float)
{ \
java_handle_##intern##array_t *a; \
\
- STATISTICS(jniinvokation()); \
+ TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayElements(env=%p, array=%p, isCopy=%d)", env, array, isCopy)); \
\
a = (java_handle_##intern##array_t *) array; \
\
if (isCopy) \
*isCopy = JNI_FALSE; \
\
- return LLNI_array_data(a); \
+ return (type *) LLNI_array_data(a); \
}
JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
\
a = (java_handle_##intern##array_t *) array; \
\
- if (elems != LLNI_array_data(a)) { \
+ if (elems != (type *) LLNI_array_data(a)) { \
switch (mode) { \
case JNI_COMMIT: \
MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
{ \
java_handle_##intern##array_t *a; \
\
- STATISTICS(jniinvokation()); \
+ 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; \
\
{
STATISTICS(jniinvokation());
- *vm = (JavaVM *) _Jv_jvm;
+ *vm = VM_get_javavm();
return 0;
}
int32_t count;
int32_t offset;
- TRACEJNICALLS("_Jv_JNI_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf);
+ TRACEJNICALLS(("_Jv_JNI_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf));
s = (java_lang_String *) str;
LLNI_field_get_ref(s, value, ca);
Obtain a direct pointer to array elements.
+ ATTENTION: Critical section keeps open when this function returns!
+ See ReleasePrimitiveArrayCritical.
+
*******************************************************************************/
-void *_Jv_JNI_GetPrimitiveArrayCritical(JNIEnv *env, jarray array,
- jboolean *isCopy)
+void* jni_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
{
- java_handle_bytearray_t *ba;
- jbyte *bp;
+ java_handle_t* h;
+ java_array_t* a;
+ arraydescriptor* ad;
+ void* data;
+
+ TRACEJNICALLS(("jni_GetPrimitiveArrayCritical(env=%p, array=%p, isCopy=%d)", env, array, isCopy));
+
+ if (isCopy != NULL) {
+ *isCopy = JNI_FALSE;
+ }
+
+ LLNI_CRITICAL_START;
- ba = (java_handle_bytearray_t *) array;
+ h = (java_handle_t*) array;
+ a = (java_array_t*) LLNI_UNWRAP(h);
+ ad = a->objheader.vftbl->arraydesc;
- /* do the same as Kaffe does */
+ /* Sanity check. */
- bp = _Jv_JNI_GetByteArrayElements(env, (jbyteArray) ba, isCopy);
+ assert(ad != NULL);
- return (void *) bp;
+ data = (void*) (((intptr_t) a) + ad->dataoffset);
+
+ return data;
}
No specific documentation.
+ ATTENTION: This function closes the critical section opened in
+ GetPrimitiveArrayCritical!
+
*******************************************************************************/
-void _Jv_JNI_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array,
- void *carray, jint mode)
+void jni_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode)
{
- STATISTICS(jniinvokation());
+ TRACEJNICALLS(("jni_ReleasePrimitiveArrayCritical(env=%p, array=%p, carray=%p, mode=%d)", env, array, carray, mode));
- /* do the same as Kaffe does */
-
- _Jv_JNI_ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray,
- mode);
+ LLNI_CRITICAL_END;
}
jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
{
- STATISTICS(jniinvokation());
-
- log_text("JNI-Call: NewWeakGlobalRef: IMPLEMENT ME!");
+ TRACEJNICALLS(("_Jv_JNI_NewWeakGlobalRef(env=%p, obj=%p): IMPLEMENT ME!", env, obj));
return obj;
}
void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
{
- STATISTICS(jniinvokation());
-
- log_text("JNI-Call: DeleteWeakGlobalRef: IMPLEMENT ME");
+ TRACEJNICALLS(("_Jv_JNI_DeleteWeakGlobalRef(env=%p, ref=%p): IMPLEMENT ME", env, ref));
}
*******************************************************************************/
-jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj)
+jobject jni_NewGlobalRef(JNIEnv* env, jobject obj)
{
hashtable_global_ref_entry *gre;
u4 key; /* hashkey */
u4 slot; /* slot in hashtable */
java_handle_t *o;
- STATISTICS(jniinvokation());
+ TRACEJNICALLS(("jni_NewGlobalRef(env=%p, obj=%p)", env, obj));
o = (java_handle_t *) obj;
/* normally addresses are aligned to 4, 8 or 16 bytes */
-#if defined(ENABLE_GC_CACAO)
- key = heap_get_hashcode(LLNI_DIRECT(o)) >> 4;
-#else
- key = ((u4) (ptrint) o) >> 4; /* align to 16-byte boundaries */
-#endif
+ key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
slot = key & (hashtable_global_ref->size - 1);
gre = hashtable_global_ref->ptr[slot];
gre = gre->hashlink; /* next element in external chain */
}
+ LLNI_CRITICAL_END;
+
/* global ref not found, create a new one */
if (gre == NULL) {
- gre = NEW(hashtable_global_ref_entry);
+ gre = GCNEW_UNCOLLECTABLE(hashtable_global_ref_entry, 1);
#if defined(ENABLE_GC_CACAO)
/* register global ref with the GC */
gc_reference_register(&(gre->o), GC_REFTYPE_JNI_GLOBALREF);
#endif
+ LLNI_CRITICAL_START;
+
gre->o = LLNI_DIRECT(o);
gre->refs = 1;
+ LLNI_CRITICAL_END;
+
/* insert entry into hashtable */
gre->hashlink = hashtable_global_ref->ptr[slot];
hashtable_global_ref->entries++;
}
- LLNI_CRITICAL_END;
-
LOCK_MONITOR_EXIT(hashtable_global_ref->header);
#if defined(ENABLE_HANDLES)
*******************************************************************************/
-void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
+void jni_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
{
hashtable_global_ref_entry *gre;
hashtable_global_ref_entry *prevgre;
u4 slot; /* slot in hashtable */
java_handle_t *o;
- STATISTICS(jniinvokation());
+ TRACEJNICALLS(("jni_DeleteGlobalRef(env=%p, globalRef=%p)", env, globalRef));
o = (java_handle_t *) globalRef;
/* normally addresses are aligned to 4, 8 or 16 bytes */
-#if defined(ENABLE_GC_CACAO)
- key = heap_get_hashcode(LLNI_DIRECT(o)) >> 4;
-#else
- key = ((u4) (ptrint) o) >> 4; /* align to 16-byte boundaries */
-#endif
+ key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
slot = key & (hashtable_global_ref->size - 1);
gre = hashtable_global_ref->ptr[slot];
gc_reference_unregister(&(gre->o));
#endif
- FREE(gre, hashtable_global_ref_entry);
+ GCFREE(gre);
}
LLNI_CRITICAL_END;
gre = gre->hashlink; /* next element in external chain */
}
- log_println("JNI-DeleteGlobalRef: global reference not found");
+ log_println("jni_DeleteGlobalRef: Global reference not found.");
LLNI_CRITICAL_END;
*******************************************************************************/
-jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
+jobject jni_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
{
-#if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
+#if defined(ENABLE_JAVASE)
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
java_handle_t *nbuf;
# if SIZEOF_VOID_P == 8
gnu_classpath_Pointer32 *paddress;
# endif
- STATISTICS(jniinvokation());
+ TRACEJNICALLSENTER(("jni_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld)", env, address, capacity));
/* alocate a gnu.classpath.Pointer{32,64} object */
/* add local reference and return the value */
- return _Jv_JNI_NewLocalRef(env, nbuf);
+ TRACEJNICALLSEXIT(("->%p", nbuf));
+
+ return jni_NewLocalRef(env, nbuf);
+
+# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+
+ jobject o;
+ int64_t addr;
+ int32_t cap;
+
+ TRACEJNICALLSENTER(("jni_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld)", env, address, capacity));
+
+ /* Be paranoid about address sign-extension. */
+
+ addr = (int64_t) ((uintptr_t) address);
+ cap = (int32_t) capacity;
+
+ o = (*env)->NewObject(env, (jclass) class_java_nio_DirectByteBuffer,
+ (jmethodID) dbb_init, addr, cap);
+
+ /* Add local reference and return the value. */
+
+ TRACEJNICALLSEXIT(("->%p", o));
+
+ return jni_NewLocalRef(env, o);
+
+# else
+# error unknown classpath configuration
+# endif
+
#else
- vm_abort("_Jv_JNI_NewDirectByteBuffer: not implemented in this configuration");
+ vm_abort("jni_NewDirectByteBuffer: Not implemented in this configuration.");
/* keep compiler happy */
void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
{
-#if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
+#if defined(ENABLE_JAVASE)
+ java_handle_t *h;
+
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+
java_nio_DirectByteBufferImpl *nbuf;
-# if SIZEOF_VOID_P == 8
+ gnu_classpath_Pointer *po;
+# if SIZEOF_VOID_P == 8
gnu_classpath_Pointer64 *paddress;
-# else
+ int64_t address;
+# else
gnu_classpath_Pointer32 *paddress;
-# endif
- void *address;
+ int32_t address;
+# endif
+ void *p;
- STATISTICS(jniinvokation());
+ TRACEJNICALLS(("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
+
+ /* Prevent compiler warning. */
- if (!builtin_instanceof(buf, class_java_nio_Buffer))
+ h = (java_handle_t *) buf;
+
+ if ((h != NULL) && !builtin_instanceof(h, class_java_nio_Buffer))
return NULL;
nbuf = (java_nio_DirectByteBufferImpl *) buf;
-# if SIZEOF_VOID_P == 8
- LLNI_field_get_ref(nbuf, address, paddress);
- /* this was the cast to avaoid warning: (gnu_classpath_Pointer64 *) nbuf->address; */
-# else
- LLNI_field_get_ref(nbuf, address, paddress);
- /* this was the cast to avaoid warning: (gnu_classpath_Pointer32 *) nbuf->address; */
-# endif
+ LLNI_field_get_ref(nbuf, address, po);
+
+# if SIZEOF_VOID_P == 8
+ paddress = (gnu_classpath_Pointer64 *) po;
+# else
+ paddress = (gnu_classpath_Pointer32 *) po;
+# endif
if (paddress == NULL)
return NULL;
LLNI_field_get_val(paddress, data, address);
- /* this was the cast to avaoid warning: (void *) paddress->data */
- return address;
+ p = (void *) (intptr_t) address;
+
+ return p;
+
+# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+
+ java_nio_Buffer *o;
+ int64_t address;
+ void *p;
+
+ TRACEJNICALLS(("_Jv_JNI_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
+
+ /* Prevent compiler warning. */
+
+ h = (java_handle_t *) buf;
+
+ if ((h != NULL) && !builtin_instanceof(h, class_sun_nio_ch_DirectBuffer))
+ return NULL;
+
+ o = (java_nio_Buffer *) buf;
+
+ LLNI_field_get_val(o, address, address);
+
+ p = (void *) (intptr_t) address;
+
+ return p;
+
+# else
+# error unknown classpath configuration
+# endif
+
#else
+
vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
/* keep compiler happy */
return NULL;
+
#endif
}
jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
{
-#if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
+#if defined(ENABLE_JAVASE) && defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
java_handle_t *o;
java_nio_Buffer *nbuf;
jlong capacity;
}
+/* GetObjectRefType ************************************************************
+
+ Returns the type of the object referred to by the obj argument. The
+ argument obj can either be a local, global or weak global
+ reference.
+
+*******************************************************************************/
+
+jobjectRefType jni_GetObjectRefType(JNIEnv *env, jobject obj)
+{
+ log_println("jni_GetObjectRefType: IMPLEMENT ME!");
+
+ return -1;
+}
+
+
/* DestroyJavaVM ***************************************************************
Unloads a Java VM and reclaims its resources. Only the main thread
jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
{
- s4 status;
+ int status;
- STATISTICS(jniinvokation());
+ TRACEJNICALLS(("_Jv_JNI_DestroyJavaVM(vm=%p)", vm));
+
+ if (VM_is_created() == false)
+ return JNI_ERR;
status = vm_destroy(vm);
*******************************************************************************/
-static s4 jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
+static int jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
{
+#if defined(ENABLE_THREADS)
JavaVMAttachArgs *vm_aargs;
+ bool result;
-#if defined(ENABLE_THREADS)
- if (threads_get_current_threadobject() == NULL) {
- vm_aargs = (JavaVMAttachArgs *) thr_args;
+ /* If the current thread has already been attached, this operation
+ is a no-op. */
- if (vm_aargs != NULL) {
- if ((vm_aargs->version != JNI_VERSION_1_2) &&
- (vm_aargs->version != JNI_VERSION_1_4))
- return JNI_EVERSION;
- }
+ result = thread_current_is_attached();
- if (!threads_attach_current_thread(vm_aargs, false))
- return JNI_ERR;
+ if (result == true) {
+ *p_env = VM_get_jnienv();
- if (!localref_table_init())
- return JNI_ERR;
+ return JNI_OK;
}
+
+ vm_aargs = (JavaVMAttachArgs *) thr_args;
+
+ if (vm_aargs != NULL) {
+ if ((vm_aargs->version != JNI_VERSION_1_2) &&
+ (vm_aargs->version != JNI_VERSION_1_4))
+ return JNI_EVERSION;
+ }
+
+ if (!thread_attach_current_external_thread(vm_aargs, false))
+ return JNI_ERR;
+
+ if (!localref_table_init())
+ return JNI_ERR;
#endif
- *p_env = _Jv_env;
+ *p_env = VM_get_jnienv();
return JNI_OK;
}
-jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
+jint jni_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
{
- STATISTICS(jniinvokation());
+ int result;
- return jni_attach_current_thread(p_env, thr_args, false);
+ TRACEJNICALLS(("jni_AttachCurrentThread(vm=%p, p_env=%p, thr_args=%p)", vm, p_env, thr_args));
+
+ if (VM_is_created() == false)
+ return JNI_ERR;
+
+ result = jni_attach_current_thread(p_env, thr_args, false);
+
+ return result;
}
*******************************************************************************/
-jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
+jint jni_DetachCurrentThread(JavaVM *vm)
{
#if defined(ENABLE_THREADS)
- threadobject *thread;
+ bool result;
- STATISTICS(jniinvokation());
+ TRACEJNICALLS(("jni_DetachCurrentThread(vm=%p)", vm));
- thread = threads_get_current_threadobject();
+ /* If the current thread has already been detached, this operation
+ is a no-op. */
- if (thread == NULL)
- return JNI_ERR;
+ result = thread_current_is_attached();
+
+ if (result == false)
+ return true;
+
+ /* We need to pop all frames before we can destroy the table. */
+
+ localref_frame_pop_all();
if (!localref_table_destroy())
return JNI_ERR;
- if (!threads_detach_thread(thread))
+ if (!thread_detach_current_external_thread())
return JNI_ERR;
#endif
*******************************************************************************/
-jint _Jv_JNI_GetEnv(JavaVM *vm, void **env, jint version)
+jint jni_GetEnv(JavaVM *vm, void **env, jint version)
{
- STATISTICS(jniinvokation());
+ TRACEJNICALLS(("jni_GetEnv(vm=%p, env=%p, version=%d)", vm, env, version));
+
+ if (VM_is_created() == false) {
+ *env = NULL;
+ return JNI_EDETACHED;
+ }
#if defined(ENABLE_THREADS)
- if (threads_get_current_threadobject() == NULL) {
+ if (thread_get_current() == NULL) {
*env = NULL;
return JNI_EDETACHED;
}
#endif
- /* check the JNI version */
+ /* Check the JNI version. */
- switch (version) {
- case JNI_VERSION_1_1:
- case JNI_VERSION_1_2:
- case JNI_VERSION_1_4:
- *env = _Jv_env;
+ if (jni_version_check(version) == true) {
+ *env = VM_get_jnienv();
return JNI_OK;
-
- default:
- ;
}
#if defined(ENABLE_JVMTI)
*******************************************************************************/
-jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
+jint jni_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
{
- STATISTICS(jniinvokation());
+ int result;
+
+ TRACEJNICALLS(("jni_AttachCurrentThreadAsDaemon(vm=%p, penv=%p, args=%p)", vm, penv, args));
- return jni_attach_current_thread(penv, args, true);
+ if (VM_is_created() == false)
+ return JNI_ERR;
+
+ result = jni_attach_current_thread(penv, args, true);
+
+ return result;
}
NULL,
_Jv_JNI_DestroyJavaVM,
- _Jv_JNI_AttachCurrentThread,
- _Jv_JNI_DetachCurrentThread,
- _Jv_JNI_GetEnv,
- _Jv_JNI_AttachCurrentThreadAsDaemon
+ jni_AttachCurrentThread,
+ jni_DetachCurrentThread,
+ jni_GetEnv,
+ jni_AttachCurrentThreadAsDaemon
};
_Jv_JNI_GetVersion,
_Jv_JNI_DefineClass,
- _Jv_JNI_FindClass,
- _Jv_JNI_FromReflectedMethod,
- _Jv_JNI_FromReflectedField,
+ jni_FindClass,
+ jni_FromReflectedMethod,
+ jni_FromReflectedField,
_Jv_JNI_ToReflectedMethod,
_Jv_JNI_GetSuperclass,
_Jv_JNI_IsAssignableFrom,
_Jv_JNI_Throw,
_Jv_JNI_ThrowNew,
_Jv_JNI_ExceptionOccurred,
- _Jv_JNI_ExceptionDescribe,
- _Jv_JNI_ExceptionClear,
+ jni_ExceptionDescribe,
+ jni_ExceptionClear,
_Jv_JNI_FatalError,
- _Jv_JNI_PushLocalFrame,
- _Jv_JNI_PopLocalFrame,
+ jni_PushLocalFrame,
+ jni_PopLocalFrame,
- _Jv_JNI_NewGlobalRef,
- _Jv_JNI_DeleteGlobalRef,
- _Jv_JNI_DeleteLocalRef,
+ jni_NewGlobalRef,
+ jni_DeleteGlobalRef,
+ jni_DeleteLocalRef,
_Jv_JNI_IsSameObject,
- _Jv_JNI_NewLocalRef,
- _Jv_JNI_EnsureLocalCapacity,
+ jni_NewLocalRef,
+ jni_EnsureLocalCapacity,
_Jv_JNI_AllocObject,
- _Jv_JNI_NewObject,
+ jni_NewObject,
_Jv_JNI_NewObjectV,
_Jv_JNI_NewObjectA,
_Jv_JNI_GetJavaVM,
- /* new JNI 1.2 functions */
+ /* New JNI 1.2 functions. */
_Jv_JNI_GetStringRegion,
_Jv_JNI_GetStringUTFRegion,
- _Jv_JNI_GetPrimitiveArrayCritical,
- _Jv_JNI_ReleasePrimitiveArrayCritical,
+ jni_GetPrimitiveArrayCritical,
+ jni_ReleasePrimitiveArrayCritical,
_Jv_JNI_GetStringCritical,
_Jv_JNI_ReleaseStringCritical,
_Jv_JNI_ExceptionCheck,
- /* new JNI 1.4 functions */
+ /* New JNI 1.4 functions. */
- _Jv_JNI_NewDirectByteBuffer,
+ jni_NewDirectByteBuffer,
_Jv_JNI_GetDirectBufferAddress,
- _Jv_JNI_GetDirectBufferCapacity
+ _Jv_JNI_GetDirectBufferCapacity,
+
+ /* New JNI 1.6 functions. */
+
+ jni_GetObjectRefType
};
jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
{
- TRACEJNICALLS("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs);
+ TRACEJNICALLS(("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs));
if (bufLen <= 0)
return JNI_ERR;
/* We currently only support 1 VM running. */
- vmBuf[0] = (JavaVM *) _Jv_jvm;
+ vmBuf[0] = VM_get_javavm();
*nVMs = 1;
return JNI_OK;
jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
{
- TRACEJNICALLS("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args);
+ TRACEJNICALLS(("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args));
/* actually create the JVM */
- if (!vm_createjvm(p_vm, p_env, vm_args))
+ if (!VM_create(p_vm, p_env, vm_args))
return JNI_ERR;
return JNI_OK;