#ifdef PROFILING
+#include "PosixSource.h"
#include "Rts.h"
-#include "LdvProfile.h"
-#include "RtsFlags.h"
+
#include "Profiling.h"
+#include "LdvProfile.h"
#include "Stats.h"
#include "RtsUtils.h"
#include "Schedule.h"
processHeapClosureForDead( StgClosure *c )
{
nat size;
- StgInfoTable *info;
+ const StgInfoTable *info;
info = get_itbl(c);
- if (info->type != EVACUATED) {
- ASSERT(((LDVW(c) & LDV_CREATE_MASK) >> LDV_SHIFT) <= era &&
- ((LDVW(c) & LDV_CREATE_MASK) >> LDV_SHIFT) > 0);
- ASSERT(((LDVW(c) & LDV_STATE_MASK) == LDV_STATE_CREATE) ||
- (
- (LDVW(c) & LDV_LAST_MASK) <= era &&
- (LDVW(c) & LDV_LAST_MASK) > 0
- ));
- }
-
- if (info->type == EVACUATED) {
+ info = c->header.info;
+ if (IS_FORWARDING_PTR(info)) {
// The size of the evacuated closure is currently stored in
// the LDV field. See SET_EVACUAEE_FOR_LDV() in
// includes/StgLdvProf.h.
return LDVW(c);
}
+ info = INFO_PTR_TO_STRUCT(info);
+
+ ASSERT(((LDVW(c) & LDV_CREATE_MASK) >> LDV_SHIFT) <= era &&
+ ((LDVW(c) & LDV_CREATE_MASK) >> LDV_SHIFT) > 0);
+ ASSERT(((LDVW(c) & LDV_STATE_MASK) == LDV_STATE_CREATE) ||
+ (
+ (LDVW(c) & LDV_LAST_MASK) <= era &&
+ (LDVW(c) & LDV_LAST_MASK) > 0
+ ));
+
size = closure_sizeW(c);
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 SE_BLACKHOLE:
- case CAF_BLACKHOLE:
- case SE_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;
case RET_SMALL:
case RET_BIG:
// others
- case BLOCKED_FETCH:
- case FETCH_ME:
- case FETCH_ME_BQ:
- case RBH:
- case REMOTE_REF:
case INVALID_OBJECT:
default:
barf("Invalid object in processHeapClosureForDead(): %d", info->type);
}
/* --------------------------------------------------------------------------
- * Calls processHeapClosureForDead() on every *dead* closures in the
- * small object pool.
- * ----------------------------------------------------------------------- */
-static void
-processSmallObjectPoolForDead( void )
-{
- bdescr *bd;
- StgPtr p;
-
- bd = small_alloc_list;
-
- // first block
- if (bd == NULL)
- return;
-
- p = bd->start;
- while (p < alloc_Hp) {
- p += processHeapClosureForDead((StgClosure *)p);
- while (p < alloc_Hp && !*p) // skip slop
- p++;
- }
- ASSERT(p == alloc_Hp);
-
- bd = bd->link;
- while (bd != NULL) {
- p = bd->start;
- while (p < bd->free) {
- p += processHeapClosureForDead((StgClosure *)p);
- while (p < bd->free && !*p) // skip slop
- p++;
- }
- ASSERT(p == bd->free);
- bd = bd->link;
- }
-}
-
-/* --------------------------------------------------------------------------
* Calls processHeapClosureForDead() on every *dead* closures in the closure
* chain.
* ----------------------------------------------------------------------- */
{
// Any object still in the chain is dead!
while (bd != NULL) {
- processHeapClosureForDead((StgClosure *)bd->start);
+ if (!(bd->flags & BF_PINNED)) {
+ processHeapClosureForDead((StgClosure *)bd->start);
+ }
bd = bd->link;
}
}
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);
+ }
}
}