static void
checkClosureShallow( StgClosure* p )
{
- ASSERT(LOOKS_LIKE_CLOSURE_PTR(p));
+ StgClosure *q;
+
+ q = UNTAG_CLOSURE(p);
+ ASSERT(LOOKS_LIKE_CLOSURE_PTR(q));
/* Is it a static closure? */
- if (!HEAP_ALLOCED(p)) {
- ASSERT(closure_STATIC(p));
+ if (!HEAP_ALLOCED(q)) {
+ ASSERT(closure_STATIC(q));
} else {
- ASSERT(!closure_STATIC(p));
+ ASSERT(!closure_STATIC(q));
}
}
// small bitmap cases (<= 32 entries)
case STOP_FRAME:
case RET_SMALL:
- case RET_VEC_SMALL:
size = BITMAP_SIZE(info->i.layout.bitmap);
checkSmallBitmap((StgPtr)c + 1,
BITMAP_BITS(info->i.layout.bitmap), size);
}
case RET_BIG: // large bitmap (> 32 entries)
- case RET_VEC_BIG:
size = GET_LARGE_BITMAP(&info->i)->size;
checkLargeBitmap((StgPtr)c + 1, GET_LARGE_BITMAP(&info->i), size);
return 1 + size;
StgRetFun *ret_fun;
ret_fun = (StgRetFun *)c;
- fun_info = get_fun_itbl(ret_fun->fun);
+ fun_info = get_fun_itbl(UNTAG_CLOSURE(ret_fun->fun));
size = ret_fun->size;
switch (fun_info->f.fun_type) {
case ARG_GEN:
}
static void
-checkPAP (StgClosure *fun, StgClosure** payload, StgWord n_args)
+checkPAP (StgClosure *tagged_fun, StgClosure** payload, StgWord n_args)
{
+ StgClosure *fun;
StgClosure *p;
StgFunInfoTable *fun_info;
+ fun = UNTAG_CLOSURE(tagged_fun);
ASSERT(LOOKS_LIKE_CLOSURE_PTR(fun));
fun_info = get_fun_itbl(fun);
n_args );
break;
}
+
+ ASSERT(fun_info->f.arity > TAG_MASK ? GET_CLOSURE_TAG(tagged_fun) == 1
+ : GET_CLOSURE_TAG(tagged_fun) == fun_info->f.arity);
}
{
const StgInfoTable *info;
- ASSERT(LOOKS_LIKE_INFO_PTR(p->header.info));
+ ASSERT(LOOKS_LIKE_CLOSURE_PTR(p));
+ p = UNTAG_CLOSURE(p);
/* Is it a static closure (i.e. in the data segment)? */
if (!HEAP_ALLOCED(p)) {
ASSERT(closure_STATIC(p));
ASSERT(!closure_STATIC(p));
}
- info = get_itbl(p);
+ info = p->header.info;
+
+ if (IS_FORWARDING_PTR(info)) {
+ barf("checkClosure: found EVACUATED closure %d", info->type);
+ }
+ info = INFO_PTR_TO_STRUCT(info);
+
switch (info->type) {
- case MVAR:
+ case MVAR_CLEAN:
+ case MVAR_DIRTY:
{
StgMVar *mvar = (StgMVar *)p;
ASSERT(LOOKS_LIKE_CLOSURE_PTR(mvar->head));
case IND_PERM:
case IND_OLDGEN:
case IND_OLDGEN_PERM:
-#ifdef TICKY_TICKY
- case SE_BLACKHOLE:
- case SE_CAF_BLACKHOLE:
-#endif
case BLACKHOLE:
case CAF_BLACKHOLE:
case STABLE_NAME:
case MUT_VAR_CLEAN:
case MUT_VAR_DIRTY:
- case CONSTR_INTLIKE:
- case CONSTR_CHARLIKE:
case CONSTR_STATIC:
case CONSTR_NOCAF_STATIC:
case THUNK_STATIC:
ASSERT(LOOKS_LIKE_CLOSURE_PTR(bco->instrs));
ASSERT(LOOKS_LIKE_CLOSURE_PTR(bco->literals));
ASSERT(LOOKS_LIKE_CLOSURE_PTR(bco->ptrs));
- ASSERT(LOOKS_LIKE_CLOSURE_PTR(bco->itbls));
return bco_sizeW(bco);
}
case RET_BCO:
case RET_SMALL:
- case RET_VEC_SMALL:
case RET_BIG:
- case RET_VEC_BIG:
case RET_DYN:
case UPDATE_FRAME:
case STOP_FRAME:
#endif
- case TVAR_WAIT_QUEUE:
+ case TVAR_WATCH_QUEUE:
{
- StgTVarWaitQueue *wq = (StgTVarWaitQueue *)p;
+ StgTVarWatchQueue *wq = (StgTVarWatchQueue *)p;
ASSERT(LOOKS_LIKE_CLOSURE_PTR(wq->next_queue_entry));
ASSERT(LOOKS_LIKE_CLOSURE_PTR(wq->prev_queue_entry));
- return sizeofW(StgTVarWaitQueue);
+ return sizeofW(StgTVarWatchQueue);
+ }
+
+ case INVARIANT_CHECK_QUEUE:
+ {
+ StgInvariantCheckQueue *q = (StgInvariantCheckQueue *)p;
+ ASSERT(LOOKS_LIKE_CLOSURE_PTR(q->invariant));
+ ASSERT(LOOKS_LIKE_CLOSURE_PTR(q->my_execution));
+ ASSERT(LOOKS_LIKE_CLOSURE_PTR(q->next_queue_entry));
+ return sizeofW(StgInvariantCheckQueue);
+ }
+
+ case ATOMIC_INVARIANT:
+ {
+ StgAtomicInvariant *invariant = (StgAtomicInvariant *)p;
+ ASSERT(LOOKS_LIKE_CLOSURE_PTR(invariant->code));
+ ASSERT(LOOKS_LIKE_CLOSURE_PTR(invariant->last_execution));
+ return sizeofW(StgAtomicInvariant);
}
case TVAR:
{
StgTVar *tv = (StgTVar *)p;
ASSERT(LOOKS_LIKE_CLOSURE_PTR(tv->current_value));
- ASSERT(LOOKS_LIKE_CLOSURE_PTR(tv->first_wait_queue_entry));
+ ASSERT(LOOKS_LIKE_CLOSURE_PTR(tv->first_watch_queue_entry));
return sizeofW(StgTVar);
}
return sizeofW(StgTRecHeader);
}
-
- case EVACUATED:
- barf("checkClosure: found EVACUATED closure %d",
- info->type);
default:
barf("checkClosure (closure type %d)", info->type);
}
/* skip over slop */
while (p < bd->free &&
- (*p < 0x1000 || !LOOKS_LIKE_INFO_PTR((void*)*p))) { p++; }
+ (*p < 0x1000 || !LOOKS_LIKE_INFO_PTR(*p))) { p++; }
}
}
}
nat size;
for (p=start; p<end; p+=size) {
- ASSERT(LOOKS_LIKE_INFO_PTR((void*)*p));
+ ASSERT(LOOKS_LIKE_INFO_PTR(*p));
size = checkClosure((StgClosure *)p);
/* This is the smallest size of closure that can live in the heap. */
ASSERT( size >= MIN_PAYLOAD_SIZE + sizeofW(StgHeader) );
StgPtr stack_end = stack + stack_size;
if (tso->what_next == ThreadRelocated) {
- checkTSO(tso->link);
+ checkTSO(tso->_link);
return;
}
void
checkGlobalTSOList (rtsBool checkTSOs)
{
- extern StgTSO *all_threads;
StgTSO *tso;
- for (tso=all_threads; tso != END_TSO_QUEUE; tso = tso->global_link) {
- ASSERT(LOOKS_LIKE_CLOSURE_PTR(tso));
- ASSERT(get_itbl(tso)->type == TSO);
- if (checkTSOs)
- checkTSO(tso);
+ nat s;
+
+ for (s = 0; s < total_steps; s++) {
+ for (tso=all_steps[s].threads; tso != END_TSO_QUEUE;
+ tso = tso->global_link) {
+ ASSERT(LOOKS_LIKE_CLOSURE_PTR(tso));
+ ASSERT(get_itbl(tso)->type == TSO);
+ if (checkTSOs)
+ checkTSO(tso);
+
+ // If this TSO is dirty and in an old generation, it better
+ // be on the mutable list.
+ if (tso->what_next == ThreadRelocated) continue;
+ if (tso->flags & (TSO_DIRTY|TSO_LINK_DIRTY)) {
+ ASSERT(Bdescr((P_)tso)->gen_no == 0 || (tso->flags & TSO_MARKED));
+ tso->flags &= ~TSO_MARKED;
+ }
+ }
}
}
for (q = bd->start; q < bd->free; q++) {
p = (StgClosure *)*q;
ASSERT(!HEAP_ALLOCED(p) || Bdescr((P_)p)->gen_no == gen);
+ if (get_itbl(p)->type == TSO) {
+ ((StgTSO *)p)->flags |= TSO_MARKED;
+ }
}
}
}
+void
+checkMutableLists (rtsBool checkTSOs)
+{
+ nat g, i;
+
+ for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
+ checkMutableList(generations[g].mut_list, g);
+ for (i = 0; i < n_capabilities; i++) {
+ checkMutableList(capabilities[i].mut_lists[g], g);
+ }
+ }
+ checkGlobalTSOList(checkTSOs);
+}
+
/*
Check the static objects list.
*/
switch (info->type) {
case IND_STATIC:
{
- StgClosure *indirectee = ((StgIndStatic *)p)->indirectee;
+ StgClosure *indirectee = UNTAG_CLOSURE(((StgIndStatic *)p)->indirectee);
ASSERT(LOOKS_LIKE_CLOSURE_PTR(indirectee));
- ASSERT(LOOKS_LIKE_INFO_PTR(indirectee->header.info));
+ ASSERT(LOOKS_LIKE_INFO_PTR((StgWord)indirectee->header.info));
p = *IND_STATIC_LINK((StgClosure *)p);
break;
}