Return-Path: Delivered-To: apmail-incubator-harmony-commits-archive@www.apache.org Received: (qmail 44974 invoked from network); 23 May 2006 15:38:13 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 23 May 2006 15:38:13 -0000 Received: (qmail 50658 invoked by uid 500); 23 May 2006 15:38:13 -0000 Delivered-To: apmail-incubator-harmony-commits-archive@incubator.apache.org Received: (qmail 50617 invoked by uid 500); 23 May 2006 15:38:12 -0000 Mailing-List: contact harmony-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: harmony-dev@incubator.apache.org Delivered-To: mailing list harmony-commits@incubator.apache.org Received: (qmail 50601 invoked by uid 99); 23 May 2006 15:38:12 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 23 May 2006 08:38:12 -0700 X-ASF-Spam-Status: No, hits=0.6 required=10.0 tests=NO_REAL_NAME X-Spam-Check-By: apache.org Received-SPF: pass (asf.osuosl.org: local policy) Received: from [140.211.166.113] (HELO eris.apache.org) (140.211.166.113) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 23 May 2006 08:38:11 -0700 Received: by eris.apache.org (Postfix, from userid 65534) id 223651A983A; Tue, 23 May 2006 08:37:51 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: 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 Date: Tue, 23 May 2006 15:37:49 -0000 To: harmony-commits@incubator.apache.org From: archie@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20060523153751.223651A983A@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N 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 */