Closure Type Profiling;
------------------------------------------------------------------------- */
+#ifndef PROFILING
static char *type_names[] = {
"INVALID_OBJECT",
"CONSTR",
"STOP_FRAME",
"CAF_BLACKHOLE",
"BLACKHOLE",
- "SE_BLACKHOLE",
- "SE_CAF_BLACKHOLE",
- "MVAR",
+ "MVAR_CLEAN",
+ "MVAR_DIRTY",
"ARR_WORDS",
"MUT_ARR_PTRS_CLEAN",
"MUT_ARR_PTRS_DIRTY",
"FETCH_ME",
"FETCH_ME_BQ",
"RBH",
- "EVACUATED",
"REMOTE_REF",
"TVAR_WATCH_QUEUE",
"INVARIANT_CHECK_QUEUE",
"ATOMICALLY_FRAME",
"CATCH_RETRY_FRAME",
"CATCH_STM_FRAME",
+ "WHITEHOLE",
"N_CLOSURE_TYPES"
};
+#endif
/* ----------------------------------------------------------------------------
* Find the "closure identity", which is a unique pointer reresenting
* the band to which this closure's heap space is attributed in the
* heap profile.
* ------------------------------------------------------------------------- */
-STATIC_INLINE void *
+static void *
closureIdentity( StgClosure *p )
{
switch (RtsFlags.ProfFlags.doHeapProfile) {
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);
+ }
}
/* --------------------------------------------------------------------------
void initProfiling2 (void)
{
+ char *prog;
+
+ prog = stgMallocBytes(strlen(prog_name) + 1, "initProfiling2");
+ strcpy(prog, prog_name);
+#ifdef mingw32_HOST_OS
+ // on Windows, drop the .exe suffix if there is one
+ {
+ char *suff;
+ suff = strrchr(prog,'.');
+ if (suff != NULL && !strcmp(suff,".exe")) {
+ *suff = '\0';
+ }
+ }
+#endif
+
if (RtsFlags.ProfFlags.doHeapProfile) {
/* Initialise the log file name */
- hp_filename = stgMallocBytes(strlen(prog_name) + 6, "hpFileName");
- sprintf(hp_filename, "%s.hp", prog_name);
+ hp_filename = stgMallocBytes(strlen(prog) + 6, "hpFileName");
+ sprintf(hp_filename, "%s.hp", prog);
/* open the log file */
if ((hp_file = fopen(hp_filename, "w")) == NULL) {
}
}
+ stgFree(prog);
+
initHeapProfiling();
}
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 = 1; t <= era; 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;
}
case IND_OLDGEN:
case IND_OLDGEN_PERM:
case CAF_BLACKHOLE:
- case SE_CAF_BLACKHOLE:
- case SE_BLACKHOLE:
case BLACKHOLE:
case FUN_1_0:
case FUN_0_1:
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 {