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.    */