From: Stefan Ring Date: Tue, 23 Jun 2009 13:13:04 +0000 (+0200) Subject: Fixes PR131. X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=cacao.git;a=commitdiff_plain;h=081b5d0c4965aa1507e975990f2f9ea95471f440 Fixes PR131. * src/threads/lock.cpp: Remove lock records only after they have become absolutely unreachable. * src/threads/lock.hpp: Added lock_schedule_lockrecord_removal. * src/vm/finalizer.cpp: Schedule lock record removal. --- diff --git a/src/threads/lock.cpp b/src/threads/lock.cpp index df007f1e8..ae7bb8740 100644 --- a/src/threads/lock.cpp +++ b/src/threads/lock.cpp @@ -459,7 +459,14 @@ static lock_record_t *lock_hashtable_get(java_handle_t* o) #if defined(ENABLE_GC_BOEHM) /* register new finalizer to clean up the lock record */ - GC_REGISTER_FINALIZER(LLNI_DIRECT(o), lock_record_finalizer, 0, 0, 0); + GC_finalization_proc ofinal = 0; + GC_REGISTER_FINALIZER_UNREACHABLE(LLNI_DIRECT(o), lock_record_finalizer, 0, &ofinal, 0); + + /* There was a finalizer -- reinstall it. We do not want to disrupt the + normal finalizer operation. We hold the monitor on this object, so + this is thread-safe. */ + if (ofinal) + GC_REGISTER_FINALIZER(LLNI_DIRECT(o), ofinal, 0, 0, 0); #endif /* enter it in the hashtable */ @@ -483,6 +490,29 @@ static lock_record_t *lock_hashtable_get(java_handle_t* o) return lr; } +/* lock_schedule_lockrecord_removal ******************************************** + + Gives the locking system a chance to schedule the removal of an unused lock + record. This function is called after an object's finalizer has run. + + IN: + o....the object which has been finalized + +*******************************************************************************/ + +#if defined(ENABLE_GC_BOEHM) +void lock_schedule_lockrecord_removal(java_handle_t *o) +{ + Lockword* lockword = lock_lockword_get(o); + if (!lockword->is_fat_lock()) + /* there is no lock record */ + return; + + /* register new finalizer to clean up the lock record */ + GC_REGISTER_FINALIZER_UNREACHABLE(LLNI_DIRECT(o), lock_record_finalizer, 0, 0, 0); +} +#endif + /* lock_hashtable_remove ******************************************************* @@ -578,11 +608,6 @@ static void lock_record_finalizer(void *object, void *p) } #endif - /* check for a finalizer function */ - - if (c->finalizer != NULL) - finalizer_run(object, p); - /* remove the lock-record entry from the hashtable and free it */ lock_hashtable_remove(THREADOBJECT, o); diff --git a/src/threads/lock.hpp b/src/threads/lock.hpp index 87519d98e..07bd54b67 100644 --- a/src/threads/lock.hpp +++ b/src/threads/lock.hpp @@ -97,6 +97,10 @@ void lock_wait_for_object(java_handle_t *o, s8 millis, s4 nanos); void lock_notify_object(java_handle_t *o); void lock_notify_all_object(java_handle_t *o); +#if defined(ENABLE_GC_BOEHM) +void lock_schedule_lockrecord_removal(java_handle_t *o); +#endif + #ifdef __cplusplus } #endif diff --git a/src/vm/finalizer.cpp b/src/vm/finalizer.cpp index cd14c484e..7a4ecd471 100644 --- a/src/vm/finalizer.cpp +++ b/src/vm/finalizer.cpp @@ -34,6 +34,7 @@ #include "threads/condition.hpp" #include "threads/mutex.hpp" #include "threads/thread.hpp" +#include "threads/lock.hpp" #include "vm/jit/builtin.hpp" #include "vm/exceptions.hpp" @@ -220,6 +221,10 @@ void finalizer_run(void *o, void *p) /* if we had an exception in the finalizer, ignore it */ exceptions_clear_exception(); + +#if defined(ENABLE_GC_BOEHM) + lock_schedule_lockrecord_removal(h); +#endif } #if defined(__cplusplus)