You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ar...@apache.org on 2006/05/23 17:37:49 UTC

svn commit: r408937 - in /incubator/harmony/enhanced/jchevm/libjc: bootstrap.c definitions.h gc_root.c gc_scan.c jni_native.c libjc.h native_ref.c structures.h thread.c vm.c

Author: archie
Date: Tue May 23 08:37:48 2006
New Revision: 408937

URL: http://svn.apache.org/viewvc?rev=408937&view=rev
Log:
Implement JNI methods NewWeakGlobalRef() and DeleteWeakGlobalRef().

Modified:
    incubator/harmony/enhanced/jchevm/libjc/bootstrap.c
    incubator/harmony/enhanced/jchevm/libjc/definitions.h
    incubator/harmony/enhanced/jchevm/libjc/gc_root.c
    incubator/harmony/enhanced/jchevm/libjc/gc_scan.c
    incubator/harmony/enhanced/jchevm/libjc/jni_native.c
    incubator/harmony/enhanced/jchevm/libjc/libjc.h
    incubator/harmony/enhanced/jchevm/libjc/native_ref.c
    incubator/harmony/enhanced/jchevm/libjc/structures.h
    incubator/harmony/enhanced/jchevm/libjc/thread.c
    incubator/harmony/enhanced/jchevm/libjc/vm.c

Modified: incubator/harmony/enhanced/jchevm/libjc/bootstrap.c
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/jchevm/libjc/bootstrap.c?rev=408937&r1=408936&r2=408937&view=diff
==============================================================================
--- incubator/harmony/enhanced/jchevm/libjc/bootstrap.c (original)
+++ incubator/harmony/enhanced/jchevm/libjc/bootstrap.c Tue May 23 08:37:48 2006
@@ -343,7 +343,7 @@
 
 		/* Wrap it in a global native reference */
 		if ((ref = _jc_new_global_native_ref(env,
-		    vm->boot.objects.vmex[i])) == NULL) {
+		    vm->boot.objects.vmex[i], JNI_FALSE)) == NULL) {
 			_jc_post_exception_info(env);
 			goto fail;
 		}

Modified: incubator/harmony/enhanced/jchevm/libjc/definitions.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/jchevm/libjc/definitions.h?rev=408937&r1=408936&r2=408937&view=diff
==============================================================================
--- incubator/harmony/enhanced/jchevm/libjc/definitions.h (original)
+++ incubator/harmony/enhanced/jchevm/libjc/definitions.h Tue May 23 08:37:48 2006
@@ -395,9 +395,18 @@
 	(((frame)->flags & _JC_NATIVE_REF_FREE_BITS)			\
 	    != _JC_NATIVE_REF_FREE_BITS)
 #define _JC_NATIVE_REF_MARK_FREE(frame, i)				\
-	((frame)->flags |= (1 << (i + 3)))
-#define _JC_NATIVE_REF_MARK_IN_USE(frame, i)				\
-	((frame)->flags &= ~(1 << (i + 3)))
+    do {								\
+	((frame)->flags |= (1 << (i + 3)));				\
+	((frame)->weak &= (1 << (i + 3)));				\
+    } while (0)
+#define _JC_NATIVE_REF_MARK_IN_USE(frame, i, weak)			\
+    do {								\
+	((frame)->flags &= ~(1 << (i + 3)));				\
+	if (weak)							\
+	    ((frame)->weak |= (1 << (i + 3)));				\
+    } while (0)
+#define _JC_NATIVE_REF_IS_WEAK(frame, i)				\
+	(((frame)->weak & (1 << (i + 3))) != 0)
 
 /* Size of one page */
 #define _JC_PAGE_SIZE			(1 << _JC_PAGE_SHIFT)

