You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ch...@apache.org on 2008/09/04 18:21:03 UTC

svn commit: r692136 - in /harmony/enhanced/drlvm/trunk/vm/vmcore: include/object_handles.h src/jni/jni.cpp src/object/object_handles.cpp

Author: chunrong
Date: Thu Sep  4 09:21:02 2008
New Revision: 692136

URL: http://svn.apache.org/viewvc?rev=692136&view=rev
Log:
apply 02_jni_weakref.patch in HARMONY-5946 [drlvm][jni] JNI weak global reference support

Modified:
    harmony/enhanced/drlvm/trunk/vm/vmcore/include/object_handles.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/jni/jni.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/object/object_handles.cpp

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/object_handles.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/object_handles.h?rev=692136&r1=692135&r2=692136&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/object_handles.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/object_handles.h Thu Sep  4 09:21:02 2008
@@ -155,6 +155,20 @@
  */
 void oh_enumerate_global_handles();
 
+/*
+ * Weak global handles
+ */
+
+/**
+ * Creates weak global handle, which needs to be explicitly freed.
+ */
+ObjectHandle oh_allocate_weak_global_handle_from_jni();
+/**
+ * Frees weak global handle.
+ */
+void oh_deallocate_weak_global_handle(ObjectHandle);
+/* For interface simplicity, weak global handles are also enumerated in function oh_enumerate_global_handles */
+
 //////////////////////////////////////////////////////////////////////////
 // Local Handles
 

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/jni/jni.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jni/jni.cpp?rev=692136&r1=692135&r2=692136&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/jni/jni.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/jni/jni.cpp Thu Sep  4 09:21:02 2008
@@ -970,13 +970,29 @@
         return JNI_TRUE;
     }
 
-    if(!(ref1 && ref2)) {
-        // One reference is null and the other is not.
-        return JNI_FALSE;
-    }
-
     ObjectHandle h1 = (ObjectHandle)ref1;
     ObjectHandle h2 = (ObjectHandle)ref2;
+    jboolean result;
+
+    if(!h1) {
+        assert(h2);
+        tmn_suspend_disable();
+        if(h2->object)
+            result = JNI_FALSE;
+        else    // h1 is NULL and h2 points to NULL object
+            result = JNI_TRUE;
+        tmn_suspend_enable();
+        return result;
+    } else if(!h2) {
+        assert(h1);
+        tmn_suspend_disable();
+        if(h1->object)
+            result = JNI_FALSE;
+        else    // h2 is NULL and h1 points to NULL object
+            result = JNI_TRUE;
+        tmn_suspend_enable();
+        return result;
+    }
 
     tmn_suspend_disable();       //---------------------------------v
 
@@ -985,7 +1001,7 @@
     TRACE2("jni-same", "IsSameObject: Obj1 = " << java_ref1->vt()->clss->get_name()->bytes <<
         " Obj2 = " << java_ref2->vt()->clss->get_name()->bytes <<
         " objects are " << ((java_ref1 == java_ref2) ? "same" : "different"));
-    jboolean result = (jboolean)((java_ref1 == java_ref2) ? JNI_TRUE : JNI_FALSE);
+    result = (jboolean)((java_ref1 == java_ref2) ? JNI_TRUE : JNI_FALSE);
 
     tmn_suspend_enable();        //---------------------------------^
 
