You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by va...@apache.org on 2006/11/13 08:21:53 UTC
svn commit: r474177 - in /incubator/harmony/enhanced/drlvm/trunk:
src/test/jni/ src/test/jni/nio/ vm/port/include/ vm/vmcore/include/
vm/vmcore/src/init/ vm/vmcore/src/jni/
Author: varlax
Date: Sun Nov 12 23:21:52 2006
New Revision: 474177
URL: http://svn.apache.org/viewvc?view=rev&rev=474177
Log:
Fixed JNI NIO support:
VM just provides no-impl stubs which are replaced by hynio functions at VM bootstrap.
Corresponding test added.
Tested on WinXP, SUSE9.
Added:
incubator/harmony/enhanced/drlvm/trunk/src/test/jni/
incubator/harmony/enhanced/drlvm/trunk/src/test/jni/nio/
incubator/harmony/enhanced/drlvm/trunk/src/test/jni/nio/DirectByteBufferTest.c
incubator/harmony/enhanced/drlvm/trunk/src/test/jni/nio/DirectByteBufferTest.java
Modified:
incubator/harmony/enhanced/drlvm/trunk/vm/port/include/port_dso.h
incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jni_direct.h
incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_init.cpp
incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jni/jni.cpp
Added: incubator/harmony/enhanced/drlvm/trunk/src/test/jni/nio/DirectByteBufferTest.c
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/src/test/jni/nio/DirectByteBufferTest.c?view=auto&rev=474177
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/src/test/jni/nio/DirectByteBufferTest.c (added)
+++ incubator/harmony/enhanced/drlvm/trunk/src/test/jni/nio/DirectByteBufferTest.c Sun Nov 12 23:21:52 2006
@@ -0,0 +1,50 @@
+#include <jni.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+JNIEXPORT jstring JNICALL Java_DirectByteBufferTest_testValidBuffer0
+ (JNIEnv *, jobject);
+
+
+/*
+ * Class: DirectByteBufferTest
+ * Method: testValidBuffer0
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_DirectByteBufferTest_testValidBuffer0
+ (JNIEnv *jenv, jobject unused)
+{
+ char* error = (char*)calloc(256, 1);
+ const jlong BUF_SIZE = 100;
+ void* buf = malloc(BUF_SIZE);
+ jobject jbuf = (*jenv)->NewDirectByteBuffer(jenv, buf, BUF_SIZE);
+ void* addr = (*jenv)->GetDirectBufferAddress(jenv, jbuf);
+ jlong size = (*jenv)->GetDirectBufferCapacity(jenv, jbuf);
+ jstring jstr;
+ if (jbuf) {
+ if (addr != buf) {
+ sprintf(error, "invalid buffer address: expected %p but was %p\n", buf, addr);
+ }
+ if (size != BUF_SIZE) {
+ sprintf(error + strlen(error),
+ "invalid buffer capacity: expected %d but was %d\n", BUF_SIZE, size);
+ }
+ } else {
+ // access to direct buffers not supported
+ if (addr != NULL | size != -1) {
+ sprintf(error, "inconsistent NIO support:\n"
+ "NewDirectByteBuffer() returned NULL;\n"
+ "GetDirectBufferAddress() returned %p\n"
+ "GetDirectBufferCapacity() returned %d\n", addr, size);
+ } else {
+ sprintf(error, "no NIO support\n");
+ }
+ }
+
+ jstr = strlen(error) ? (*jenv)->NewStringUTF(jenv, error) : NULL;
+ free(buf);
+ free(error);
+
+ return jstr;
+}
Added: incubator/harmony/enhanced/drlvm/trunk/src/test/jni/nio/DirectByteBufferTest.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/src/test/jni/nio/DirectByteBufferTest.java?view=auto&rev=474177
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/src/test/jni/nio/DirectByteBufferTest.java (added)
+++ incubator/harmony/enhanced/drlvm/trunk/src/test/jni/nio/DirectByteBufferTest.java Sun Nov 12 23:21:52 2006
@@ -0,0 +1,27 @@
+
+public class DirectByteBufferTest {
+
+ static { System.loadLibrary("DirectByteBufferTest");}
+
+ public static void main(String[] args) {
+ new DirectByteBufferTest().testValidBuffer();
+ }
+
+ private native String testValidBuffer0();
+
+ public void testValidBuffer() {
+ assertNull(testValidBuffer0());
+ }
+
+ public void assertNull(Object o) {
+ if (o == null) {
+ System.out.println("PASSED");
+ } else {
+ fail(o.toString());
+ }
+ }
+
+ public void fail(String s) {
+ System.out.println("FAILED: " + s);
+ }
+}
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/port/include/port_dso.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/port/include/port_dso.h?view=diff&rev=474177&r1=474176&r2=474177
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/port/include/port_dso.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/port/include/port_dso.h Sun Nov 12 23:21:52 2006
@@ -31,6 +31,16 @@
extern "C" {
#endif
+/**
+ * Decorate shared library name (.dll <-> lib*.so).
+ * The "name" parameter should be double-quoted string.
+ * @non_apr
+ */
+#ifdef PLATFORM_POSIX
+# define PORT_DSO_NAME(name) "lib" name ".so"
+#elif PLATFORM_NT
+# define PORT_DSO_NAME(name) name ".dll"
+#endif
#define PORT_DSO_DEFAULT 0
#define PORT_DSO_BIND_NOW 0x1
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jni_direct.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jni_direct.h?view=diff&rev=474177&r1=474176&r2=474177
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jni_direct.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jni_direct.h Sun Nov 12 23:21:52 2006
@@ -592,9 +592,10 @@
VMEXPORT jobject JNICALL ToReflectedMethod(JNIEnv *env, jclass cls, jmethodID methodID, jboolean isStatic);
VMEXPORT jobject JNICALL ToReflectedField(JNIEnv *env, jclass cls, jfieldID fieldID, jboolean isStatic);
-VMEXPORT jobject JNICALL NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity);
-VMEXPORT void* JNICALL GetDirectBufferAddress(JNIEnv* env, jobject buf);
-VMEXPORT jlong JNICALL GetDirectBufferCapacity(JNIEnv* env, jobject buf);
+// JNI NIO functions are imported from classlib thus no direct access to them
+//VMEXPORT jobject JNICALL NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity);
+//VMEXPORT void* JNICALL GetDirectBufferAddress(JNIEnv* env, jobject buf);
+//VMEXPORT jlong JNICALL GetDirectBufferCapacity(JNIEnv* env, jobject buf);
VMEXPORT jint JNICALL DestroyJavaVM(JavaVM*);
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_init.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_init.cpp?view=diff&rev=474177&r1=474176&r2=474177
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_init.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_init.cpp Sun Nov 12 23:21:52 2006
@@ -21,6 +21,8 @@
#include <apr_env.h>
#include <apr_general.h>
+#include <apr_dso.h>
+#include "port_dso.h"
#include "open/gc.h"
#include "open/thread_externals.h"
@@ -255,6 +257,45 @@
return JNI_OK;
}
+typedef void* (JNICALL *GDBA) (JNIEnv* env, jobject buf);
+typedef jobject (JNICALL *NDB)(JNIEnv* env, void* address, jlong capacity);
+typedef jlong (JNICALL *GDBC)(JNIEnv* env, jobject buf);
+
+/**
+ * Imports NIO functions to JNI functions table from hynio lib.
+ * Note: bootstrap classloader is picky to load classlib's natives earliest,
+ * so this should be called after bcl initialization.
+ */
+static jint populate_jni_nio() {
+ bool just_loaded;
+ NativeLoadStatus loading_status;
+ NativeLibraryHandle handle = natives_load_library(
+ PORT_DSO_NAME("hynio"), &just_loaded, &loading_status);
+ if (!handle || loading_status) {
+ char error_message[1024];
+ natives_describe_error(loading_status, error_message, sizeof(error_message));
+
+ WARN("Failed to initialize JNI NIO support: " << error_message);
+ return JNI_ERR;
+ }
+
+ apr_dso_handle_sym_t gdba, gdbc, ndb;
+ if( APR_SUCCESS == apr_dso_sym(&gdba, handle, "GetDirectBufferAddress")
+ && APR_SUCCESS == apr_dso_sym(&gdbc, handle, "GetDirectBufferCapacity")
+ && APR_SUCCESS == apr_dso_sym(&ndb, handle, "NewDirectByteBuffer") )
+ {
+ jni_vtable.GetDirectBufferAddress = (GDBA)gdba;
+ jni_vtable.GetDirectBufferCapacity = (GDBC)gdbc;
+ jni_vtable.NewDirectByteBuffer = (NDB)ndb;
+ return JNI_OK;
+ }
+ else
+ {
+ WARN("Failed to import JNI NIO functions.");
+ return JNI_ERR;
+ }
+}
+
/**
* Loads initial classes. For example j.l.Object, j.l.Class, etc.
*/
@@ -663,6 +704,8 @@
status = preload_classes(vm_env);
if (status != JNI_OK) return status;
+ populate_jni_nio();
+
// Now the thread is attached to VM and it is valid to disable it.
hythread_suspend_disable();
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jni/jni.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jni/jni.cpp?view=diff&rev=474177&r1=474176&r2=474177
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jni/jni.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jni/jni.cpp Sun Nov 12 23:21:52 2006
@@ -59,6 +59,10 @@
static void JNICALL UnimpStub(JNIEnv*);
jint JNICALL GetVersion(JNIEnv *);
+jobject JNICALL NewDirectByteBuffer(JNIEnv* , void* , jlong );
+void* JNICALL GetDirectBufferAddress(JNIEnv* , jobject );
+jlong JNICALL GetDirectBufferCapacity(JNIEnv* , jobject );
+
struct JNINativeInterface_ jni_vtable = {
(void*)UnimpStub,
@@ -1408,62 +1412,22 @@
return reflection_reflect_field(env, fieldID);
}
-VMEXPORT jobject JNICALL NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity)
+jobject JNICALL NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity)
{
- TRACE2("jni", "NewDirectByteBuffer called");
- jclass bbcl = FindClass(env, VM_Global_State::loader_env->JavaNioByteBuffer_String);
- if (NULL == bbcl)
- {
- exn_clear();
- return NULL;
- }
- jmethodID id = GetStaticMethodID(env, bbcl, "newDirectByteBuffer", "(JI)Ljava/nio/ByteBuffer;");
- if (NULL == id)
- {
- exn_clear();
- return NULL;
- }
- // There is an inconsistency between JNI and API specifications. JNI spec declares byte buffer
- // capacity as jlong. In the same time byte buffer capacity has int type in API spec.
- jobject bb = CallStaticObjectMethod(env, bbcl, id, (jlong)POINTER_SIZE_INT(address), (jint)capacity);
-
- return bb;
+ //no-impl stub replaced by classlib's func at VM startup
+ return NULL;
}
-VMEXPORT void* JNICALL GetDirectBufferAddress(JNIEnv* env, jobject buf)
+void* JNICALL GetDirectBufferAddress(JNIEnv* env, jobject buf)
{
- TRACE2("jni", "GetDirectBufferAddress called");
- jclass bbcl = FindClass(env, VM_Global_State::loader_env->JavaNioByteBuffer_String);
- if (NULL == bbcl)
- {
- exn_clear();
- return NULL;
- }
- jmethodID id = GetStaticMethodID(env, bbcl, "getDirectBufferAddress", "(Ljava/nio/ByteBuffer;)J");
- if (NULL == id)
- {
- exn_clear();
- return NULL;
- }
- return (void*)POINTER_SIZE_INT(CallStaticLongMethod(env, bbcl, id, buf));
+ //no-impl stub replaced by classlib's func at VM startup
+ return NULL;
}
-VMEXPORT jlong JNICALL GetDirectBufferCapacity(JNIEnv* env, jobject buf)
+jlong JNICALL GetDirectBufferCapacity(JNIEnv* env, jobject buf)
{
- TRACE2("jni", "GetDirectBufferCapacity called");
- jclass bbcl = FindClass(env, VM_Global_State::loader_env->JavaNioByteBuffer_String);
- if (NULL == bbcl)
- {
- exn_clear();
- return -1;
- }
- jmethodID id = GetStaticMethodID(env, bbcl, "getDirectBufferCapacity", "(Ljava/nio/ByteBuffer;)I");
- if (NULL == id)
- {
- exn_clear();
- return -1;
- }
- return (jlong)CallStaticIntMethod(env, bbcl, id, buf);
+ //no-impl stub replaced by classlib's func at VM startup
+ return -1;
}
/* BEGIN: Invocation API functions. */