[project @ 2005-10-21 14:02:17 by simonmar]
[ghc-hetmet.git] / ghc / includes / Updates.h
index a748a37..4bc6199 100644 (file)
@@ -157,6 +157,7 @@ extern void awakenBlockedQueue(StgBlockingQueueElement *q, StgClosure *node);
 
 #endif /* GRAN || PAR */
 
+
 /* -----------------------------------------------------------------------------
    Updates: lower-level macros which update a closure with an
    indirection to another closure.
@@ -184,8 +185,13 @@ extern void awakenBlockedQueue(StgBlockingQueueElement *q, StgClosure *node);
  * to point to itself, and the closure being updated should not
  * already have been updated (the mutable list will get messed up
  * otherwise).
+ *
+ * NB. We do *not* do this in SMP mode, because when we have the
+ * possibility of multiple threads entering the same closure, zeroing
+ * the slop in one of the threads would have a disastrous effect on
+ * the other (seen in the wild!).
  */
-#if !defined(DEBUG)
+#if !defined(DEBUG) || defined(SMP)
 
 #define DEBUG_FILL_SLOP(p) /* nothing */
 
@@ -193,24 +199,28 @@ extern void awakenBlockedQueue(StgBlockingQueueElement *q, StgClosure *node);
 
 #ifdef CMINUSMINUS
 
-#define DEBUG_FILL_SLOP(p)                     \
-  W_ inf;                                      \
-  W_ np;                                       \
-  W_ nw;                                       \
-  W_ i;                                                \
-  inf = %GET_STD_INFO(p);                      \
-  np = TO_W_(%INFO_PTRS(inf));                 \
-  nw = TO_W_(%INFO_NPTRS(inf));                        \
-  if (%INFO_TYPE(inf) != HALF_W_(THUNK_SELECTOR)) {    \
-    i = 0;                                     \
-    for:                                       \
-      if (i < np + nw) {                       \
-        StgClosure_payload(p,i) = 0;           \
-        i = i + 1;                             \
-        goto for;                              \
-      }                                                \
-  }
-
+#define DEBUG_FILL_SLOP(p)                                             \
+  W_ inf;                                                              \
+  W_ sz;                                                               \
+  W_ i;                                                                        \
+  inf = %GET_STD_INFO(p);                                              \
+  if (%INFO_TYPE(inf) == HALF_W_(THUNK_SELECTOR)) {                    \
+       StgThunk_payload(p,0) = 0;                                      \
+  } else {                                                             \
+    if (%INFO_TYPE(inf) != HALF_W_(BLACKHOLE)) {                       \
+      if (%INFO_TYPE(inf) == HALF_W_(AP_STACK)) {                      \
+          sz = StgAP_STACK_size(p) + BYTES_TO_WDS(SIZEOF_StgAP_STACK_NoHdr); \
+      } else {                                                         \
+          sz = TO_W_(%INFO_PTRS(inf)) + TO_W_(%INFO_NPTRS(inf));       \
+      }                                                                        \
+      i = 0;                                                           \
+      for:                                                             \
+        if (i < sz) {                                                  \
+          StgThunk_payload(p,i) = 0;                                   \
+          i = i + 1;                                                   \
+          goto for;                                                    \
+        }                                                              \
+  } }
 
 #else /* !CMINUSMINUS */
 
@@ -218,12 +228,25 @@ INLINE_HEADER void
 DEBUG_FILL_SLOP(StgClosure *p)
 {                                              
     StgInfoTable *inf = get_itbl(p);           
-    nat np = inf->layout.payload.ptrs,         
-       nw = inf->layout.payload.nptrs, i;
-    if (inf->type != THUNK_SELECTOR) {
-       for (i = 0; i < np + nw; i++) {
-           ((StgClosure *)p)->payload[i] = 0;
-       }
+    nat i, sz;
+
+    switch (inf->type) {
+    case BLACKHOLE:
+       return;
+    case AP_STACK:
+       sz = ((StgAP_STACK *)p)->size + sizeofW(StgAP_STACK) - sizeofW(StgHeader);
+       break;
+    case THUNK_SELECTOR:
+#ifdef SMP
+       ((StgSelector *)p)->selectee = 0;
+#endif
+       return;
+    default:
+       sz = inf->layout.payload.ptrs + inf->layout.payload.nptrs;
+        break;
+    }
+    for (i = 0; i < sz; i++) {
+       ((StgThunk *)p)->payload[i] = 0;
     }
 }
 
@@ -247,7 +270,8 @@ DEBUG_FILL_SLOP(StgClosure *p)
                                                                \
 /*    ASSERT( p1 != p2 && !closure_IND(p1) );                  \
  */ LDV_RECORD_DEAD_FILL_SLOP_DYNAMIC(p1);                     \
-    bd = Bdescr(p1);                                           \
+/*  foreign "C" cas(p1 "ptr", 0, stg_WHITEHOLE_info);          \
+ */ bd = Bdescr(p1);                                           \
     if (bdescr_gen_no(bd) == 0 :: CInt) {                      \
       StgInd_indirectee(p1) = p2;                              \
       SET_INFO(p1, ind_info);                                  \
@@ -256,7 +280,7 @@ DEBUG_FILL_SLOP(StgClosure *p)
       and_then;                                                        \
     } else {                                                   \
       DEBUG_FILL_SLOP(p1);                                     \
-      foreign "C" recordMutableGen(p1 "ptr",                   \
+      foreign "C" recordMutableGenLock(p1 "ptr",               \
                 generation(TO_W_(bdescr_gen_no(bd))) "ptr");   \
       StgInd_indirectee(p1) = p2;                              \
       SET_INFO(p1, stg_IND_OLDGEN_info);                       \
@@ -269,6 +293,7 @@ DEBUG_FILL_SLOP(StgClosure *p)
   {                                                                    \
     bdescr *bd;                                                                \
                                                                        \
+    /* cas(p1, 0, &stg_WHITEHOLE_info); */                             \
     ASSERT( (P_)p1 != (P_)p2 && !closure_IND(p1) );                    \
     LDV_RECORD_DEAD_FILL_SLOP_DYNAMIC(p1);                             \
     bd = Bdescr((P_)p1);                                               \
@@ -280,7 +305,7 @@ DEBUG_FILL_SLOP(StgClosure *p)
       and_then;                                                                \
     } else {                                                           \
       DEBUG_FILL_SLOP(p1);                                             \
-      recordMutableGen(p1, &generations[bd->gen_no]);                  \
+      recordMutableGenLock(p1, &generations[bd->gen_no]);              \
       ((StgInd *)p1)->indirectee = p2;                                 \
       SET_INFO(p1, &stg_IND_OLDGEN_info);                              \
       TICK_UPD_OLD_IND();                                              \
@@ -319,7 +344,7 @@ updateWithPermIndirection(StgClosure *p1,
     LDV_RECORD_CREATE(p1);
     TICK_UPD_NEW_PERM_IND(p1);
   } else {
-    recordMutableGen(p1, &generations[bd->gen_no]);
+    recordMutableGenLock(p1, &generations[bd->gen_no]);
     ((StgInd *)p1)->indirectee = p2;
     SET_INFO(p1, &stg_IND_OLDGEN_PERM_info);
     /*