@@ -1418,14 +1434,47 @@
 {
     TRACE("NewWeakGlobalRef called");
     assert(hythread_is_suspend_enabled());
-    return NewGlobalRef(jni_env, obj);
+    
+    if (exn_raised() || !obj) return NULL;
+
+    if(obj == NULL) {
+        return NULL;
+    }
+
+    assert(hythread_is_suspend_enabled());
+    ObjectHandle new_handle = oh_allocate_weak_global_handle_from_jni();
+
+    if (new_handle == NULL) {
+        return NULL;
+    }
+
+    ObjectHandle old_handle = (ObjectHandle)obj;
+
+    tmn_suspend_disable();       //---------------------------------v
+
+    new_handle->object = old_handle->object;
+    TRACE("NewWeakGlobalRef class = " << old_handle->object->vt()->clss);
+
+    tmn_suspend_enable();        //---------------------------------^
+
+    return (jweak)new_handle;
 }
 
 VMEXPORT void JNICALL DeleteWeakGlobalRef(JNIEnv * jni_env, jweak obj)
 {
     TRACE("DeleteWeakGlobalRef called");
     assert(hythread_is_suspend_enabled());
-    DeleteGlobalRef(jni_env, obj);
+    
+    if (obj == NULL) return;
+
+#ifdef _DEBUG
+    tmn_suspend_disable();
+    ObjectHandle h = (ObjectHandle)obj;
+    TRACE("DeleteGlobalRef class = " << h->object->vt()->clss);
+    tmn_suspend_enable();
+#endif
+
+    oh_deallocate_weak_global_handle((ObjectHandle)obj);
 }
 
 jboolean JNICALL ExceptionCheck(JNIEnv * jni_env)

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/object/object_handles.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/object/object_handles.cpp?rev=692136&r1=692135&r2=692136&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/object/object_handles.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/object/object_handles.cpp Thu Sep  4 09:21:02 2008
@@ -258,12 +258,90 @@
     STD_FREE(h);
 } //vm_delete_global_object_handle
 
+static void oh_enumerate_weak_global_handles();
+
 void oh_enumerate_global_handles()
 {
     TRACE2("enumeration", "enumerating global handles");
     for(ObjectHandlesOld* g = global_object_handles; g; g=g->next)
         if (g->handle.object)
             vm_enumerate_root_reference((void**)&g->handle.object, FALSE);
+    oh_enumerate_weak_global_handles();
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Weak Global Handles
+static ObjectHandlesOld* weak_global_object_handles = NULL;
+
+static ObjectHandle oh_allocate_weak_global_handle_internal()
+{
+    Global_Env * vm_env = VM_Global_State::loader_env;
+
+    // Allocate and init handle
+    ObjectHandlesOld* h = oh_allocate_object_handle(); //(ObjectHandlesOld*)m_malloc(sizeof(ObjectHandlesOld));
+
+    if (h == NULL)  {
+        return NULL;
+    }
+
+    h->handle.object = NULL;
+    h->allocated_on_the_stack = false;
+    
+    hythread_suspend_disable(); // ----------------vvv
+    vm_env->p_handle_lock->_lock(); 
+    // Insert at beginning of globals list
+    h->prev = NULL;
+    h->next = weak_global_object_handles;
+    weak_global_object_handles = h;
+    if(h->next)
+        h->next->prev = h;
+    vm_env->p_handle_lock->_unlock();
+    hythread_suspend_enable(); //--------------------------------------------^^^
+    return &h->handle;
+} //vm_create_weak_global_object_handle
+
+ObjectHandle oh_allocate_weak_global_handle_from_jni()
+{
+    ObjectHandle res = oh_allocate_weak_global_handle_internal();
+
+    if (res == NULL) {
+        exn_raise_object(VM_Global_State::loader_env->java_lang_OutOfMemoryError);
+    }
+    return res;
+}
+
+static bool UNUSED is_weak_global_handle(ObjectHandle handle)
+{
+    for(ObjectHandlesOld* g = weak_global_object_handles; g; g=g->next)
+        if (g==(ObjectHandlesOld*)handle) return true;
+    return false;
+}
+
+void oh_deallocate_weak_global_handle(ObjectHandle handle)
+{
+    Global_Env * vm_env = VM_Global_State::loader_env;
+
+    tmn_suspend_disable(); // ----------vvv
+    vm_env->p_handle_lock->_lock();
+    assert(is_weak_global_handle(handle));
+
+    handle->object = NULL;
+    ObjectHandlesOld* h = (ObjectHandlesOld*)handle;
+    if (h->next) h->next->prev = h->prev;
+    if (h->prev) h->prev->next = h->next;
+    if (h==weak_global_object_handles) weak_global_object_handles = h->next;
+
+    vm_env->p_handle_lock->_unlock();
+    tmn_suspend_enable(); // -------------------------------------^^^
+    STD_FREE(h);
+} //vm_delete_global_object_handle
+
+static void oh_enumerate_weak_global_handles()
+{
+    TRACE2("enumeration", "enumerating weak global handles");
+    for(ObjectHandlesOld* g = weak_global_object_handles; g; g=g->next)
+        if (g->handle.object)
+            vm_enumerate_weak_root_reference((void**)&g->handle.object, FALSE);
 }
 
 //////////////////////////////////////////////////////////////////////////