+ (void)p; /* keep gcc -Wall happy */
+ return rtsTrue;
+#else
+ rtsBool b;
+
+ // The CCS has a selected field to indicate whether this closure is
+ // deselected by not being mentioned in the module, CC, or CCS
+ // selectors.
+ if (!p->header.prof.ccs->selected) {
+ return rtsFalse;
+ }
+
+ if (RtsFlags.ProfFlags.descrSelector) {
+ b = strMatchesSelector( (get_itbl((StgClosure *)p))->prof.closure_desc,
+ RtsFlags.ProfFlags.descrSelector );
+ if (!b) return rtsFalse;
+ }
+ if (RtsFlags.ProfFlags.typeSelector) {
+ b = strMatchesSelector( (get_itbl((StgClosure *)p))->prof.closure_type,
+ RtsFlags.ProfFlags.typeSelector );
+ if (!b) return rtsFalse;
+ }
+ if (RtsFlags.ProfFlags.retainerSelector) {
+ RetainerSet *rs;
+ nat i;
+ // We must check that the retainer set is valid here. One
+ // reason it might not be valid is if this closure is a
+ // a newly deceased weak pointer (i.e. a DEAD_WEAK), since
+ // these aren't reached by the retainer profiler's traversal.
+ if (isRetainerSetFieldValid((StgClosure *)p)) {
+ rs = retainerSetOf((StgClosure *)p);
+ if (rs != NULL) {
+ for (i = 0; i < rs->num; i++) {
+ b = strMatchesSelector( rs->element[i]->cc->label,
+ RtsFlags.ProfFlags.retainerSelector );
+ if (b) return rtsTrue;
+ }
+ }
+ }
+ return rtsFalse;
+ }
+ return rtsTrue;
+#endif /* PROFILING */
+}
+
+/* -----------------------------------------------------------------------------
+ * Aggregate the heap census info for biographical profiling
+ * -------------------------------------------------------------------------- */
+#ifdef PROFILING
+static void
+aggregateCensusInfo( void )
+{
+ HashTable *acc;
+ nat t;
+ counter *c, *d, *ctrs;
+ Arena *arena;
+
+ if (!doingLDVProfiling()) return;
+
+ // Aggregate the LDV counters when displaying by biography.
+ if (RtsFlags.ProfFlags.doHeapProfile == HEAP_BY_LDV) {
+ int void_total, drag_total;
+
+ // Now we compute void_total and drag_total for each census
+ void_total = 0;
+ drag_total = 0;
+ for (t = 1; t < era; t++) { // note: start at 1, not 0
+ void_total += censuses[t].void_total;
+ drag_total += censuses[t].drag_total;
+ censuses[t].void_total = void_total;
+ censuses[t].drag_total = drag_total;
+ ASSERT( censuses[t].void_total <= censuses[t].not_used );
+ ASSERT( censuses[t].drag_total <= censuses[t].used );
+ }
+
+ return;
+ }
+
+ // otherwise... we're doing a heap profile that is restricted to
+ // some combination of lag, drag, void or use. We've kept all the
+ // census info for all censuses so far, but we still need to
+ // aggregate the counters forwards.
+
+ arena = newArena();
+ acc = allocHashTable();
+ ctrs = NULL;
+
+ for (t = 1; t < era; t++) {
+
+ // first look through all the counters we're aggregating
+ for (c = ctrs; c != NULL; c = c->next) {
+ // if one of the totals is non-zero, then this closure
+ // type must be present in the heap at this census time...
+ d = lookupHashTable(censuses[t].hash, (StgWord)c->identity);
+
+ if (d == NULL) {
+ // if this closure identity isn't present in the
+ // census for this time period, then our running
+ // totals *must* be zero.
+ ASSERT(c->c.ldv.void_total == 0 && c->c.ldv.drag_total == 0);
+
+ // fprintCCS(stderr,c->identity);
+ // fprintf(stderr," census=%d void_total=%d drag_total=%d\n",
+ // t, c->c.ldv.void_total, c->c.ldv.drag_total);
+ } else {
+ d->c.ldv.void_total += c->c.ldv.void_total;
+ d->c.ldv.drag_total += c->c.ldv.drag_total;
+ c->c.ldv.void_total = d->c.ldv.void_total;
+ c->c.ldv.drag_total = d->c.ldv.drag_total;
+
+ ASSERT( c->c.ldv.void_total >= 0 );
+ ASSERT( c->c.ldv.drag_total >= 0 );
+ }
+ }
+
+ // now look through the counters in this census to find new ones
+ for (c = censuses[t].ctrs; c != NULL; c = c->next) {
+ d = lookupHashTable(acc, (StgWord)c->identity);
+ if (d == NULL) {
+ d = arenaAlloc( arena, sizeof(counter) );
+ initLDVCtr(d);
+ insertHashTable( acc, (StgWord)c->identity, d );
+ d->identity = c->identity;
+ d->next = ctrs;
+ ctrs = d;
+ d->c.ldv.void_total = c->c.ldv.void_total;
+ d->c.ldv.drag_total = c->c.ldv.drag_total;
+ }
+ ASSERT( c->c.ldv.void_total >= 0 );
+ ASSERT( c->c.ldv.drag_total >= 0 );
+ }
+ }
+
+ freeHashTable(acc, NULL);
+ arenaFree(arena);
+}