summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--includes/Constants.h2
-rw-r--r--rts/Sanity.c25
-rw-r--r--rts/Sanity.h1
-rw-r--r--rts/sm/GC.c3
4 files changed, 30 insertions, 1 deletions
diff --git a/includes/Constants.h b/includes/Constants.h
index f0f3ce70a2..967a852496 100644
--- a/includes/Constants.h
+++ b/includes/Constants.h
@@ -266,6 +266,8 @@
*/
#define TSO_LINK_DIRTY 32
+#define TSO_MARKED 64
+
/* -----------------------------------------------------------------------------
RET_DYN stack frames
-------------------------------------------------------------------------- */
diff --git a/rts/Sanity.c b/rts/Sanity.c
index 3eea3cd11c..8f3b627a2b 100644
--- a/rts/Sanity.c
+++ b/rts/Sanity.c
@@ -793,6 +793,14 @@ checkGlobalTSOList (rtsBool checkTSOs)
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;
+ }
}
}
}
@@ -812,10 +820,27 @@ checkMutableList( bdescr *mut_bd, nat gen )
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 (void)
+{
+ 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(rtsTrue);
+}
+
/*
Check the static objects list.
*/
diff --git a/rts/Sanity.h b/rts/Sanity.h
index 8cf3f9e52e..b86dc97aa5 100644
--- a/rts/Sanity.h
+++ b/rts/Sanity.h
@@ -29,6 +29,7 @@ extern StgOffset checkStackFrame ( StgPtr sp );
extern StgOffset checkClosure ( StgClosure* p );
extern void checkMutableList ( bdescr *bd, nat gen );
+extern void checkMutableLists (void);
#if defined(GRAN)
extern void checkTSOsSanity(void);
diff --git a/rts/sm/GC.c b/rts/sm/GC.c
index f8a0980e51..ef0c79a6ea 100644
--- a/rts/sm/GC.c
+++ b/rts/sm/GC.c
@@ -268,8 +268,9 @@ GarbageCollect ( rtsBool force_major_gc )
memInventory(traceClass(DEBUG_gc));
#endif
- // check stack sanity *before* GC (ToDo: check all threads)
+ // check stack sanity *before* GC
IF_DEBUG(sanity, checkFreeListSanity());
+ IF_DEBUG(sanity, checkMutableLists());
// Initialise all our gc_thread structures
for (t = 0; t < n_gc_threads; t++) {