/* -----------------------------------------------------------------------------
- * $Id: GC.c,v 1.140 2002/09/06 09:56:12 simonmar Exp $
+ * $Id: GC.c,v 1.143 2002/09/18 06:34:07 mthomas 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();
}
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:
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;
}