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  <[EMAIL PROTECTED]>
+
+       * 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  <[EMAIL PROTECTED]>
 
        * 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);
     }

_______________________________________________
kaffe mailing list
kaffe@kaffe.org
http://kaffe.org/cgi-bin/mailman/listinfo/kaffe

Reply via email to