X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FUpdates.h;h=62473b3eaf4d02b8feb5a263df766d1748cfe919;hb=5c67b7e313b2455ca65d5aa5970d86889145e97e;hp=37bb9a289630d8703c682d0a794cde1e6e78284f;hpb=21f6b31c31b924b9bb572175f34c1408522fba48;p=ghc-hetmet.git diff --git a/ghc/rts/Updates.h b/ghc/rts/Updates.h index 37bb9a2..62473b3 100644 --- a/ghc/rts/Updates.h +++ b/ghc/rts/Updates.h @@ -186,67 +186,74 @@ extern void awakenBlockedQueue(StgBlockingQueueElement *q, StgClosure *node); * 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 + * NB. We do *not* do this in THREADED_RTS 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) || defined(SMP) - -#define DEBUG_FILL_SLOP(p) /* nothing */ - -#else /* DEBUG */ - #ifdef CMINUSMINUS -#define DEBUG_FILL_SLOP(p) \ +#define FILL_SLOP(p) \ W_ inf; \ W_ sz; \ W_ i; \ inf = %GET_STD_INFO(p); \ - if (%INFO_TYPE(inf) != HALF_W_(THUNK_SELECTOR)) { \ - if (%INFO_TYPE(inf) != HALF_W_(BLACKHOLE)) { \ + if (%INFO_TYPE(inf) != HALF_W_(THUNK_SELECTOR) \ + && %INFO_TYPE(inf) != HALF_W_(BLACKHOLE) \ + && %INFO_TYPE(inf) != HALF_W_(CAF_BLACKHOLE)) { \ if (%INFO_TYPE(inf) == HALF_W_(AP_STACK)) { \ - sz = StgAP_STACK_size(p) + BYTES_TO_WDS(SIZEOF_StgAP_STACK_NoHdr); \ + sz = StgAP_STACK_size(p) + BYTES_TO_WDS(SIZEOF_StgAP_STACK_NoThunkHdr); \ } else { \ - sz = TO_W_(%INFO_PTRS(inf)) + TO_W_(%INFO_NPTRS(inf)); \ + if (%INFO_TYPE(inf) == HALF_W_(AP)) { \ + sz = TO_W_(StgAP_n_args(p)) + BYTES_TO_WDS(SIZEOF_StgAP_NoThunkHdr); \ + } else { \ + sz = TO_W_(%INFO_PTRS(inf)) + TO_W_(%INFO_NPTRS(inf)); \ + } \ } \ - i = 1; /* skip over indirectee */ \ + i = 0; \ for: \ if (i < sz) { \ StgThunk_payload(p,i) = 0; \ i = i + 1; \ goto for; \ } \ - } } + } #else /* !CMINUSMINUS */ INLINE_HEADER void -DEBUG_FILL_SLOP(StgClosure *p) +FILL_SLOP(StgClosure *p) { StgInfoTable *inf = get_itbl(p); nat i, sz; switch (inf->type) { case BLACKHOLE: + case CAF_BLACKHOLE: case THUNK_SELECTOR: return; + case AP: + sz = ((StgAP *)p)->n_args + sizeofW(StgAP) - sizeofW(StgThunkHeader); + break; case AP_STACK: - sz = ((StgAP_STACK *)p)->size + sizeofW(StgAP_STACK) - sizeofW(StgHeader); + sz = ((StgAP_STACK *)p)->size + sizeofW(StgAP_STACK) - sizeofW(StgThunkHeader); break; default: sz = inf->layout.payload.ptrs + inf->layout.payload.nptrs; break; } - // start at one to skip over the indirectee - for (i = 1; i < sz; i++) { + for (i = 0; i < sz; i++) { ((StgThunk *)p)->payload[i] = 0; } } #endif /* CMINUSMINUS */ -#endif /* DEBUG */ + +#if !defined(DEBUG) || defined(THREADED_RTS) +#define DEBUG_FILL_SLOP(p) /* do nothing */ +#else +#define DEBUG_FILL_SLOP(p) FILL_SLOP(p) +#endif /* We have two versions of this macro (sadly), one for use in C-- code, * and the other for C. @@ -266,6 +273,7 @@ DEBUG_FILL_SLOP(StgClosure *p) DEBUG_FILL_SLOP(p1); \ LDV_RECORD_DEAD_FILL_SLOP_DYNAMIC(p1); \ StgInd_indirectee(p1) = p2; \ + foreign "C" wb() []; \ bd = Bdescr(p1); \ if (bdescr_gen_no(bd) != 0 :: CInt) { \ foreign "C" recordMutableCap(p1 "ptr", \ @@ -291,6 +299,7 @@ DEBUG_FILL_SLOP(StgClosure *p) DEBUG_FILL_SLOP(p1); \ LDV_RECORD_DEAD_FILL_SLOP_DYNAMIC(p1); \ ((StgInd *)p1)->indirectee = p2; \ + wb(); \ bd = Bdescr((P_)p1); \ if (bd->gen_no != 0) { \ recordMutableGenLock(p1, &generations[bd->gen_no]); \