X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=rts%2FProfHeap.c;h=599b479c8dcf0454623658b4fcc8c6e2d0e06169;hp=ea71e20fd40ce0c6ea909c3eac71bcbd9facf1c8;hb=842e9d6628a27cf1f420d53f6a5901935dc50c54;hpb=9ff76535edb25ab7434284adddb5c64708ecb547 diff --git a/rts/ProfHeap.c b/rts/ProfHeap.c index ea71e20..599b479 100644 --- a/rts/ProfHeap.c +++ b/rts/ProfHeap.c @@ -1,18 +1,10 @@ -/* ----------------------------------------------------------------------------- +/* ---------------------------------------------------------------------------- * * (c) The GHC Team, 1998-2003 * * Support for heap profiling * - * ---------------------------------------------------------------------------*/ - -#if defined(DEBUG) && !defined(PROFILING) -#define DEBUG_HEAP_PROF -#else -#undef DEBUG_HEAP_PROF -#endif - -#if defined(PROFILING) || defined(DEBUG_HEAP_PROF) + * --------------------------------------------------------------------------*/ #include "PosixSource.h" #include "Rts.h" @@ -103,70 +95,89 @@ static void aggregateCensusInfo( void ); static void dumpCensus( Census *census ); -/* ----------------------------------------------------------------------------- +/* ---------------------------------------------------------------------------- Closure Type Profiling; + ------------------------------------------------------------------------- */ - PROBABLY TOTALLY OUT OF DATE -- ToDo (SDM) - -------------------------------------------------------------------------- */ - -#ifdef DEBUG_HEAP_PROF +#ifndef PROFILING static char *type_names[] = { - "INVALID_OBJECT" - , "CONSTR" - , "CONSTR_STATIC" - , "CONSTR_NOCAF_STATIC" - - , "FUN" - , "FUN_STATIC" - - , "THUNK" - , "THUNK_STATIC" - , "THUNK_SELECTOR" - - , "BCO" - , "AP_STACK" - , "AP" - - , "PAP" - - , "IND" - , "IND_OLDGEN" - , "IND_PERM" - , "IND_OLDGEN_PERM" - , "IND_STATIC" - - , "RET_BCO" - , "RET_SMALL" - , "RET_BIG" - , "RET_DYN" - , "UPDATE_FRAME" - , "CATCH_FRAME" - , "STOP_FRAME" - - , "BLACKHOLE" - , "MVAR" - - , "ARR_WORDS" - - , "MUT_ARR_PTRS_CLEAN" - , "MUT_ARR_PTRS_DIRTY" - , "MUT_ARR_PTRS_FROZEN" - , "MUT_VAR_CLEAN" - , "MUT_VAR_DIRTY" - - , "WEAK" - - , "TSO" - - , "BLOCKED_FETCH" - , "FETCH_ME" - - , "EVACUATED" -}; - -#endif /* DEBUG_HEAP_PROF */ + "INVALID_OBJECT", + "CONSTR", + "CONSTR_1_0", + "CONSTR_0_1", + "CONSTR_2_0", + "CONSTR_1_1", + "CONSTR_0_2", + "CONSTR_STATIC", + "CONSTR_NOCAF_STATIC", + "FUN", + "FUN_1_0", + "FUN_0_1", + "FUN_2_0", + "FUN_1_1", + "FUN_0_2", + "FUN_STATIC", + "THUNK", + "THUNK_1_0", + "THUNK_0_1", + "THUNK_2_0", + "THUNK_1_1", + "THUNK_0_2", + "THUNK_STATIC", + "THUNK_SELECTOR", + "BCO", + "AP", + "PAP", + "AP_STACK", + "IND", + "IND_OLDGEN", + "IND_PERM", + "IND_OLDGEN_PERM", + "IND_STATIC", + "RET_BCO", + "RET_SMALL", + "RET_BIG", + "RET_DYN", + "RET_FUN", + "UPDATE_FRAME", + "CATCH_FRAME", + "STOP_FRAME", + "CAF_BLACKHOLE", + "BLACKHOLE", + "SE_BLACKHOLE", + "SE_CAF_BLACKHOLE", + "MVAR_CLEAN", + "MVAR_DIRTY", + "ARR_WORDS", + "MUT_ARR_PTRS_CLEAN", + "MUT_ARR_PTRS_DIRTY", + "MUT_ARR_PTRS_FROZEN0", + "MUT_ARR_PTRS_FROZEN", + "MUT_VAR_CLEAN", + "MUT_VAR_DIRTY", + "WEAK", + "STABLE_NAME", + "TSO", + "BLOCKED_FETCH", + "FETCH_ME", + "FETCH_ME_BQ", + "RBH", + "EVACUATED", + "REMOTE_REF", + "TVAR_WATCH_QUEUE", + "INVARIANT_CHECK_QUEUE", + "ATOMIC_INVARIANT", + "TVAR", + "TREC_CHUNK", + "TREC_HEADER", + "ATOMICALLY_FRAME", + "CATCH_RETRY_FRAME", + "CATCH_STM_FRAME", + "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. @@ -182,9 +193,9 @@ closureIdentity( StgClosure *p ) 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. @@ -193,11 +204,25 @@ closureIdentity( StgClosure *p ) else return NULL; -#else // DEBUG - case HEAP_BY_INFOPTR: - return (void *)((StgClosure *)p)->header.info; +#else case HEAP_BY_CLOSURE_TYPE: - return type_names[get_itbl(p)->type]; + { + StgInfoTable *info; + info = get_itbl(p); + switch (info->type) { + case CONSTR: + case CONSTR_1_0: + case CONSTR_0_1: + case CONSTR_2_0: + case CONSTR_1_1: + case CONSTR_0_2: + case CONSTR_STATIC: + case CONSTR_NOCAF_STATIC: + return GET_CON_DESC(itbl_to_con_itbl(info)); + default: + return type_names[info->type]; + } + } #endif default: @@ -300,6 +325,7 @@ LDV_recordDead( StgClosure *c, nat size ) /* -------------------------------------------------------------------------- * Initialize censuses[era]; * ----------------------------------------------------------------------- */ + STATIC_INLINE void initEra(Census *census) { @@ -317,14 +343,19 @@ initEra(Census *census) 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); + } } /* -------------------------------------------------------------------------- * Increases era by 1 and initialize census[era]. * Reallocates gi[] and increases its size if needed. * ----------------------------------------------------------------------- */ + static void nextEra( void ) { @@ -348,23 +379,23 @@ nextEra( void ) initEra( &censuses[era] ); } -/* ----------------------------------------------------------------------------- - * DEBUG heap profiling, by info table - * -------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Heap profiling by info table + * ------------------------------------------------------------------------- */ -#ifdef DEBUG_HEAP_PROF +#if !defined(PROFILING) FILE *hp_file; static char *hp_filename; -void initProfiling1( void ) +void initProfiling1 (void) { } -void freeProfiling1( void ) +void freeProfiling1 (void) { } -void initProfiling2( void ) +void initProfiling2 (void) { if (RtsFlags.ProfFlags.doHeapProfile) { /* Initialise the log file name */ @@ -387,7 +418,7 @@ void endProfiling( void ) { endHeapProfiling(); } -#endif /* DEBUG_HEAP_PROF */ +#endif /* !PROFILING */ static void printSample(rtsBool beginSample, StgDouble sampleValue) @@ -427,12 +458,8 @@ initHeapProfiling(void) 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"); @@ -463,10 +490,6 @@ initHeapProfiling(void) printSample(rtsTrue, 0); printSample(rtsFalse, 0); -#ifdef DEBUG_HEAP_PROF - DEBUG_LoadSymbols(prog_name); -#endif - #ifdef PROFILING if (doingRetainerProfiling()) { initRetainerProfiling(); @@ -502,12 +525,19 @@ endHeapProfiling(void) } #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(); @@ -603,7 +633,7 @@ strMatchesSelector( char* str, char* sel ) rtsBool closureSatisfiesConstraints( StgClosure* p ) { -#ifdef DEBUG_HEAP_PROF +#if !defined(PROFILING) (void)p; /* keep gcc -Wall happy */ return rtsTrue; #else @@ -617,12 +647,12 @@ closureSatisfiesConstraints( StgClosure* p ) } 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; } @@ -808,11 +838,8 @@ dumpCensus( Census *census ) if (count == 0) continue; -#ifdef DEBUG_HEAP_PROF +#if !defined(PROFILING) switch (RtsFlags.ProfFlags.doHeapProfile) { - case HEAP_BY_INFOPTR: - fprintf(hp_file, "%s", lookupGHCName(ctr->identity)); - break; case HEAP_BY_CLOSURE_TYPE: fprintf(hp_file, "%s", (char *)ctr->identity); break; @@ -948,7 +975,8 @@ heapCensusChain( Census *census, bdescr *bd ) size = bco_sizeW((StgBCO *)p); break; - case MVAR: + case MVAR_CLEAN: + case MVAR_DIRTY: case WEAK: case STABLE_NAME: case MUT_VAR_CLEAN: @@ -984,10 +1012,7 @@ heapCensusChain( Census *census, bdescr *bd ) case TSO: prim = rtsTrue; -#ifdef DEBUG_HEAP_PROF - size = tso_sizeW((StgTSO *)p); - break; -#else +#ifdef PROFILING if (RtsFlags.ProfFlags.includeTSOs) { size = tso_sizeW((StgTSO *)p); break; @@ -996,6 +1021,9 @@ heapCensusChain( Census *census, bdescr *bd ) p += tso_sizeW((StgTSO *)p); continue; } +#else + size = tso_sizeW((StgTSO *)p); + break; #endif case TREC_HEADER: @@ -1034,11 +1062,11 @@ heapCensusChain( Census *census, bdescr *bd ) identity = NULL; -#ifdef DEBUG_HEAP_PROF - real_size = size; -#else +#ifdef PROFILING // subtract the profiling overhead real_size = size - sizeofW(StgProfHeader); +#else + real_size = size; #endif if (closureSatisfiesConstraints((StgClosure*)p)) { @@ -1123,13 +1151,6 @@ heapCensus( void ) #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 { @@ -1158,13 +1179,13 @@ heapCensus( void ) // future restriction by biography. #ifdef PROFILING if (RtsFlags.ProfFlags.bioSelector == NULL) -#endif { freeHashTable( census->hash, NULL/* don't free the elements */ ); arenaFree( census->arena ); census->hash = NULL; census->arena = NULL; } +#endif // we're into the next time period now nextEra(); @@ -1174,5 +1195,3 @@ heapCensus( void ) #endif } -#endif /* PROFILING || DEBUG_HEAP_PROF */ -