Modified: incubator/harmony/enhanced/jchevm/libjc/gc_root.c
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/jchevm/libjc/gc_root.c?rev=408937&r1=408936&r2=408937&view=diff
==============================================================================
--- incubator/harmony/enhanced/jchevm/libjc/gc_root.c (original)
+++ incubator/harmony/enhanced/jchevm/libjc/gc_root.c Tue May 23 08:37:48 2006
@@ -120,7 +120,7 @@
 /*
  * Compute the root set of references. Returns the number of references,
  * or -1 if there was an error. The caller must free the returned array.
- * Ths stack of the current thread must be clipped.
+ * The stack of the current thread must be clipped.
  *
  * If unsuccessful an exception is stored.
  *
@@ -365,6 +365,8 @@
 
 /*
  * Walk all objects in a native reference list.
+ *
+ * We skip JNI weak references; they're handled explicitly in the GC scan.
  */
 static int
 _jc_root_walk_native_refs(_jc_native_frame_list *list, _jc_object ***refsp)
@@ -381,9 +383,10 @@
 		if (!_JC_NATIVE_REF_ANY_USED(frame))
 			continue;
 
-		/* Iterate references in this frame */
+		/* Iterate non-weak references in this frame */
 		for (i = 0; i < _JC_NATIVE_REFS_PER_FRAME; i++) {
-			if (!_JC_NATIVE_REF_IS_FREE(frame, i)) {
+			if (!_JC_NATIVE_REF_IS_FREE(frame, i)
+			    && !_JC_NATIVE_REF_IS_WEAK(frame, i)) {
 				_jc_object *const obj = frame->refs[i];
 
 				if (obj != NULL) {

Modified: incubator/harmony/enhanced/jchevm/libjc/gc_scan.c
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/jchevm/libjc/gc_scan.c?rev=408937&r1=408936&r2=408937&view=diff
==============================================================================
--- incubator/harmony/enhanced/jchevm/libjc/gc_scan.c (original)
+++ incubator/harmony/enhanced/jchevm/libjc/gc_scan.c Tue May 23 08:37:48 2006
@@ -50,6 +50,7 @@
 	_jc_trace_info *trace = NULL;
 	struct timeval start_time;
 	_jc_class_loader *loader;
+	_jc_native_frame *frame;
 	char *last_small_page;
 	int root_set_length;
 	_jc_heap_sweep sweep;
@@ -229,6 +230,28 @@
 		trace->num_finalizable = num_finalizable;
 	}
 
+	/* Clear JNI weak references pointing to unreachable objects */
+	SLIST_FOREACH(frame, &vm->native_globals, link) {
+
+		/* Skip empty frames */
+		if (!_JC_NATIVE_REF_ANY_USED(frame))
+			continue;
+
+		/* Look for any weak references in this frame */
+		for (i = 0; i < _JC_NATIVE_REFS_PER_FRAME; i++) {
+			if (_JC_NATIVE_REF_IS_WEAK(frame, i)) {
+				_jc_object *const obj = frame->refs[i];
+
+				/* Sanity check */
+				_JC_ASSERT(!_JC_NATIVE_REF_IS_FREE(frame, i));
+
+				/* If not keepable, clear the reference */
+				if (!_JC_LW_TEST(obj->lockword, KEEP))
+					_JC_NATIVE_REF_MARK_FREE(frame, i);
+			}
+		}
+	}
+
 	/* Now recycle unreachable blocks and pages */
 	_jc_heap_sweep_init(heap, &sweep);
 	last_small_page = NULL;
@@ -517,8 +540,7 @@
 	if (!_JC_IN_HEAP(trace->heap, obj)) {
 
 		/* Is object already marked? */
-		if ((lockword & _JC_LW_VISITED_BIT)
-		    == trace->gc_stack_visited)
+		if ((lockword & _JC_LW_VISITED_BIT) == trace->gc_stack_visited)
 		    	return 1;
 
 		/* Sanity check that this is the first GC cycle */

Modified: incubator/harmony/enhanced/jchevm/libjc/jni_native.c
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/jchevm/libjc/jni_native.c?rev=408937&r1=408936&r2=408937&view=diff
==============================================================================
--- incubator/harmony/enhanced/jchevm/libjc/jni_native.c (original)
+++ incubator/harmony/enhanced/jchevm/libjc/jni_native.c Tue May 23 08:37:48 2006
@@ -923,7 +923,7 @@
 	 * at the beginning of the buffer.				\
 	 */								\
 	if ((buf->l = _jc_new_global_native_ref(env,			\
-	    (_jc_object *)a)) == NULL) {				\
+	    (_jc_object *)a, JNI_FALSE)) == NULL) {			\
 		_jc_post_exception_info(env);				\
 		_jc_vm_free(&buf);					\
 		goto done;						\
@@ -1291,7 +1291,7 @@
 	_jc_resuming_java(env, &cstack);
 
 	/* Get new reference */
-	if ((ref = _jc_new_global_native_ref(env, *obj)) == NULL)
+	if ((ref = _jc_new_global_native_ref(env, *obj, JNI_FALSE)) == NULL)
 		_jc_post_exception_info(env);
 
 	/* Returning to native code */
@@ -1358,23 +1358,26 @@
 {
 	_jc_env *const env = _JC_JNI2ENV(jenv);
 	_jc_c_stack cstack;
+	jobject ref;
 
 	/* Returning from native code */
 	_jc_resuming_java(env, &cstack);
 
-	_jc_fatal_error(env->vm, "%s: unimplemented", __FUNCTION__);
+	/* Get new weak global reference */
+	if ((ref = _jc_new_global_native_ref(env, *obj, JNI_TRUE)) == NULL)
+		_jc_post_exception_info(env);
+
+	/* Returning to native code */
+	_jc_stopping_java(env, &cstack, NULL);
+
+	/* Done */
+	return ref;
 }
 
 static void
 DeleteWeakGlobalRef(JNIEnv *jenv, jweak obj)
 {
-	_jc_env *const env = _JC_JNI2ENV(jenv);
-	_jc_c_stack cstack;
-
-	/* Returning from native code */
-	_jc_resuming_java(env, &cstack);
-
-	_jc_fatal_error(env->vm, "%s: unimplemented", __FUNCTION__);
+	DeleteGlobalRef(jenv, obj);
 }
 
 static jint

Modified: incubator/harmony/enhanced/jchevm/libjc/libjc.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/jchevm/libjc/libjc.h?rev=408937&r1=408936&r2=408937&view=diff
==============================================================================
--- incubator/harmony/enhanced/jchevm/libjc/libjc.h (original)
+++ incubator/harmony/enhanced/jchevm/libjc/libjc.h Tue May 23 08:37:48 2006
@@ -337,7 +337,7 @@
 extern _jc_object	*_jc_free_local_native_ref(jobject *obj);
 extern void		_jc_free_all_native_local_refs(_jc_env *env);
 extern jobject		_jc_new_global_native_ref(_jc_env *env,
-				_jc_object *obj);
+				_jc_object *obj, jboolean weak);
 extern _jc_object	*_jc_free_global_native_ref(jobject *obj);
 extern void		_jc_free_all_native_global_refs(_jc_jvm *vm);
 extern jint		_jc_push_local_native_frame(_jc_env *env, int num_refs);

Modified: incubator/harmony/enhanced/jchevm/libjc/native_ref.c
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/jchevm/libjc/native_ref.c?rev=408937&r1=408936&r2=408937&view=diff
==============================================================================
--- incubator/harmony/enhanced/jchevm/libjc/native_ref.c (original)
+++ incubator/harmony/enhanced/jchevm/libjc/native_ref.c Tue May 23 08:37:48 2006
@@ -15,7 +15,7 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  *
- * $Id: native_ref.c,v 1.3 2004/07/05 21:03:27 archiecobbs Exp $
+ * $Id$
  */
 
 #include "libjc.h"
@@ -33,7 +33,8 @@
  * Internal functions
  */
 static void		_jc_pop_native_frame(_jc_native_frame_list *list);
-static jobject		_jc_new_native_ref(_jc_native_frame *frame);
+static jobject		_jc_new_native_ref(_jc_native_frame *frame,
+				jboolean weak);
 static void		_jc_free_native_ref(jobject obj);
 
 /*
@@ -55,7 +56,7 @@
 
 	/* Find a free reference in the current local native reference frame */
 	SLIST_FOREACH(frame, &env->native_locals, link) {
-		if ((ref = _jc_new_native_ref(frame)) != NULL)
+		if ((ref = _jc_new_native_ref(frame, JNI_FALSE)) != NULL)
 			break;
 		if ((frame->flags & _JC_NATIVE_REF_EXTENSION) == 0)
 			break;
@@ -119,7 +120,7 @@
  * NOTE: The global VM mutex should not be acquired when calling this.
  */
 jobject
-_jc_new_global_native_ref(_jc_env *env, _jc_object *obj)
+_jc_new_global_native_ref(_jc_env *env, _jc_object *obj, jboolean weak)
 {
 	_jc_jvm *const vm = env->vm;
 	_jc_native_frame *frame;
@@ -135,7 +136,7 @@
 
 	/* Find a free reference in any global native reference frame */
 	SLIST_FOREACH(frame, &vm->native_globals, link) {
-		if ((ref = _jc_new_native_ref(frame)) != NULL)
+		if ((ref = _jc_new_native_ref(frame, weak)) != NULL)
 			break;
 	}
 
@@ -144,7 +145,7 @@
 		if ((frame = _jc_add_native_frame(env,
 		    &vm->native_globals)) == NULL)
 			goto fail;
-		ref = _jc_new_native_ref(frame);
+		ref = _jc_new_native_ref(frame, weak);
 		_JC_ASSERT(ref != NULL);
 	}
 
@@ -370,7 +371,7 @@
  * Returns NULL (without posting any exceptions) if unable.
  */
 static jobject
-_jc_new_native_ref(_jc_native_frame *frame)
+_jc_new_native_ref(_jc_native_frame *frame, jboolean weak)
 {
 	int i;
 
@@ -385,7 +386,7 @@
 	_JC_ASSERT(i >= 0 && i < _JC_NATIVE_REFS_PER_FRAME);
 
 	/* Mark reference in use */
-	_JC_NATIVE_REF_MARK_IN_USE(frame, i);
+	_JC_NATIVE_REF_MARK_IN_USE(frame, i, weak);
 
 	/* Done */
 	return &frame->refs[i];

Modified: incubator/harmony/enhanced/jchevm/libjc/structures.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/jchevm/libjc/structures.h?rev=408937&r1=408936&r2=408937&view=diff
==============================================================================
--- incubator/harmony/enhanced/jchevm/libjc/structures.h (original)
+++ incubator/harmony/enhanced/jchevm/libjc/structures.h Tue May 23 08:37:48 2006
@@ -159,6 +159,7 @@
  */
 struct _jc_native_frame {
 	SLIST_ENTRY(_jc_native_frame)	link;
+	_jc_word			weak;	/* for JNI weak global refs */
 	_jc_word			flags;
 	_jc_object			*refs[_JC_NATIVE_REFS_PER_FRAME];
 };

Modified: incubator/harmony/enhanced/jchevm/libjc/thread.c
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/jchevm/libjc/thread.c?rev=408937&r1=408936&r2=408937&view=diff
==============================================================================
--- incubator/harmony/enhanced/jchevm/libjc/thread.c (original)
+++ incubator/harmony/enhanced/jchevm/libjc/thread.c Tue May 23 08:37:48 2006
@@ -1144,7 +1144,7 @@
 
 	/* Instantiate one and wrap in a global native reference */
 	if ((ref = _jc_new_global_native_ref(env,
-	    _jc_new_object(env, type))) == NULL) {
+	    _jc_new_object(env, type), JNI_FALSE)) == NULL) {
 		_jc_post_exception_info(env);
 		goto fail;
 	}

Modified: incubator/harmony/enhanced/jchevm/libjc/vm.c
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/jchevm/libjc/vm.c?rev=408937&r1=408936&r2=408937&view=diff
==============================================================================
--- incubator/harmony/enhanced/jchevm/libjc/vm.c (original)
+++ incubator/harmony/enhanced/jchevm/libjc/vm.c Tue May 23 08:37:48 2006
@@ -193,7 +193,7 @@
 
 	/* Wrap it in a global native reference */
 	if (_jc_new_global_native_ref(env,
-	    vm->boot.objects.systemThreadGroup) == NULL)
+	    vm->boot.objects.systemThreadGroup, JNI_FALSE) == NULL)
 		goto fail;
 
 	/* Create java.lang.Thread instance for this thread */