summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÖmer Sinan Ağacan <omeragacan@gmail.com>2020-03-14 09:54:54 +0300
committerMarge Bot <ben+marge-bot@smart-cactus.org>2020-03-16 23:54:04 -0400
commit92327e3afd9d2650c9cc9610297d40c2712da085 (patch)
treea08ee80c4707e8150359545dfe839a365898002a
parent18a346a4b5a02b8c62e8eedb91b35c2d8e754b96 (diff)
downloadhaskell-92327e3afd9d2650c9cc9610297d40c2712da085.tar.gz
Update sanity checking for TSOs:
- Remove an invalid assumption about GC checking what_next field. The GC doesn't care about what_next at all, if a TSO is reachable then all its pointers are followed (other than global_tso, which is only followed by compacting GC). - Remove checkSTACK in checkTSO: TSO stacks will be visited in checkHeapChain, or checkLargeObjects etc. - Add an assertion in checkTSO to check that the global_link field is sane. - Did some refactor to remove forward decls in checkGlobalTSOList and added braces around single-statement if statements.
-rw-r--r--rts/sm/Sanity.c58
1 files changed, 22 insertions, 36 deletions
diff --git a/rts/sm/Sanity.c b/rts/sm/Sanity.c
index 23f0fc57b4..1c4c75514d 100644
--- a/rts/sm/Sanity.c
+++ b/rts/sm/Sanity.c
@@ -604,18 +604,8 @@ checkSTACK (StgStack *stack)
void
checkTSO(StgTSO *tso)
{
- StgTSO *next;
- const StgInfoTable *info;
-
- if (tso->what_next == ThreadKilled) {
- /* The garbage collector doesn't bother following any pointers
- * from dead threads, so don't check sanity here.
- */
- return;
- }
-
- next = tso->_link;
- info = (const StgInfoTable*) tso->_link->header.info;
+ StgTSO *next = tso->_link;
+ const StgInfoTable *info = (const StgInfoTable*) tso->_link->header.info;
load_load_barrier();
ASSERT(next == END_TSO_QUEUE ||
@@ -636,9 +626,9 @@ checkTSO(StgTSO *tso)
ASSERT(LOOKS_LIKE_CLOSURE_PTR(tso->bq));
ASSERT(LOOKS_LIKE_CLOSURE_PTR(tso->blocked_exceptions));
ASSERT(LOOKS_LIKE_CLOSURE_PTR(tso->stackobj));
-
- // XXX are we checking the stack twice?
- checkSTACK(tso->stackobj);
+ ASSERT(LOOKS_LIKE_CLOSURE_PTR(tso->global_link) &&
+ (tso->global_link == END_TSO_QUEUE ||
+ get_itbl((StgClosure*)tso->global_link)->type == TSO));
}
/*
@@ -648,16 +638,14 @@ checkTSO(StgTSO *tso)
void
checkGlobalTSOList (bool checkTSOs)
{
- StgTSO *tso;
- uint32_t g;
-
- for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
- for (tso=generations[g].threads; tso != END_TSO_QUEUE;
+ for (uint32_t g = 0; g < RtsFlags.GcFlags.generations; g++) {
+ for (StgTSO *tso = generations[g].threads; tso != END_TSO_QUEUE;
tso = tso->global_link) {
ASSERT(LOOKS_LIKE_CLOSURE_PTR(tso));
ASSERT(get_itbl((StgClosure *)tso)->type == TSO);
- if (checkTSOs)
+ if (checkTSOs) {
checkTSO(tso);
+ }
// If this TSO is dirty and in an old generation, it better
// be on the mutable list.
@@ -666,22 +654,20 @@ checkGlobalTSOList (bool checkTSOs)
tso->flags &= ~TSO_MARKED;
}
- {
- StgStack *stack;
- StgUnderflowFrame *frame;
-
- stack = tso->stackobj;
- while (1) {
- if (stack->dirty & STACK_DIRTY) {
- ASSERT(Bdescr((P_)stack)->gen_no == 0 || (stack->dirty & STACK_SANE));
- stack->dirty &= ~STACK_SANE;
- }
- frame = (StgUnderflowFrame*) (stack->stack + stack->stack_size
- - sizeofW(StgUnderflowFrame));
- if (frame->info != &stg_stack_underflow_frame_info
- || frame->next_chunk == (StgStack*)END_TSO_QUEUE) break;
- stack = frame->next_chunk;
+ StgStack *stack = tso->stackobj;
+ while (1) {
+ if (stack->dirty & STACK_DIRTY) {
+ ASSERT(Bdescr((P_)stack)->gen_no == 0 || (stack->dirty & STACK_SANE));
+ stack->dirty &= ~STACK_SANE;
+ }
+ StgUnderflowFrame *frame =
+ (StgUnderflowFrame*) (stack->stack + stack->stack_size
+ - sizeofW(StgUnderflowFrame));
+ if (frame->info != &stg_stack_underflow_frame_info
+ || frame->next_chunk == (StgStack*)END_TSO_QUEUE) {
+ break;
}
+ stack = frame->next_chunk;
}
}
}