[kaffe] CVS kaffe (guilhem): Fixlets for the finalisation of weakly referenced objects.
Kaffe CVS
cvs-commits at kaffe.org
Sun Feb 13 08:56:41 PST 2005
PatchSet 5522
Date: 2005/02/13 16:51:35
Author: guilhem
Branch: HEAD
Tag: (none)
Log:
Fixlets for the finalisation of weakly referenced objects.
Members:
ChangeLog:1.3566->1.3567
kaffe/kaffevm/kaffe-gc/gc-incremental.c:1.18->1.19
kaffe/kaffevm/systems/unix-pthreads/lock-impl.c:1.18->1.19
Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.3566 kaffe/ChangeLog:1.3567
--- kaffe/ChangeLog:1.3566 Sun Feb 13 16:20:37 2005
+++ kaffe/ChangeLog Sun Feb 13 16:51:35 2005
@@ -1,3 +1,13 @@
+2005-02-13 Guilhem Lavaux <guilhem at kaffe.org>
+
+ * kaffe/kaffevm/kaffe-gc/gc-incremental.c
+ (finaliserMan): Splitted into finaliserMan and finaliserJob.
+ (clearStack): Removed.
+ (gcMarkAddress): Removed debug printf.
+
+ * kaffe/kaffevm/systems/unix-pthreads/lock-impl.c
+ (jthread_condwait): Removed debug printf.
+
2005-02-12 Guilhem Lavaux <guilhem at kaffe.org>
* config/sparc/sysdepCallMethod.h
Index: kaffe/kaffe/kaffevm/kaffe-gc/gc-incremental.c
diff -u kaffe/kaffe/kaffevm/kaffe-gc/gc-incremental.c:1.18 kaffe/kaffe/kaffevm/kaffe-gc/gc-incremental.c:1.19
--- kaffe/kaffe/kaffevm/kaffe-gc/gc-incremental.c:1.18 Sun Jan 30 12:42:44 2005
+++ kaffe/kaffe/kaffevm/kaffe-gc/gc-incremental.c Sun Feb 13 16:51:37 2005
@@ -46,6 +46,7 @@
/* Avoid recursively allocating OutOfMemoryError */
#define OOM_ALLOCATING ((void *) -1)
+#define STACK_SWEEP_MARGIN 1024
#define GCSTACKSIZE 16384
#define FINALIZERSTACKSIZE THREADSTACKSIZE
@@ -305,8 +306,6 @@
/* Get block info for this memory - if it exists */
info = gc_mem2block(mem);
unit = UTOUNIT(mem);
- if (mem == 0x832e3b4)
- dprintf("marked bad mem\n");
if (gc_heap_isobject(info, unit)) {
markObjectDontCheck(unit, info, GCMEM2IDX(info, unit));
}
@@ -868,90 +867,96 @@
* the objects in turn. An object is only finalised once after which
* it is deleted.
*/
-
-static void clearStack(void *stackMin, void *stackMax)
+static void finaliserJob(Collector *gcif, int *where)
{
- void *p = alloca(1024);
-
- memset(p, 0, 1024);
+ gc_block* info = NULL;
+ gc_unit* unit = NULL;
+ int idx = 0;
+ void *stack;
+#define iLockRoot (*where)
+
+ /*
+ * Loop until the list of objects whose finaliser needs to be run is empty
+ * [ checking the condition without holding a lock is ok, since we're the only
+ * thread removing elements from the list (the list can never shrink during
+ * a gc pass) ].
+ *
+ * According to the spec, the finalisers have to be run without any user
+ * visible locks held. Therefore, we must temporarily release the finman
+ * lock and may not hold the gc_lock while running the finalisers as they
+ * are exposed to the user by java.lang.Runtime.
+ *
+ * In addition, we must prevent an object and everything it references from
+ * being collected while the finaliser is run (since we can't hold the gc_lock,
+ * there may be several gc passes in the meantime). To do so, we keep the
+ * object in the finalise list and only remove it from there when its
+ * finaliser is done (simply adding the object to the grey list while its
+ * finaliser is run only works as long as there's at most one gc pass).
+ *
+ * In order to determine the finaliser of an object, we have to access the
+ * gc_block that contains it and its index. Doing this without holding a
+ * lock only works as long as both, the gc_blocks and the indices of the
+ * objects in a gc_block, are constant.
+ */
+ while (gclists[finalise].cnext != &gclists[finalise]) {
+ unit = gclists[finalise].cnext;
+ info = gc_mem2block(unit);
+ idx = GCMEM2IDX(info, unit);
+
+ /* Call finaliser */
+ unlockStaticMutex(&finman);
+ (*gcFunctions[KGC_GET_FUNCS(info,idx)].final)(gcif, UTOMEM(unit));
+ lockStaticMutex(&finman);
+
+ /* and remove unit from the finaliser list */
+ lockStaticMutex(&gc_lock);
+ UREMOVELIST(unit);
+ UAPPENDLIST(gclists[nofin_white], unit);
+
+ gcStats.finalmem -= GCBLOCKSIZE(info);
+ gcStats.finalobj -= 1;
+
+ assert(KGC_GET_STATE(info,idx) == KGC_STATE_INFINALIZE);
+ /* Objects are only finalised once */
+ KGC_SET_STATE(info, idx, KGC_STATE_FINALIZED);
+ KGC_SET_COLOUR(info, idx, KGC_COLOUR_WHITE);
+ unlockStaticMutex(&gc_lock);
+ }
+ info = NULL;
+ unit = NULL;
+ idx = 0;
+
+ /* This cleans STACK_SWEEP_MARGIN bytes on the stack. This is needed
+ * because some objects may still lie on our stack.
+ */
+ stack = alloca(STACK_SWEEP_MARGIN);
+
+ memset((void *)((uintp)stack), 0, STACK_SWEEP_MARGIN);
+#undef iLockRoot
}
static void NONRETURNING
finaliserMan(void* arg)
{
- gc_block* info;
- gc_unit* unit;
- int idx;
- Collector *gcif = (Collector*)arg;
- int iLockRoot;
-
-
- lockStaticMutex(&finman);
- for (;;) {
-
- finalRunning = false;
- while (finalRunning == false) {
- waitStaticCond(&finman, (jlong)0);
- }
- assert(finalRunning == true);
-
- /*
- * Loop until the list of objects whose finaliser needs to be run is empty
- * [ checking the condition without holding a lock is ok, since we're the only
- * thread removing elements from the list (the list can never shrink during
- * a gc pass) ].
- *
- * According to the spec, the finalisers have to be run without any user
- * visible locks held. Therefore, we must temporarily release the finman
- * lock and may not hold the gc_lock while running the finalisers as they
- * are exposed to the user by java.lang.Runtime.
- *
- * In addition, we must prevent an object and everything it references from
- * being collected while the finaliser is run (since we can't hold the gc_lock,
- * there may be several gc passes in the meantime). To do so, we keep the
- * object in the finalise list and only remove it from there when its
- * finaliser is done (simply adding the object to the grey list while its
- * finaliser is run only works as long as there's at most one gc pass).
- *
- * In order to determine the finaliser of an object, we have to access the
- * gc_block that contains it and its index. Doing this without holding a
- * lock only works as long as both, the gc_blocks and the indices of the
- * objects in a gc_block, are constant.
- */
- while (gclists[finalise].cnext != &gclists[finalise]) {
- unit = gclists[finalise].cnext;
- info = gc_mem2block(unit);
- idx = GCMEM2IDX(info, unit);
-
- /* Call finaliser */
- unlockStaticMutex(&finman);
- (*gcFunctions[KGC_GET_FUNCS(info,idx)].final)(gcif, UTOMEM(unit));
- lockStaticMutex(&finman);
-
- /* and remove unit from the finaliser list */
- lockStaticMutex(&gc_lock);
- UREMOVELIST(unit);
- UAPPENDLIST(gclists[nofin_white], unit);
-
- gcStats.finalmem -= GCBLOCKSIZE(info);
- gcStats.finalobj -= 1;
-
- assert(KGC_GET_STATE(info,idx) == KGC_STATE_INFINALIZE);
- /* Objects are only finalised once */
- KGC_SET_STATE(info, idx, KGC_STATE_FINALIZED);
- KGC_SET_COLOUR(info, idx, KGC_COLOUR_WHITE);
- unlockStaticMutex(&gc_lock);
- }
-
- /* Wake up anyone waiting for the finalizer to finish */
- {
- clearStack(NULL, NULL);
- }
- lockStaticMutex(&finmanend);
- broadcastStaticCond(&finmanend);
- unlockStaticMutex(&finmanend);
- }
- unlockStaticMutex(&finman);
+ Collector *gcif = (Collector*)arg;
+ int iLockRoot;
+
+ lockStaticMutex(&finman);
+ for (;;) {
+ finalRunning = false;
+ while (finalRunning == false) {
+ waitStaticCond(&finman, (jlong)0);
+ }
+ assert(finalRunning == true);
+
+ finaliserJob(gcif, &iLockRoot);
+
+ /* Wake up anyone waiting for the finalizer to finish */
+ lockStaticMutex(&finmanend);
+ broadcastStaticCond(&finmanend);
+ unlockStaticMutex(&finmanend);
+ }
+ unlockStaticMutex(&finman);
}
static
Index: kaffe/kaffe/kaffevm/systems/unix-pthreads/lock-impl.c
diff -u kaffe/kaffe/kaffevm/systems/unix-pthreads/lock-impl.c:1.18 kaffe/kaffe/kaffevm/systems/unix-pthreads/lock-impl.c:1.19
--- kaffe/kaffe/kaffevm/systems/unix-pthreads/lock-impl.c:1.18 Sun Feb 6 11:55:45 2005
+++ kaffe/kaffe/kaffevm/systems/unix-pthreads/lock-impl.c Sun Feb 13 16:51:37 2005
@@ -136,8 +136,6 @@
if ( timeout == NOTIMEOUT )
{
- if ((void *)0x827e6dc == cur)
- dprintf("stack ptr=%p\n", &status);
/* we handle this as "wait forever" */
status = ThreadCondWait(cur, cv, mux);
}
More information about the kaffe
mailing list