summaryrefslogtreecommitdiff
path: root/rts
diff options
context:
space:
mode:
authorDaniel Gröber <dxld@darkboxed.org>2019-06-23 18:41:40 +0200
committerDaniel Gröber <dxld@darkboxed.org>2019-09-22 15:18:10 +0200
commit64ec45a798f9b335ab9ba8cb2c7bb9ae0f056ba1 (patch)
treebbaf428de7cec92e1b92a28f914cda00015ab3fd /rts
parentb7e15d17a48286548f26f93594fb1b0b700dd422 (diff)
downloadhaskell-64ec45a798f9b335ab9ba8cb2c7bb9ae0f056ba1.tar.gz
rts: retainer: Reduce DEBUG_RETAINER ifdef noise
Keeping track of the maximum stack seems like a good idea in all configurations. The associated ASSERTs only materialize in debug mode but having the statistic is nice. To make the debug code less prone to bitrotting I introduce a function 'debug()' which doesn't actually print by default and is #define'd away only when the standard DEBUG define is off.
Diffstat (limited to 'rts')
-rw-r--r--rts/RetainerProfile.c91
-rw-r--r--rts/RetainerSet.c7
-rw-r--r--rts/Stats.c4
-rw-r--r--rts/Stats.h6
4 files changed, 39 insertions, 69 deletions
diff --git a/rts/RetainerProfile.c b/rts/RetainerProfile.c
index e127afe5ae..c9b42956a1 100644
--- a/rts/RetainerProfile.c
+++ b/rts/RetainerProfile.c
@@ -211,7 +211,6 @@ typedef struct {
*/
stackElement *currentStackBoundary;
-#if defined(DEBUG_RETAINER)
/*
stackSize records the current size of the stack.
maxStackSize records its high water mark.
@@ -225,7 +224,6 @@ typedef struct {
than the actual depth of the graph.
*/
int stackSize, maxStackSize;
-#endif
} traverseState;
/* Callback called when heap traversal visits a closure.
@@ -250,6 +248,22 @@ static void traverseStack(traverseState *, StgClosure *, stackData, StgPtr, StgP
static void traverseClosure(traverseState *, StgClosure *, StgClosure *, retainer);
static void traversePushClosure(traverseState *, StgClosure *, StgClosure *, stackData);
+#if defined(DEBUG)
+unsigned int g_traversalDebugLevel = 0;
+static inline void debug(const char *s, ...)
+{
+ va_list ap;
+
+ if(g_traversalDebugLevel == 0)
+ return;
+
+ va_start(ap,s);
+ vdebugBelch(s, ap);
+ va_end(ap);
+}
+#else
+#define debug(...)
+#endif
// number of blocks allocated for one stack
#define BLOCKS_IN_STACK 1
@@ -427,9 +441,7 @@ pushStackElement(traverseState *ts, stackElement *se)
{
bdescr *nbd; // Next Block Descriptor
if (ts->stackTop - 1 < ts->stackBottom) {
-#if defined(DEBUG_RETAINER)
- // debugBelch("push() to the next stack.\n");
-#endif
+ debug("pop() to the next stack.\n");
// currentStack->free is updated when the active stack is switched
// to the next stack.
ts->currentStack->free = (StgPtr)ts->stackTop;
@@ -453,13 +465,10 @@ pushStackElement(traverseState *ts, stackElement *se)
// small enough (5 words) that this direct assignment seems to be enough.
*ts->stackTop = *se;
-#if defined(DEBUG_RETAINER)
ts->stackSize++;
if (ts->stackSize > ts->maxStackSize) ts->maxStackSize = ts->stackSize;
ASSERT(ts->stackSize >= 0);
- debugBelch("stackSize = %d\n", ts->stackSize);
-#endif
-
+ debug("stackSize = %d\n", ts->stackSize);
}
/* Push an object onto traverse stack. This method can be used anytime
@@ -503,9 +512,7 @@ traversePushChildren(traverseState *ts, StgClosure *c, stackData data, StgClosur
stackElement se;
bdescr *nbd; // Next Block Descriptor
-#if defined(DEBUG_RETAINER)
- debugBelch("push(): stackTop = 0x%x, currentStackBoundary = 0x%x\n", ts->stackTop, ts->currentStackBoundary);
-#endif
+ debug("push(): stackTop = 0x%x, currentStackBoundary = 0x%x\n", ts->stackTop, ts->currentStackBoundary);
ASSERT(get_itbl(c)->type != TSO);
ASSERT(get_itbl(c)->type != AP_STACK);
@@ -720,9 +727,7 @@ traversePushChildren(traverseState *ts, StgClosure *c, stackData data, StgClosur
* -------------------------------------------------------------------------- */
static void
popStackElement(traverseState *ts) {
-#if defined(DEBUG_RETAINER)
- debugBelch("popStackElement(): stackTop = 0x%x, currentStackBoundary = 0x%x\n", ts->stackTop, ts->currentStackBoundary);
-#endif
+ debug("popStackElement(): stackTop = 0x%x, currentStackBoundary = 0x%x\n", ts->stackTop, ts->currentStackBoundary);
ASSERT(ts->stackTop != ts->stackLimit);
ASSERT(!isEmptyWorkStack(ts));
@@ -730,20 +735,18 @@ popStackElement(traverseState *ts) {
// <= (instead of <) is wrong!
if (ts->stackTop + 1 < ts->stackLimit) {
ts->stackTop++;
-#if defined(DEBUG_RETAINER)
+
ts->stackSize--;
if (ts->stackSize > ts->maxStackSize) ts->maxStackSize = ts->stackSize;
ASSERT(ts->stackSize >= 0);
- debugBelch("stackSize = (--) %d\n", ts->stackSize);
-#endif
+ debug("stackSize = (--) %d\n", ts->stackSize);
+
return;
}
bdescr *pbd; // Previous Block Descriptor
-#if defined(DEBUG_RETAINER)
- debugBelch("pop() to the previous stack.\n");
-#endif
+ debug("pop() to the previous stack.\n");
ASSERT(ts->stackTop + 1 == ts->stackLimit);
ASSERT(ts->stackBottom == (stackElement *)ts->currentStack->start);
@@ -752,12 +755,12 @@ popStackElement(traverseState *ts) {
// The stack is completely empty.
ts->stackTop++;
ASSERT(ts->stackTop == ts->stackLimit);
-#if defined(DEBUG_RETAINER)
+
ts->stackSize--;
if (ts->stackSize > ts->maxStackSize) ts->maxStackSize = ts->stackSize;
ASSERT(ts->stackSize >= 0);
- debugBelch("stackSize = %d\n", ts->stackSize);
-#endif
+ debug("stackSize = %d\n", ts->stackSize);
+
return;
}
@@ -771,12 +774,10 @@ popStackElement(traverseState *ts) {
returnToOldStack(ts, pbd);
-#if defined(DEBUG_RETAINER)
ts->stackSize--;
if (ts->stackSize > ts->maxStackSize) ts->maxStackSize = ts->stackSize;
ASSERT(ts->stackSize >= 0);
- debugBelch("stackSize = %d\n", ts->stackSize);
-#endif
+ debug("stackSize = %d\n", ts->stackSize);
}
/* -----------------------------------------------------------------------------
@@ -802,9 +803,7 @@ traversePop(traverseState *ts, StgClosure **c, StgClosure **cp, stackData *data)
{
stackElement *se;
-#if defined(DEBUG_RETAINER)
- debugBelch("pop(): stackTop = 0x%x, currentStackBoundary = 0x%x\n", ts->stackTop, ts->currentStackBoundary);
-#endif
+ debug("pop(): stackTop = 0x%x currentStackBoundary = 0x%x\n", ts->stackTop, ts->currentStackBoundary);
// Is this the last internal element? If so instead of modifying the current
// stackElement in place we actually remove it from the stack.
@@ -1274,10 +1273,8 @@ traversePushStack(traverseState *ts, StgClosure *cp, stackData data,
oldStackBoundary = ts->currentStackBoundary;
ts->currentStackBoundary = ts->stackTop;
-#if defined(DEBUG_RETAINER)
- debugBelch("retainStack() called: oldStackBoundary = 0x%x, currentStackBoundary = 0x%x\n",
+ debug("retainStack() called: oldStackBoundary = 0x%x, currentStackBoundary = 0x%x\n",
oldStackBoundary, ts->currentStackBoundary);
-#endif
ASSERT(get_itbl(cp)->type == STACK);
@@ -1370,10 +1367,8 @@ traversePushStack(traverseState *ts, StgClosure *cp, stackData data,
// restore currentStackBoundary
ts->currentStackBoundary = oldStackBoundary;
-#if defined(DEBUG_RETAINER)
- debugBelch("retainStack() finished: currentStackBoundary = 0x%x\n",
+ debug("retainStack() finished: currentStackBoundary = 0x%x\n",
ts->currentStackBoundary);
-#endif
}
/* ----------------------------------------------------------------------------
@@ -1533,6 +1528,7 @@ loop:
traversePop(ts, &c, &cp, &data);
if (c == NULL) {
+ debug("maxStackSize= %d\n", ts->maxStackSize);
return;
}
inner_loop:
@@ -1545,9 +1541,7 @@ inner_loop:
case TSO:
if (((StgTSO *)c)->what_next == ThreadComplete ||
((StgTSO *)c)->what_next == ThreadKilled) {
-#if defined(DEBUG_RETAINER)
- debugBelch("ThreadComplete or ThreadKilled encountered in retainClosure()\n");
-#endif
+ debug("ThreadComplete or ThreadKilled encountered in retainClosure()\n");
goto loop;
}
break;
@@ -1803,20 +1797,14 @@ computeRetainerSet( traverseState *ts )
void
resetStaticObjectForProfiling( StgClosure *static_objects )
{
-#if defined(DEBUG_RETAINER)
- uint32_t count;
-#endif
+ uint32_t count = 0;
StgClosure *p;
-#if defined(DEBUG_RETAINER)
- count = 0;
-#endif
p = static_objects;
while (p != END_OF_STATIC_OBJECT_LIST) {
p = UNTAG_STATIC_LIST_PTR(p);
-#if defined(DEBUG_RETAINER)
count++;
-#endif
+
switch (get_itbl(p)->type) {
case IND_STATIC:
// Since we do not compute the retainer set of any
@@ -1843,9 +1831,8 @@ resetStaticObjectForProfiling( StgClosure *static_objects )
break;
}
}
-#if defined(DEBUG_RETAINER)
- debugBelch("count in scavenged_static_objects = %d\n", count);
-#endif
+
+ debug("count in scavenged_static_objects = %d\n", count);
}
/* -----------------------------------------------------------------------------
@@ -1865,10 +1852,8 @@ retainerProfile(void)
// Now we flips flip.
flip = flip ^ 1;
-#if defined(DEBUG_RETAINER)
g_retainerTraverseState.stackSize = 0;
g_retainerTraverseState.maxStackSize = 0;
-#endif
numObjectVisited = 0;
timesAnyObjectVisited = 0;
@@ -1888,9 +1873,7 @@ retainerProfile(void)
stat_endRP(
retainerGeneration - 1, // retainerGeneration has just been incremented!
-#if defined(DEBUG_RETAINER)
g_retainerTraverseState.maxStackSize,
-#endif
(double)timesAnyObjectVisited / numObjectVisited);
}
diff --git a/rts/RetainerSet.c b/rts/RetainerSet.c
index 98cfcec225..556bcc0eab 100644
--- a/rts/RetainerSet.c
+++ b/rts/RetainerSet.c
@@ -127,9 +127,7 @@ addElement(retainer r, RetainerSet *rs)
RetainerSet *nrs; // New Retainer Set
StgWord hk; // Hash Key
-#if defined(DEBUG_RETAINER)
// debugBelch("addElement(%p, %p) = ", r, rs);
-#endif
ASSERT(rs != NULL);
ASSERT(rs->num <= RtsFlags.ProfFlags.maxRetainerSetSize);
@@ -167,9 +165,8 @@ addElement(retainer r, RetainerSet *rs)
if (rs->element[i] != nrs->element[i + 1]) break;
if (i < rs->num) continue;
-#if defined(DEBUG_RETAINER)
// debugBelch("%p\n", nrs);
-#endif
+
// The set we are seeking already exists!
return nrs;
}
@@ -190,9 +187,7 @@ addElement(retainer r, RetainerSet *rs)
hashTable[hash(hk)] = nrs;
-#if defined(DEBUG_RETAINER)
// debugBelch("%p\n", nrs);
-#endif
return nrs;
}
diff --git a/rts/Stats.c b/rts/Stats.c
index b3730c611e..41427d0430 100644
--- a/rts/Stats.c
+++ b/rts/Stats.c
@@ -515,9 +515,7 @@ stat_startRP(void)
void
stat_endRP(
uint32_t retainerGeneration,
-#if defined(DEBUG_RETAINER)
int maxStackSize,
-#endif
double averageNumVisit)
{
Time user, elapsed;
@@ -528,9 +526,7 @@ stat_endRP(
fprintf(prof_file, "Retainer Profiling: %d, at %f seconds\n",
retainerGeneration, mut_user_time_during_RP());
-#if defined(DEBUG_RETAINER)
fprintf(prof_file, "\tMax auxiliary stack size = %u\n", maxStackSize);
-#endif
fprintf(prof_file, "\tAverage number of visits per object = %f\n",
averageNumVisit);
}
diff --git a/rts/Stats.h b/rts/Stats.h
index 73bed2273d..1f498aea23 100644
--- a/rts/Stats.h
+++ b/rts/Stats.h
@@ -39,11 +39,7 @@ void stat_endGC (Capability *cap, struct gc_thread_ *_gct, W_ live,
#if defined(PROFILING)
void stat_startRP(void);
-void stat_endRP(uint32_t,
-#if defined(DEBUG_RETAINER)
- int,
-#endif
- double);
+void stat_endRP(uint32_t, int, double);
#endif /* PROFILING */
#if defined(PROFILING) || defined(DEBUG)