/* -----------------------------------------------------------------------------
- * $Id: RetainerProfile.c,v 1.10 2003/05/16 14:39:29 simonmar Exp $
*
* (c) The GHC Team, 2001
* Author: Sungwoo Park
#define INLINE inline
#endif
-#include <stdio.h>
-
#include "Rts.h"
#include "RtsUtils.h"
#include "RetainerProfile.h"
#include "Schedule.h"
#include "Printer.h"
#include "Storage.h"
-#include "StoragePriv.h"
#include "RtsFlags.h"
#include "Weak.h"
#include "Sanity.h"
-#include "StablePriv.h"
#include "Profiling.h"
#include "Stats.h"
#include "BlockAlloc.h"
{
if (infoTable->i.srt_bitmap == (StgHalfWord)(-1)) {
info->type = posTypeLargeSRT;
- info->next.large_srt.srt = (StgLargeSRT *)infoTable->srt;
+ info->next.large_srt.srt = (StgLargeSRT *)GET_FUN_SRT(infoTable);
info->next.large_srt.offset = 0;
} else {
info->type = posTypeSRT;
- info->next.srt.srt = (StgClosure **)(infoTable->srt);
+ info->next.srt.srt = (StgClosure **)GET_FUN_SRT(infoTable);
info->next.srt.srt_bitmap = infoTable->i.srt_bitmap;
}
}
{
if (infoTable->i.srt_bitmap == (StgHalfWord)(-1)) {
info->type = posTypeLargeSRT;
- info->next.large_srt.srt = (StgLargeSRT *)infoTable->srt;
+ info->next.large_srt.srt = (StgLargeSRT *)GET_SRT(infoTable);
info->next.large_srt.offset = 0;
} else {
info->type = posTypeSRT;
- info->next.srt.srt = (StgClosure **)(infoTable->srt);
+ info->next.srt.srt = (StgClosure **)GET_SRT(infoTable);
info->next.srt.srt_bitmap = infoTable->i.srt_bitmap;
}
}
bdescr *nbd; // Next Block Descriptor
#ifdef DEBUG_RETAINER
- // fprintf(stderr, "push(): stackTop = 0x%x, currentStackBoundary = 0x%x\n", stackTop, currentStackBoundary);
+ // debugBelch("push(): stackTop = 0x%x, currentStackBoundary = 0x%x\n", stackTop, currentStackBoundary);
#endif
ASSERT(get_itbl(c)->type != TSO);
if (stackTop - 1 < stackBottom) {
#ifdef DEBUG_RETAINER
- // fprintf(stderr, "push() to the next stack.\n");
+ // debugBelch("push() to the next stack.\n");
#endif
// currentStack->free is updated when the active stack is switched
// to the next stack.
stackSize++;
if (stackSize > maxStackSize) maxStackSize = stackSize;
// ASSERT(stackSize >= 0);
- // fprintf(stderr, "stackSize = %d\n", stackSize);
+ // debugBelch("stackSize = %d\n", stackSize);
#endif
}
bdescr *pbd; // Previous Block Descriptor
#ifdef DEBUG_RETAINER
- // fprintf(stderr, "pop() to the previous stack.\n");
+ // debugBelch("pop() to the previous stack.\n");
#endif
ASSERT(stackTop + 1 == stackLimit);
if (stackSize > maxStackSize) maxStackSize = stackSize;
/*
ASSERT(stackSize >= 0);
- fprintf(stderr, "stackSize = %d\n", stackSize);
+ debugBelch("stackSize = %d\n", stackSize);
*/
#endif
return;
if (stackSize > maxStackSize) maxStackSize = stackSize;
/*
ASSERT(stackSize >= 0);
- fprintf(stderr, "stackSize = %d\n", stackSize);
+ debugBelch("stackSize = %d\n", stackSize);
*/
#endif
}
static INLINE void
popOff(void) {
#ifdef DEBUG_RETAINER
- // fprintf(stderr, "\tpopOff(): stackTop = 0x%x, currentStackBoundary = 0x%x\n", stackTop, currentStackBoundary);
+ // debugBelch("\tpopOff(): stackTop = 0x%x, currentStackBoundary = 0x%x\n", stackTop, currentStackBoundary);
#endif
ASSERT(stackTop != stackLimit);
if (stackSize > maxStackSize) maxStackSize = stackSize;
/*
ASSERT(stackSize >= 0);
- fprintf(stderr, "stackSize = %d\n", stackSize);
+ debugBelch("stackSize = %d\n", stackSize);
*/
#endif
return;
stackElement *se;
#ifdef DEBUG_RETAINER
- // fprintf(stderr, "pop(): stackTop = 0x%x, currentStackBoundary = 0x%x\n", stackTop, currentStackBoundary);
+ // debugBelch("pop(): stackTop = 0x%x, currentStackBoundary = 0x%x\n", stackTop, currentStackBoundary);
#endif
do {
currentStackBoundary = stackTop;
#ifdef DEBUG_RETAINER
- // fprintf(stderr, "retainStack() called: oldStackBoundary = 0x%x, currentStackBoundary = 0x%x\n", oldStackBoundary, currentStackBoundary);
+ // debugBelch("retainStack() called: oldStackBoundary = 0x%x, currentStackBoundary = 0x%x\n", oldStackBoundary, currentStackBoundary);
#endif
ASSERT(get_itbl(c)->type != TSO ||
p = retain_small_bitmap(p, size, bitmap, c, c_child_r);
follow_srt:
- retainSRT((StgClosure **)info->srt, info->i.srt_bitmap, c, c_child_r);
+ retainSRT((StgClosure **)GET_SRT(info), info->i.srt_bitmap, c, c_child_r);
continue;
case RET_BCO: {
// large bitmap (> 32 entries, or > 64 on a 64-bit machine)
case RET_BIG:
case RET_VEC_BIG:
- size = info->i.layout.large_bitmap->size;
+ size = GET_LARGE_BITMAP(&info->i)->size;
p++;
- retain_large_bitmap(p, info->i.layout.large_bitmap,
+ retain_large_bitmap(p, GET_LARGE_BITMAP(&info->i),
size, c, c_child_r);
p += size;
// and don't forget to follow the SRT
dyn = ((StgRetDyn *)p)->liveness;
// traverse the bitmap first
- bitmap = GET_LIVENESS(dyn);
+ bitmap = RET_DYN_LIVENESS(dyn);
p = (P_)&((StgRetDyn *)p)->payload[0];
size = RET_DYN_BITMAP_SIZE;
p = retain_small_bitmap(p, size, bitmap, c, c_child_r);
// skip over the non-ptr words
- p += GET_NONPTRS(dyn) + RET_DYN_NONPTR_REGS_SIZE;
+ p += RET_DYN_NONPTRS(dyn) + RET_DYN_NONPTR_REGS_SIZE;
// follow the ptr words
- for (size = GET_PTRS(dyn); size > 0; size--) {
+ for (size = RET_DYN_PTRS(dyn); size > 0; size--) {
retainClosure((StgClosure *)*p, c, c_child_r);
p++;
}
fun_info = get_fun_itbl(ret_fun->fun);
p = (P_)&ret_fun->payload;
- switch (fun_info->fun_type) {
+ switch (fun_info->f.fun_type) {
case ARG_GEN:
- bitmap = BITMAP_BITS(fun_info->bitmap);
- size = BITMAP_SIZE(fun_info->bitmap);
+ bitmap = BITMAP_BITS(fun_info->f.bitmap);
+ size = BITMAP_SIZE(fun_info->f.bitmap);
p = retain_small_bitmap(p, size, bitmap, c, c_child_r);
break;
case ARG_GEN_BIG:
- size = ((StgLargeBitmap *)fun_info->bitmap)->size;
- retain_large_bitmap(p, (StgLargeBitmap *)fun_info->bitmap,
+ size = GET_FUN_LARGE_BITMAP(fun_info)->size;
+ retain_large_bitmap(p, GET_FUN_LARGE_BITMAP(fun_info),
size, c, c_child_r);
p += size;
break;
default:
- bitmap = BITMAP_BITS(stg_arg_bitmaps[fun_info->fun_type]);
- size = BITMAP_SIZE(stg_arg_bitmaps[fun_info->fun_type]);
+ bitmap = BITMAP_BITS(stg_arg_bitmaps[fun_info->f.fun_type]);
+ size = BITMAP_SIZE(stg_arg_bitmaps[fun_info->f.fun_type]);
p = retain_small_bitmap(p, size, bitmap, c, c_child_r);
break;
}
// restore currentStackBoundary
currentStackBoundary = oldStackBoundary;
#ifdef DEBUG_RETAINER
- // fprintf(stderr, "retainStack() finished: currentStackBoundary = 0x%x\n", currentStackBoundary);
+ // debugBelch("retainStack() finished: currentStackBoundary = 0x%x\n", currentStackBoundary);
#endif
#ifdef DEBUG_RETAINER
p = (StgPtr)pap->payload;
size = pap->n_args;
- switch (fun_info->fun_type) {
+ switch (fun_info->f.fun_type) {
case ARG_GEN:
- bitmap = BITMAP_BITS(fun_info->bitmap);
+ bitmap = BITMAP_BITS(fun_info->f.bitmap);
p = retain_small_bitmap(p, pap->n_args, bitmap,
(StgClosure *)pap, c_child_r);
break;
case ARG_GEN_BIG:
- retain_large_bitmap(p, (StgLargeBitmap *)fun_info->bitmap,
+ retain_large_bitmap(p, GET_FUN_LARGE_BITMAP(fun_info),
size, (StgClosure *)pap, c_child_r);
p += size;
break;
p += size;
break;
default:
- bitmap = BITMAP_BITS(stg_arg_bitmaps[fun_info->fun_type]);
+ bitmap = BITMAP_BITS(stg_arg_bitmaps[fun_info->f.fun_type]);
p = retain_small_bitmap(p, pap->n_args, bitmap,
(StgClosure *)pap, c_child_r);
break;
#ifdef DEBUG_RETAINER
// oldStackTop = stackTop;
- // fprintf(stderr, "retainClosure() called: c0 = 0x%x, cp0 = 0x%x, r0 = 0x%x\n", c0, cp0, r0);
+ // debugBelch("retainClosure() called: c0 = 0x%x, cp0 = 0x%x, r0 = 0x%x\n", c0, cp0, r0);
#endif
// (c, cp, r) = (c0, cp0, r0)
goto inner_loop;
loop:
- //fprintf(stderr, "loop");
+ //debugBelch("loop");
// pop to (c, cp, r);
pop(&c, &cp, &r);
if (c == NULL) {
#ifdef DEBUG_RETAINER
- // fprintf(stderr, "retainClosure() ends: oldStackTop = 0x%x, stackTop = 0x%x\n", oldStackTop, stackTop);
+ // debugBelch("retainClosure() ends: oldStackTop = 0x%x, stackTop = 0x%x\n", oldStackTop, stackTop);
#endif
return;
}
- //fprintf(stderr, "inner_loop");
+ //debugBelch("inner_loop");
inner_loop:
// c = current closure under consideration,
if (((StgTSO *)c)->what_next == ThreadComplete ||
((StgTSO *)c)->what_next == ThreadKilled) {
#ifdef DEBUG_RETAINER
- fprintf(stderr, "ThreadComplete or ThreadKilled encountered in retainClosure()\n");
+ debugBelch("ThreadComplete or ThreadKilled encountered in retainClosure()\n");
#endif
goto loop;
}
if (((StgTSO *)c)->what_next == ThreadRelocated) {
#ifdef DEBUG_RETAINER
- fprintf(stderr, "ThreadRelocated encountered in retainClosure()\n");
+ debugBelch("ThreadRelocated encountered in retainClosure()\n");
#endif
c = (StgClosure *)((StgTSO *)c)->link;
goto inner_loop;
}
}
#ifdef DEBUG_RETAINER
- // fprintf(stderr, "count in scavenged_static_objects = %d\n", count);
+ // debugBelch("count in scavenged_static_objects = %d\n", count);
#endif
}
#endif
#ifdef DEBUG_RETAINER
- fprintf(stderr, " < retainerProfile() invoked : %d>\n", retainerGeneration);
+ debugBelch(" < retainerProfile() invoked : %d>\n", retainerGeneration);
#endif
stat_startRP();
// We haven't flipped the bit yet.
#ifdef DEBUG_RETAINER
- fprintf(stderr, "Before traversing:\n");
+ debugBelch("Before traversing:\n");
sumOfCostLinear = 0;
for (i = 0;i < N_CLOSURE_TYPES; i++)
costArrayLinear[i] = 0;
totalHeapSize = checkHeapSanityForRetainerProfiling();
- fprintf(stderr, "\tsumOfCostLinear = %d, totalHeapSize = %d\n", sumOfCostLinear, totalHeapSize);
+ debugBelch("\tsumOfCostLinear = %d, totalHeapSize = %d\n", sumOfCostLinear, totalHeapSize);
/*
- fprintf(stderr, "costArrayLinear[] = ");
+ debugBelch("costArrayLinear[] = ");
for (i = 0;i < N_CLOSURE_TYPES; i++)
- fprintf(stderr, "[%u:%u] ", i, costArrayLinear[i]);
- fprintf(stderr, "\n");
+ debugBelch("[%u:%u] ", i, costArrayLinear[i]);
+ debugBelch("\n");
*/
ASSERT(sumOfCostLinear == totalHeapSize);
/*
#define pcostArrayLinear(index) \
if (costArrayLinear[index] > 0) \
- fprintf(stderr, "costArrayLinear[" #index "] = %u\n", costArrayLinear[index])
+ debugBelch("costArrayLinear[" #index "] = %u\n", costArrayLinear[index])
pcostArrayLinear(THUNK_STATIC);
pcostArrayLinear(FUN_STATIC);
pcostArrayLinear(CONSTR_STATIC);
timesAnyObjectVisited = 0;
#ifdef DEBUG_RETAINER
- fprintf(stderr, "During traversing:\n");
+ debugBelch("During traversing:\n");
sumOfNewCost = 0;
sumOfNewCostExtra = 0;
for (i = 0;i < N_CLOSURE_TYPES; i++)
computeRetainerSet();
#ifdef DEBUG_RETAINER
- fprintf(stderr, "After traversing:\n");
+ debugBelch("After traversing:\n");
sumOfCostLinear = 0;
for (i = 0;i < N_CLOSURE_TYPES; i++)
costArrayLinear[i] = 0;
totalHeapSize = checkHeapSanityForRetainerProfiling();
- fprintf(stderr, "\tsumOfCostLinear = %d, totalHeapSize = %d\n", sumOfCostLinear, totalHeapSize);
+ debugBelch("\tsumOfCostLinear = %d, totalHeapSize = %d\n", sumOfCostLinear, totalHeapSize);
ASSERT(sumOfCostLinear == totalHeapSize);
// now, compare the two results
1) Dead weak pointers, whose type is CONSTR. These objects are not
reachable from any roots.
*/
- fprintf(stderr, "Comparison:\n");
- fprintf(stderr, "\tcostArrayLinear[] (must be empty) = ");
+ debugBelch("Comparison:\n");
+ debugBelch("\tcostArrayLinear[] (must be empty) = ");
for (i = 0;i < N_CLOSURE_TYPES; i++)
if (costArray[i] != costArrayLinear[i])
// nothing should be printed except MUT_VAR after major GCs
- fprintf(stderr, "[%u:%u] ", i, costArrayLinear[i]);
- fprintf(stderr, "\n");
+ debugBelch("[%u:%u] ", i, costArrayLinear[i]);
+ debugBelch("\n");
- fprintf(stderr, "\tsumOfNewCost = %u\n", sumOfNewCost);
- fprintf(stderr, "\tsumOfNewCostExtra = %u\n", sumOfNewCostExtra);
- fprintf(stderr, "\tcostArray[] (must be empty) = ");
+ debugBelch("\tsumOfNewCost = %u\n", sumOfNewCost);
+ debugBelch("\tsumOfNewCostExtra = %u\n", sumOfNewCostExtra);
+ debugBelch("\tcostArray[] (must be empty) = ");
for (i = 0;i < N_CLOSURE_TYPES; i++)
if (costArray[i] != costArrayLinear[i])
// nothing should be printed except MUT_VAR after major GCs
- fprintf(stderr, "[%u:%u] ", i, costArray[i]);
- fprintf(stderr, "\n");
+ debugBelch("[%u:%u] ", i, costArray[i]);
+ debugBelch("\n");
// only for major garbage collection
ASSERT(sumOfNewCost + sumOfNewCostExtra == sumOfCostLinear);
if (get_itbl(c)->type == CONSTR &&
!strcmp(get_itbl(c)->prof.closure_type, "DEAD_WEAK") &&
!strcmp(get_itbl(c)->prof.closure_desc, "DEAD_WEAK")) {
- fprintf(stderr, "\tUnvisited dead weak pointer object found: c = %p\n", c);
+ debugBelch("\tUnvisited dead weak pointer object found: c = %p\n", c);
costArray[get_itbl(c)->type] += cost(c);
sumOfNewCost += cost(c);
} else
- fprintf(stderr,
+ debugBelch(
"Unvisited object: flip = %d, c = %p(%d, %s, %s), rs = %p\n",
flip, c, get_itbl(c)->type,
get_itbl(c)->prof.closure_type, get_itbl(c)->prof.closure_desc,
RSET(c));
} else {
- // fprintf(stderr, "sanityCheckHeapClosure) S: flip = %d, c = %p(%d), rs = %p\n", flip, c, get_itbl(c)->type, RSET(c));
+ // debugBelch("sanityCheckHeapClosure) S: flip = %d, c = %p(%d), rs = %p\n", flip, c, get_itbl(c)->type, RSET(c));
}
info = get_itbl(c);
nat costSum, g, s;
costSum = 0;
- fprintf(stderr, "START: sumOfCostLinear = %d, costSum = %d\n", sumOfCostLinear, costSum);
+ debugBelch("START: sumOfCostLinear = %d, costSum = %d\n", sumOfCostLinear, costSum);
if (RtsFlags.GcFlags.generations == 1) {
costSum += heapCheck(g0s0->to_blocks);
- fprintf(stderr, "heapCheck: sumOfCostLinear = %d, costSum = %d\n", sumOfCostLinear, costSum);
+ debugBelch("heapCheck: sumOfCostLinear = %d, costSum = %d\n", sumOfCostLinear, costSum);
costSum += chainCheck(g0s0->large_objects);
- fprintf(stderr, "chainCheck: sumOfCostLinear = %d, costSum = %d\n", sumOfCostLinear, costSum);
+ debugBelch("chainCheck: sumOfCostLinear = %d, costSum = %d\n", sumOfCostLinear, costSum);
} else {
for (g = 0; g < RtsFlags.GcFlags.generations; g++)
for (s = 0; s < generations[g].n_steps; s++) {
*/
if (g == 0 && s == 0) {
costSum += smallObjectPoolCheck();
- fprintf(stderr, "smallObjectPoolCheck(): sumOfCostLinear = %d, costSum = %d\n", sumOfCostLinear, costSum);
+ debugBelch("smallObjectPoolCheck(): sumOfCostLinear = %d, costSum = %d\n", sumOfCostLinear, costSum);
costSum += chainCheck(generations[g].steps[s].large_objects);
- fprintf(stderr, "chainCheck(): sumOfCostLinear = %d, costSum = %d\n", sumOfCostLinear, costSum);
+ debugBelch("chainCheck(): sumOfCostLinear = %d, costSum = %d\n", sumOfCostLinear, costSum);
} else {
costSum += heapCheck(generations[g].steps[s].blocks);
- fprintf(stderr, "heapCheck(): sumOfCostLinear = %d, costSum = %d\n", sumOfCostLinear, costSum);
+ debugBelch("heapCheck(): sumOfCostLinear = %d, costSum = %d\n", sumOfCostLinear, costSum);
costSum += chainCheck(generations[g].steps[s].large_objects);
- fprintf(stderr, "chainCheck(): sumOfCostLinear = %d, costSum = %d\n", sumOfCostLinear, costSum);
+ debugBelch("chainCheck(): sumOfCostLinear = %d, costSum = %d\n", sumOfCostLinear, costSum);
}
}
}
if (*q == (StgWord)p) {
r = q;
while (!LOOKS_LIKE_GHC_INFO(*r)) r--;
- fprintf(stderr, "Found in gen[%d], step[%d]: q = %p, r = %p\n", g, s, q, r);
+ debugBelch("Found in gen[%d], step[%d]: q = %p, r = %p\n", g, s, q, r);
// return;
}
}
if (*q == (StgWord)p) {
r = q;
while (*r == 0 || !LOOKS_LIKE_GHC_INFO(*r)) r--;
- fprintf(stderr, "Found in gen[%d], large_objects: %p\n", g, r);
+ debugBelch("Found in gen[%d], large_objects: %p\n", g, r);
// return;
}
}
bd = generations[g].steps[s].blocks;
for (; bd; bd = bd->link) {
if (bd->start <= p && p < bd->free) {
- fprintf(stderr, "Belongs to gen[%d], step[%d]", g, s);
+ debugBelch("Belongs to gen[%d], step[%d]", g, s);
return;
}
}
bd = generations[g].steps[s].large_objects;
for (; bd; bd = bd->link) {
if (bd->start <= p && p < bd->start + getHeapClosureSize((StgClosure *)bd->start)) {
- fprintf(stderr, "Found in gen[%d], large_objects: %p\n", g, bd->start);
+ debugBelch("Found in gen[%d], large_objects: %p\n", g, bd->start);
return;
}
}