/* -----------------------------------------------------------------------------
- * $Id: GC.c,v 1.140 2002/09/06 09:56:12 simonmar Exp $
+ * $Id: GC.c,v 1.145 2002/10/25 09:40:47 simonmar Exp $
*
* (c) The GHC Team 1998-1999
*
#include "Prelude.h"
#include "ParTicky.h" // ToDo: move into Rts.h
#include "GCCompact.h"
+#include "Signals.h"
#if defined(GRAN) || defined(PAR)
# include "GranSimRts.h"
# include "ParallelRts.h"
/* Used to avoid long recursion due to selector thunks
*/
static lnat thunk_selector_depth = 0;
-#define MAX_THUNK_SELECTOR_DEPTH 256
+#define MAX_THUNK_SELECTOR_DEPTH 8
/* -----------------------------------------------------------------------------
Static function declarations
Now, Now));
#endif
+#ifndef mingw32_TARGET_OS
+ // block signals
+ blockUserSignals();
+#endif
+
// tell the stats department that we've started a GC
stat_startGC();
// ok, GC over: tell the stats department what happened.
stat_endGC(allocated, collected, live, copied, N);
+#ifndef mingw32_TARGET_OS
+ // unblock signals again
+ unblockUserSignals();
+#endif
+
//PAR_TICKY_TP();
}
if (LOOKS_LIKE_STATIC(p) || bd->gen_no > N) {
return p;
}
- // large objects have an evacuated flag
+
+ // if it's a pointer into to-space, then we're done
+ if (bd->flags & BF_EVACUATED) {
+ return p;
+ }
+
+ // large objects use the evacuated flag
if (bd->flags & BF_LARGE) {
- if (bd->flags & BF_EVACUATED) {
- return p;
- } else {
- return NULL;
- }
+ return NULL;
}
+
// check the mark bit for compacted steps
if (bd->step->is_compacted && is_marked((P_)p,bd)) {
return p;
static __inline__ void
upd_evacuee(StgClosure *p, StgClosure *dest)
{
- p->header.info = &stg_EVACUATED_info;
- ((StgEvacuated *)p)->evacuee = dest;
+ // Source object must be in from-space:
+ ASSERT((Bdescr((P_)p)->flags & BF_EVACUATED) == 0);
+ // not true: (ToDo: perhaps it should be)
+ // ASSERT(Bdescr((P_)dest)->flags & BF_EVACUATED);
+ p->header.info = &stg_EVACUATED_info;
+ ((StgEvacuated *)p)->evacuee = dest;
}
Evaluate a THUNK_SELECTOR if possible.
returns: NULL if we couldn't evaluate this THUNK_SELECTOR, or
- a closure pointer if we evaluated it and this is the result
+ a closure pointer if we evaluated it and this is the result. Note
+ that "evaluating" the THUNK_SELECTOR doesn't necessarily mean
+ reducing it to HNF, just that we have eliminated the selection.
+ The result might be another thunk, or even another THUNK_SELECTOR.
If the return value is non-NULL, the original selector thunk has
been BLACKHOLE'd, and should be updated with an indirection or a
StgInfoTable *info;
const StgInfoTable *info_ptr;
StgClosure *selectee;
-
+
selectee = p->selectee;
// Save the real info pointer (NOTE: not the same as get_itbl()).
info_ptr = p->header.info;
+ // If the THUNK_SELECTOR is in a generation that we are not
+ // collecting, then bail out early. We won't be able to save any
+ // space in any case, and updating with an indirection is trickier
+ // in an old gen.
+ if (Bdescr((StgPtr)p)->gen_no > N) {
+ return NULL;
+ }
+
// BLACKHOLE the selector thunk, since it is now under evaluation.
// This is important to stop us going into an infinite loop if
// this selector thunk eventually refers to itself.
SET_INFO(p,&stg_BLACKHOLE_info);
selector_loop:
+
info = get_itbl(selectee);
switch (info->type) {
case CONSTR:
return selectee->payload[field];
case IND:
- case IND_STATIC:
case IND_PERM:
case IND_OLDGEN:
case IND_OLDGEN_PERM:
// leaks by evaluating this selector thunk anyhow.
break;
+ case IND_STATIC:
+ // We can't easily tell whether the indirectee is into
+ // from or to-space, so just bail out here.
+ break;
+
case THUNK_SELECTOR:
{
StgClosure *val;
if (val == NULL) {
break;
} else {
- // we evaluated this selector thunk, so update it with
- // an indirection.
- UPD_IND_NOLOCK(selectee, val);
+ // We evaluated this selector thunk, so update it with
+ // an indirection. NOTE: we don't use UPD_IND here,
+ // because we are guaranteed that p is in a generation
+ // that we are collecting, and we never want to put the
+ // indirection on a mutable list.
+ ((StgInd *)selectee)->indirectee = val;
+ SET_INFO(selectee,&stg_IND_info);
selectee = val;
goto selector_loop;
}