#include "RetainerSet.h"
#include "Schedule.h"
#include "Printer.h"
-#include "Storage.h"
#include "RtsFlags.h"
#include "Weak.h"
#include "Sanity.h"
#include "Profiling.h"
#include "Stats.h"
-#include "BlockAlloc.h"
#include "ProfHeap.h"
#include "Apply.h"
bitmap = info->next.srt.srt_bitmap;
while (bitmap != 0) {
if ((bitmap & 1) != 0) {
-#ifdef ENABLE_WIN32_DLL_SUPPORT
-
+#if defined(__PIC__) && defined(mingw32_TARGET_OS)
if ((unsigned long)(*(info->next.srt.srt)) & 0x1)
c = (* (StgClosure **)((unsigned long)*(info->next.srt.srt)) & ~0x1);
else
return; // no child
break;
- case TVAR_WAIT_QUEUE:
- *first_child = (StgClosure *)((StgTVarWaitQueue *)c)->waiting_tso;
+ case TVAR_WATCH_QUEUE:
+ *first_child = (StgClosure *)((StgTVarWatchQueue *)c)->closure;
se.info.next.step = 2; // 2 = second
break;
case TVAR:
case AP_STACK:
case TSO:
case IND_STATIC:
- case CONSTR_INTLIKE:
- case CONSTR_CHARLIKE:
case CONSTR_NOCAF_STATIC:
// stack objects
case UPDATE_FRAME:
case RET_DYN:
case RET_BCO:
case RET_SMALL:
- case RET_VEC_SMALL:
case RET_BIG:
- case RET_VEC_BIG:
// invalid objects
case IND:
case BLOCKED_FETCH:
// following statement by either a memcpy() call or a switch statement
// on the type of the element. Currently, the size of stackElement is
// small enough (5 words) that this direct assignment seems to be enough.
+
+ // ToDo: The line below leads to the warning:
+ // warning: 'se.info.type' may be used uninitialized in this function
+ // This is caused by the fact that there are execution paths through the
+ // large switch statement above where some cases do not initialize this
+ // field. Is this really harmless? Can we avoid the warning?
*stackTop = se;
#ifdef DEBUG_RETAINER
*r = se->c_child_r;
return;
- case TVAR_WAIT_QUEUE:
+ case TVAR_WATCH_QUEUE:
if (se->info.next.step == 2) {
- *c = (StgClosure *)((StgTVarWaitQueue *)se->c)->next_queue_entry;
+ *c = (StgClosure *)((StgTVarWatchQueue *)se->c)->next_queue_entry;
se->info.next.step++; // move to the next step
// no popOff
} else {
- *c = (StgClosure *)((StgTVarWaitQueue *)se->c)->prev_queue_entry;
+ *c = (StgClosure *)((StgTVarWatchQueue *)se->c)->prev_queue_entry;
popOff();
}
*cp = se->c;
return;
case TVAR:
- *c = (StgClosure *)((StgTVar *)se->c)->first_wait_queue_entry;
+ *c = (StgClosure *)((StgTVar *)se->c)->first_watch_queue_entry;
*cp = se->c;
*r = se->c_child_r;
popOff();
case AP_STACK:
case TSO:
case IND_STATIC:
- case CONSTR_INTLIKE:
- case CONSTR_CHARLIKE:
case CONSTR_NOCAF_STATIC:
// stack objects
case RET_DYN:
case STOP_FRAME:
case RET_BCO:
case RET_SMALL:
- case RET_VEC_SMALL:
case RET_BIG:
- case RET_VEC_BIG:
// invalid objects
case IND:
case BLOCKED_FETCH:
case BCO:
case ARR_WORDS:
// STM
- case TVAR_WAIT_QUEUE:
+ case TVAR_WATCH_QUEUE:
case TREC_HEADER:
case TREC_CHUNK:
return rtsFalse;
//
// IND_STATIC cannot be *c, *cp, *r in the retainer profiling loop.
case IND_STATIC:
- // CONSTR_INTLIKE, CONSTR_CHARLIKE, and CONSTR_NOCAF_STATIC
+ // CONSTR_NOCAF_STATIC
// cannot be *c, *cp, *r in the retainer profiling loop.
- case CONSTR_INTLIKE:
- case CONSTR_CHARLIKE:
case CONSTR_NOCAF_STATIC:
// Stack objects are invalid because they are never treated as
// legal objects during retainer profiling.
case RET_DYN:
case RET_BCO:
case RET_SMALL:
- case RET_VEC_SMALL:
case RET_BIG:
- case RET_VEC_BIG:
// other cases
case IND:
case BLOCKED_FETCH:
case CATCH_RETRY_FRAME:
case ATOMICALLY_FRAME:
case RET_SMALL:
- case RET_VEC_SMALL:
bitmap = BITMAP_BITS(info->i.layout.bitmap);
size = BITMAP_SIZE(info->i.layout.bitmap);
p++;
// large bitmap (> 32 entries, or > 64 on a 64-bit machine)
case RET_BIG:
- case RET_VEC_BIG:
size = GET_LARGE_BITMAP(&info->i)->size;
p++;
retain_large_bitmap(p, GET_LARGE_BITMAP(&info->i),
StgFunInfoTable *fun_info;
retainClosure(ret_fun->fun, c, c_child_r);
- fun_info = get_fun_itbl(ret_fun->fun);
+ fun_info = get_fun_itbl(UNTAG_CLOSURE(ret_fun->fun));
p = (P_)&ret_fun->payload;
switch (fun_info->f.fun_type) {
* ------------------------------------------------------------------------- */
static INLINE StgPtr
-retain_PAP_payload (StgClosure *pap, retainer c_child_r, StgClosure *fun,
+retain_PAP_payload (StgClosure *pap, /* NOT tagged */
+ retainer c_child_r, /* NOT tagged */
+ StgClosure *fun, /* tagged */
StgClosure** payload, StgWord n_args)
{
StgPtr p;
StgFunInfoTable *fun_info;
retainClosure(fun, pap, c_child_r);
+ fun = UNTAG_CLOSURE(fun);
fun_info = get_fun_itbl(fun);
ASSERT(fun_info->i.type != PAP);
static void
retainClosure( StgClosure *c0, StgClosure *cp0, retainer r0 )
{
- // c = Current closure
- // cp = Current closure's Parent
- // r = current closures' most recent Retainer
+ // c = Current closure (possibly tagged)
+ // cp = Current closure's Parent (NOT tagged)
+ // r = current closures' most recent Retainer (NOT tagged)
// c_child_r = current closure's children's most recent retainer
// first_child = first child of c
StgClosure *c, *cp, *first_child;
//debugBelch("inner_loop");
inner_loop:
+ c = UNTAG_CLOSURE(c);
+
// c = current closure under consideration,
// cp = current closure's parent,
// r = current closure's most recent retainer
#ifdef DEBUG_RETAINER
switch (typeOfc) {
case IND_STATIC:
- case CONSTR_INTLIKE:
- case CONSTR_CHARLIKE:
case CONSTR_NOCAF_STATIC:
case CONSTR_STATIC:
case THUNK_STATIC:
// We just skip IND_STATIC, so its retainer set is never computed.
c = ((StgIndStatic *)c)->indirectee;
goto inner_loop;
- case CONSTR_INTLIKE:
- case CONSTR_CHARLIKE:
// static objects with no pointers out, so goto loop.
case CONSTR_NOCAF_STATIC:
// It is not just enough not to compute the retainer set for *c; it is
static void
retainRoot( StgClosure **tl )
{
+ StgClosure *c;
+
// We no longer assume that only TSOs and WEAKs are roots; any closure can
// be a root.
ASSERT(isEmptyRetainerStack());
currentStackBoundary = stackTop;
- if (*tl != &stg_END_TSO_QUEUE_closure && isRetainer(*tl)) {
- retainClosure(*tl, *tl, getRetainerFrom(*tl));
+ c = UNTAG_CLOSURE(*tl);
+ if (c != &stg_END_TSO_QUEUE_closure && isRetainer(c)) {
+ retainClosure(c, c, getRetainerFrom(c));
} else {
- retainClosure(*tl, *tl, CCS_SYSTEM);
+ retainClosure(c, c, CCS_SYSTEM);
}
// NOT TRUE: ASSERT(isMember(getRetainerFrom(*tl), retainerSetOf(*tl)));
case IND_STATIC:
// no cost involved
break;
- case CONSTR_INTLIKE:
- case CONSTR_CHARLIKE:
case CONSTR_NOCAF_STATIC:
case CONSTR_STATIC:
case THUNK_STATIC:
pcostArrayLinear(FUN_STATIC);
pcostArrayLinear(CONSTR_STATIC);
pcostArrayLinear(CONSTR_NOCAF_STATIC);
- pcostArrayLinear(CONSTR_INTLIKE);
- pcostArrayLinear(CONSTR_CHARLIKE);
*/
#endif
if ((((StgWord)RSET(c) & 1) ^ flip) != 0) {
if (get_itbl(c)->type == CONSTR &&
- !strcmp(get_itbl(c)->prof.closure_type, "DEAD_WEAK") &&
- !strcmp(get_itbl(c)->prof.closure_desc, "DEAD_WEAK")) {
+ !strcmp(GET_PROF_TYPE(get_itbl(c)), "DEAD_WEAK") &&
+ !strcmp(GET_PROF_DESC(get_itbl(c)), "DEAD_WEAK")) {
debugBelch("\tUnvisited dead weak pointer object found: c = %p\n", c);
costArray[get_itbl(c)->type] += cost(c);
sumOfNewCost += cost(c);
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,
+ get_itbl(c)->prof.closure_type, GET_PROF_DESC(get_itbl(c)),
RSET(c));
} else {
// debugBelch("sanityCheckHeapClosure) S: flip = %d, c = %p(%d), rs = %p\n", flip, c, get_itbl(c)->type, RSET(c));