Fixes PR131.
authorStefan Ring <stefan@complang.tuwien.ac.at>
Tue, 23 Jun 2009 13:13:04 +0000 (15:13 +0200)
committerStefan Ring <stefan@complang.tuwien.ac.at>
Tue, 23 Jun 2009 13:13:04 +0000 (15:13 +0200)
* 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.

src/threads/lock.cpp
src/threads/lock.hpp
src/vm/finalizer.cpp

index df007f1e82e7f5d13ef2903a9f6c2c7e4b926726..ae7bb874036d858dd59c9b74cd7f2f43786356ce 100644 (file)
@@ -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);
index 87519d98efce363dc34368eab5e5f94395a57447..07bd54b671a885a5a41ccf1524578c201ff0dcfc 100644 (file)
@@ -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
index cd14c484e4d6e0f68e349e09f379fc0f322976f3..7a4ecd4711e86c50f9beb68d519a9c8a9e506ff2 100644 (file)
@@ -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)