X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FGC.c;h=120f02a76e25eb5fd5fd5f48303a18da1ad17c2b;hb=17219e16788255f934b518d1549aac92bdce7a8c;hp=a1bbf56c743a60242f587ef8b2d452ea92b4cfd8;hpb=6d35596c37601a9bf608e32034c390d516454c29;p=ghc-hetmet.git diff --git a/ghc/rts/GC.c b/ghc/rts/GC.c index a1bbf56..120f02a 100644 --- a/ghc/rts/GC.c +++ b/ghc/rts/GC.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * $Id: GC.c,v 1.96 2001/02/11 17:51:07 simonmar Exp $ + * $Id: GC.c,v 1.102 2001/04/03 16:35:12 sewardj Exp $ * * (c) The GHC Team 1998-1999 * @@ -44,6 +44,7 @@ #include "Weak.h" #include "StablePriv.h" #include "Prelude.h" +#include "ParTicky.h" // ToDo: move into Rts.h #if defined(GRAN) || defined(PAR) # include "GranSimRts.h" # include "ParallelRts.h" @@ -137,6 +138,11 @@ bdescr *old_to_space; lnat new_blocks; /* blocks allocated during this GC */ lnat g0s0_pcnt_kept = 30; /* percentage of g0s0 live at last minor GC */ +/* Used to avoid long recursion due to selector thunks + */ +lnat thunk_selector_depth = 0; +#define MAX_THUNK_SELECTOR_DEPTH 256 + //@node Static function declarations, Garbage Collect, STATIC OBJECT LIST //@subsection Static function declarations @@ -211,6 +217,9 @@ void GarbageCollect ( void (*get_roots)(void), rtsBool force_major_gc ) /* tell the stats department that we've started a GC */ stat_startGC(); + /* Init stats and print par specific (timing) info */ + PAR_TICKY_PAR_START(); + /* attribute any costs to CCS_GC */ #ifdef PROFILING prev_CCS = CCCS; @@ -404,6 +413,8 @@ void GarbageCollect ( void (*get_roots)(void), rtsBool force_major_gc ) /* Mark the entries in the GALA table of the parallel system */ markLocalGAs(major_gc); + /* Mark all entries on the list of pending fetches */ + markPendingFetches(major_gc); #endif /* Mark the weak pointer list, and prepare to detect dead weak @@ -786,6 +797,8 @@ void GarbageCollect ( void (*get_roots)(void), rtsBool force_major_gc ) /* ok, GC over: tell the stats department what happened. */ stat_endGC(allocated, collected, live, copied, N); + + //PAR_TICKY_TP(); } //@node Weak Pointers, Evacuation, Garbage Collect @@ -1473,6 +1486,29 @@ loop: selectee = ((StgEvacuated *)selectee)->evacuee; goto selector_loop; + case THUNK_SELECTOR: +# if 0 + /* Disabled 03 April 2001 by JRS; it seems to cause the GC (or + something) to go into an infinite loop when the nightly + stage2 compiles PrelTup.lhs. */ + + /* we can't recurse indefinitely in evacuate(), so set a + * limit on the number of times we can go around this + * loop. + */ + if (thunk_selector_depth < MAX_THUNK_SELECTOR_DEPTH) { + bdescr *bd; + bd = Bdescr((P_)selectee); + if (!bd->evacuated) { + thunk_selector_depth++; + selectee = evacuate(selectee); + thunk_selector_depth--; + goto selector_loop; + } + } + /* otherwise, fall through... */ +# endif + case AP_UPD: case THUNK: case THUNK_1_0: @@ -1481,8 +1517,6 @@ loop: case THUNK_1_1: case THUNK_0_2: case THUNK_STATIC: - case THUNK_SELECTOR: - /* aargh - do recursively???? */ case CAF_BLACKHOLE: case SE_CAF_BLACKHOLE: case SE_BLACKHOLE: @@ -1491,6 +1525,37 @@ loop: /* not evaluated yet */ break; +#if defined(PAR) + /* a copy of the top-level cases below */ + case RBH: // cf. BLACKHOLE_BQ + { + //StgInfoTable *rip = get_closure_info(q, &size, &ptrs, &nonptrs, &vhs, str); + to = copy(q,BLACKHOLE_sizeW(),stp); + //ToDo: derive size etc from reverted IP + //to = copy(q,size,stp); + // recordMutable((StgMutClosure *)to); + return to; + } + + case BLOCKED_FETCH: + ASSERT(sizeofW(StgBlockedFetch) >= MIN_NONUPD_SIZE); + to = copy(q,sizeofW(StgBlockedFetch),stp); + return to; + +# ifdef DIST + case REMOTE_REF: +# endif + case FETCH_ME: + ASSERT(sizeofW(StgBlockedFetch) >= MIN_UPD_SIZE); + to = copy(q,sizeofW(StgFetchMe),stp); + return to; + + case FETCH_ME_BQ: + ASSERT(sizeofW(StgBlockedFetch) >= MIN_UPD_SIZE); + to = copy(q,sizeofW(StgFetchMeBlockingQueue),stp); + return to; +#endif + default: barf("evacuate: THUNK_SELECTOR: strange selectee %d", (int)(selectee_info->type)); @@ -1521,15 +1586,15 @@ loop: return q; case IND_STATIC: - /* a revertible CAF - it'll be on the CAF list, so don't do - * anything with it here (we'll scavenge it later). + /* If q->saved_info != NULL, then it's a revertible CAF - it'll be + * on the CAF list, so don't do anything with it here (we'll + * scavenge it later). */ - if (((StgIndStatic *)q)->saved_info != NULL) { - return q; - } - if (major_gc && IND_STATIC_LINK((StgClosure *)q) == NULL) { - IND_STATIC_LINK((StgClosure *)q) = static_objects; - static_objects = (StgClosure *)q; + if (major_gc + && ((StgIndStatic *)q)->saved_info == NULL + && IND_STATIC_LINK((StgClosure *)q) == NULL) { + IND_STATIC_LINK((StgClosure *)q) = static_objects; + static_objects = (StgClosure *)q; } return q; @@ -1689,6 +1754,9 @@ loop: q, info_type(q), to, info_type(to))); return to; +# ifdef DIST + case REMOTE_REF: +# endif case FETCH_ME: ASSERT(sizeofW(StgBlockedFetch) >= MIN_UPD_SIZE); to = copy(q,sizeofW(StgFetchMe),stp); @@ -2150,10 +2218,10 @@ scavenge(step *stp) break; } +#ifdef DIST + case REMOTE_REF: +#endif case FETCH_ME: - IF_DEBUG(gc, - belch("@@ scavenge: HWL claims nothing to do for %p (%s)", - p, info_type((StgClosure *)p))); p += sizeofW(StgFetchMe); break; // nothing to do in this case @@ -2583,6 +2651,10 @@ scavenge_mutable_list(generation *gen) break; } +#ifdef DIST + case REMOTE_REF: + barf("scavenge_mutable_list: REMOTE_REF %d", (int)(info->type)); +#endif case FETCH_ME: p += sizeofW(StgFetchMe); break; // nothing to do in this case @@ -2664,7 +2736,7 @@ scavenge_static(void) case THUNK_STATIC: case FUN_STATIC: scavenge_srt(info); - /* fall through */ + break; case CONSTR_STATIC: { @@ -3341,8 +3413,18 @@ threadSqueezeStack(StgTSO *tso) /* wasn't there something about update squeezing and ticky to be * sorted out? oh yes: we aren't counting each enter properly * in this case. See the log somewhere. KSW 1999-04-21 + * + * Check two things: that the two update frames don't point to + * the same object, and that the updatee_bypass isn't already an + * indirection. Both of these cases only happen when we're in a + * block hole-style loop (and there are multiple update frames + * on the stack pointing to the same closure), but they can both + * screw us up if we don't check. */ - UPD_IND_NOLOCK(updatee_bypass, updatee_keep); /* this wakes the threads up */ + if (updatee_bypass != updatee_keep && !closure_IND(updatee_bypass)) { + /* this wakes the threads up */ + UPD_IND_NOLOCK(updatee_bypass, updatee_keep); + } sp = (P_)frame - 1; /* sp = stuff to slide */ displacement += sizeofW(StgUpdateFrame);