#include "Schedule.h"
/* --------------------------------------------------------------------------
- * Fills in the slop when a *dynamic* closure changes its type.
- * First calls LDV_recordDead() to declare the closure is dead, and then
- * fills in the slop.
- *
- * Invoked when:
- * 1) blackholing, UPD_BH_UPDATABLE() and UPD_BH_SINGLE_ENTRY (in
- * includes/StgMacros.h), threadLazyBlackHole() and
- * threadSqueezeStack() (in GC.c).
- * 2) updating with indirection closures, updateWithIndirection()
- * and updateWithPermIndirection() (in Storage.h).
- *
- * LDV_recordDead_FILL_SLOP_DYNAMIC() is not called on 'inherently used'
- * closures such as TSO. It is not called on PAP because PAP is not updatable.
- * ----------------------------------------------------------------------- */
-void
-LDV_recordDead_FILL_SLOP_DYNAMIC( StgClosure *p )
-{
- nat size, i;
-
-#if defined(__GNUC__) && __GNUC__ < 3 && defined(DEBUG)
-#error Please use gcc 3.0+ to compile this file with DEBUG; gcc < 3.0 miscompiles it
-#endif
-
- if (era > 0) {
- // very like FILL_SLOP(), except that we call LDV_recordDead().
- size = closure_sizeW(p);
-
- LDV_recordDead((StgClosure *)(p), size);
-
- if (size > sizeofW(StgThunkHeader)) {
- for (i = 0; i < size - sizeofW(StgThunkHeader); i++) {
- ((StgThunk *)(p))->payload[i] = 0;
- }
- }
- }
-}
-
-/* --------------------------------------------------------------------------
* This function is called eventually on every object destroyed during
* a garbage collection, whether it is a major garbage collection or
* not. If c is an 'inherently used' closure, nothing happens. If c
'inherently used' cases: do nothing.
*/
case TSO:
+ case STACK:
case MVAR_CLEAN:
case MVAR_DIRTY:
case MUT_ARR_PTRS_CLEAN:
case MUT_VAR_CLEAN:
case MUT_VAR_DIRTY:
case BCO:
- case STABLE_NAME:
- case TVAR_WATCH_QUEUE:
- case TVAR:
- case TREC_HEADER:
+ case PRIM:
+ case MUT_PRIM:
case TREC_CHUNK:
- case INVARIANT_CHECK_QUEUE:
- case ATOMIC_INVARIANT:
return size;
/*
case FUN_1_1:
case FUN_0_2:
case BLACKHOLE:
- case CAF_BLACKHOLE:
+ case BLOCKING_QUEUE:
case IND_PERM:
- case IND_OLDGEN_PERM:
/*
'Ingore' cases
*/
- // Why can we ignore IND/IND_OLDGEN closures? We assume that
+ // Why can we ignore IND closures? We assume that
// any census is preceded by a major garbage collection, which
- // IND/IND_OLDGEN closures cannot survive. Therefore, it is no
- // use considering IND/IND_OLDGEN closures in the meanwhile
+ // IND closures cannot survive. Therefore, it is no
+ // use considering IND closures in the meanwhile
// because they will perish before the next census at any
// rate.
case IND:
- case IND_OLDGEN:
// Found a dead closure: record its size
LDV_recordDead(c, size);
return size;
// stack objects
case UPDATE_FRAME:
case CATCH_FRAME:
+ case UNDERFLOW_FRAME:
case STOP_FRAME:
case RET_DYN:
case RET_BCO:
}
/* --------------------------------------------------------------------------
- * Calls processHeapClosureForDead() on every *dead* closures in the
- * small object pool.
- * ----------------------------------------------------------------------- */
-static void
-processSmallObjectPoolForDead( void )
-{
- bdescr *bd;
- StgPtr p;
-
- for (bd = g0s0->blocks; bd != NULL; bd = bd->link) {
- p = bd->start;
- while (p < bd->free) {
- p += processHeapClosureForDead((StgClosure *)p);
- while (p < bd->free && !*p) // skip slop
- p++;
- }
- ASSERT(p == bd->free);
- }
-}
-
-/* --------------------------------------------------------------------------
* Calls processHeapClosureForDead() on every *dead* closures in the closure
* chain.
* ----------------------------------------------------------------------- */
void
LdvCensusForDead( nat N )
{
- nat g, s;
+ nat g;
// ldvTime == 0 means that LDV profiling is currently turned off.
if (era == 0)
//
barf("Lag/Drag/Void profiling not supported with -G1");
} else {
- for (g = 0; g <= N; g++)
- for (s = 0; s < generations[g].n_steps; s++) {
- if (g == 0 && s == 0) {
- processSmallObjectPoolForDead();
- processNurseryForDead();
- processChainForDead(generations[g].steps[s].large_objects);
- } else{
- processHeapForDead(generations[g].steps[s].old_blocks);
- processChainForDead(generations[g].steps[s].large_objects);
- }
- }
+ processNurseryForDead();
+ for (g = 0; g <= N; g++) {
+ processHeapForDead(generations[g].old_blocks);
+ processChainForDead(generations[g].large_objects);
+ }
}
}