[project @ 1999-02-26 17:46:04 by simonm]
authorsimonm <unknown>
Fri, 26 Feb 1999 17:46:09 +0000 (17:46 +0000)
committersimonm <unknown>
Fri, 26 Feb 1999 17:46:09 +0000 (17:46 +0000)
Fix a bug in weak pointer support: if finalize is called on a weak
pointer, then a DEAD_WEAK object could appear on the weak pointer
list.

To avoid needing to double-link this list, add a link field to
DEAD_WEAK objects, and remove them from the list at garbage collection
time.

ghc/includes/Closures.h
ghc/rts/GC.c
ghc/rts/PrimOps.hc

index 23446c4..76aeecc 100644 (file)
@@ -1,5 +1,5 @@
 /* ----------------------------------------------------------------------------
- * $Id: Closures.h,v 1.9 1999/02/19 18:26:04 sewardj Exp $
+ * $Id: Closures.h,v 1.10 1999/02/26 17:46:04 simonm Exp $
  *
  * (c) The GHC Team, 1998-1999
  *
@@ -265,6 +265,11 @@ typedef struct _StgWeak {  /* Weak v */
   struct _StgWeak *link;
 } StgWeak;
 
+typedef struct _StgDeadWeak {  /* Weak v */
+  StgHeader header;
+  struct _StgWeak *link;
+} StgDeadWeak;
+
 /* Dynamic stack frames - these have a liveness mask in the object
  * itself, rather than in the info table.  Useful for generic heap
  * check code.
index 71048a1..64108c9 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: GC.c,v 1.44 1999/02/26 13:36:12 simonm Exp $
+ * $Id: GC.c,v 1.45 1999/02/26 17:46:08 simonm Exp $
  *
  * (c) The GHC Team 1998-1999
  *
@@ -758,6 +758,16 @@ traverse_weak_ptr_list(void)
       w = (StgWeak *)((StgEvacuated *)w)->evacuee;
       *last_w = w;
     }
+
+    /* There might be a DEAD_WEAK on the list if finalizeWeak# was
+     * called on a live weak pointer object.  Just remove it.
+     */
+    if (w->header.info == &DEAD_WEAK_info) {
+      next_w = ((StgDeadWeak *)w)->link;
+      *last_w = next_w;
+      continue;
+    }
+
     ASSERT(get_itbl(w)->type == WEAK);
 
     /* Now, check whether the key is reachable.
index 33e2d23..37af75f 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: PrimOps.hc,v 1.17 1999/02/26 12:46:48 simonm Exp $
+ * $Id: PrimOps.hc,v 1.18 1999/02/26 17:46:09 simonm Exp $
  *
  * (c) The GHC Team, 1998-1999
  *
@@ -348,10 +348,11 @@ FN_(finalizzeWeakzh_fast)
 {
   /* R1.p = weak ptr
    */
-  StgWeak *w;
+  StgDeadWeak *w;
+  StgClosure *f;
   FB_
   TICK_RET_UNBOXED_TUP(0);
-  w = (StgWeak *)R1.p;
+  w = (StgDeadWeak *)R1.p;
 
   /* already dead? */
   if (w->header.info == &DEAD_WEAK_info) {
@@ -360,12 +361,14 @@ FN_(finalizzeWeakzh_fast)
 
   /* kill it */
   w->header.info = &DEAD_WEAK_info;
+  f = ((StgWeak *)w)->finalizer;
+  w->link = ((StgWeak *)w)->link;
 
   /* return the finalizer */
-  if (w->finalizer == &NO_FINALIZER_closure) {
+  if (f == &NO_FINALIZER_closure) {
       RET_NP(0,&NO_FINALIZER_closure);
   } else {
-      RET_NP(1,w->finalizer);
+      RET_NP(1,f);
   }
   FE_
 }