Closure Type Profiling;
------------------------------------------------------------------------- */
+#ifndef PROFILING
static char *type_names[] = {
"INVALID_OBJECT",
"CONSTR",
"BLACKHOLE",
"SE_BLACKHOLE",
"SE_CAF_BLACKHOLE",
- "MVAR",
+ "MVAR_CLEAN",
+ "MVAR_DIRTY",
"ARR_WORDS",
"MUT_ARR_PTRS_CLEAN",
"MUT_ARR_PTRS_DIRTY",
"CATCH_STM_FRAME",
"N_CLOSURE_TYPES"
};
+#endif
/* ----------------------------------------------------------------------------
* Find the "closure identity", which is a unique pointer reresenting
case HEAP_BY_MOD:
return p->header.prof.ccs->cc->module;
case HEAP_BY_DESCR:
- return get_itbl(p)->prof.closure_desc;
+ return GET_PROF_DESC(get_itbl(p));
case HEAP_BY_TYPE:
- return get_itbl(p)->prof.closure_type;
+ return GET_PROF_TYPE(get_itbl(p));
case HEAP_BY_RETAINER:
// AFAIK, the only closures in the heap which might not have a
// valid retainer set are DEAD_WEAK closures.
case CONSTR_0_2:
case CONSTR_STATIC:
case CONSTR_NOCAF_STATIC:
- printf("",strlen(GET_CON_DESC(itbl_to_con_itbl(info))));
return GET_CON_DESC(itbl_to_con_itbl(info));
default:
return type_names[info->type];
STATIC_INLINE void
freeEra(Census *census)
{
- arenaFree(census->arena);
- freeHashTable(census->hash, NULL);
+ if (RtsFlags.ProfFlags.bioSelector != NULL)
+ // when bioSelector==NULL, these are freed in heapCensus()
+ {
+ arenaFree(census->arena);
+ freeHashTable(census->hash, NULL);
+ }
}
/* --------------------------------------------------------------------------
* Heap profiling by info table
* ------------------------------------------------------------------------- */
-#if !defined(PROFILNG)
+#if !defined(PROFILING)
FILE *hp_file;
static char *hp_filename;
era = 0;
}
- { // max_era = 2^LDV_SHIFT
- nat p;
- max_era = 1;
- for (p = 0; p < LDV_SHIFT; p++)
- max_era *= 2;
- }
+ // max_era = 2^LDV_SHIFT
+ max_era = 1 << LDV_SHIFT;
n_censuses = 32;
censuses = stgMallocBytes(sizeof(Census) * n_censuses, "initHeapProfiling");
}
#endif
- {
+#ifdef PROFILING
+ if (doingLDVProfiling()) {
nat t;
- for (t = 0; t <= era; t++) {
+ for (t = 1; t <= era; t++) {
freeEra( &censuses[t] );
}
+ } else {
+ freeEra( &censuses[0] );
}
+#else
+ freeEra( &censuses[0] );
+#endif
+
stgFree(censuses);
seconds = mut_user_time();
}
if (RtsFlags.ProfFlags.descrSelector) {
- b = strMatchesSelector( (get_itbl((StgClosure *)p))->prof.closure_desc,
+ b = strMatchesSelector( (GET_PROF_DESC(get_itbl((StgClosure *)p))),
RtsFlags.ProfFlags.descrSelector );
if (!b) return rtsFalse;
}
if (RtsFlags.ProfFlags.typeSelector) {
- b = strMatchesSelector( (get_itbl((StgClosure *)p))->prof.closure_type,
+ b = strMatchesSelector( (GET_PROF_TYPE(get_itbl((StgClosure *)p))),
RtsFlags.ProfFlags.typeSelector );
if (!b) return rtsFalse;
}
size = bco_sizeW((StgBCO *)p);
break;
- case MVAR:
+ case MVAR_CLEAN:
+ case MVAR_DIRTY:
case WEAK:
case STABLE_NAME:
case MUT_VAR_CLEAN:
#endif
// Traverse the heap, collecting the census info
-
- // First the small_alloc_list: we have to fix the free pointer at
- // the end by calling tidyAllocatedLists() first.
- tidyAllocateLists();
- heapCensusChain( census, small_alloc_list );
-
- // Now traverse the heap in each generation/step.
if (RtsFlags.GcFlags.generations == 1) {
heapCensusChain( census, g0s0->blocks );
} else {